void EventManager_OnRemovePresence (IScenePresence presence) { ScriptControllerPresenceModule m = (ScriptControllerPresenceModule)presence.RequestModuleInterface<IScriptControllerModule> (); if (m != null) { m.Close (); presence.UnregisterModuleInterface<IScriptControllerModule> (m); } }
/// <summary> /// Get all of the attachments for the given avatar /// </summary> /// <param name="avatarID">The avatar whose attachments will be returned</param> /// <returns>The avatar's attachments as SceneObjectGroups</returns> public ISceneEntity[] GetAttachmentsForAvatar(UUID avatarID) { ISceneEntity[] attachments = new ISceneEntity[0]; IScenePresence presence = m_scene.GetScenePresence(avatarID); if (presence != null) { AvatarAttachments attPlugin = presence.RequestModuleInterface <AvatarAttachments>(); if (attPlugin != null) { attachments = attPlugin.Get(); } } return(attachments); }
/// <summary> /// Saves a user's appearance /// </summary> /// <param name="agentid"></param> /// <param name="app"></param> private void HandleAppearanceSave(UUID agentid, AvatarAppearance app) { IScenePresence sp = m_scene.GetScenePresence(agentid); if (sp == null) { return; } IAvatarAppearanceModule appearanceModule = sp.RequestModuleInterface <IAvatarAppearanceModule>(); AvatarAppearance appearance = appearanceModule != null ? appearanceModule.Appearance : app; m_scene.AvatarService.SetAppearance(agentid, appearance); }
public bool SetAvatarAppearance(UUID botID, AvatarAppearance avatarApp, IScene scene) { Bot bot; //Find the bot if (!m_bots.TryGetValue(botID, out bot)) { return(false); } var origOwner = avatarApp.Owner; avatarApp.Owner = botID; List <AvatarAttachment> attachments = avatarApp.GetAttachments(); avatarApp.ClearAttachments(); // get original attachments foreach (AvatarAttachment t in attachments) { InventoryItemBase item = scene.InventoryService.GetItem(origOwner, t.ItemID); if (item != null) { item.ID = UUID.Random(); item.Owner = botID; item.Folder = UUID.Zero; scene.InventoryService.AddCacheItemAsync(item); //Now fix the ItemID avatarApp.SetAttachment(t.AttachPoint, item.ID, t.AssetID); } } IScenePresence SP = scene.GetScenePresence(botID); if (SP == null) { return(false); // Failed! bot not found?? } IAvatarAppearanceModule appearance = SP.RequestModuleInterface <IAvatarAppearanceModule>(); appearance.Appearance = avatarApp; appearance.InitialHasWearablesBeenSent = true; return(true); }
public void QueueInitialAppearanceSend(UUID agentid) { MainConsole.Instance.DebugFormat("[AVFACTORY]: Queue initial appearance send for {0}", agentid); IScenePresence sp = m_scene.GetScenePresence(agentid); if (sp == null) { MainConsole.Instance.WarnFormat("[AvatarFactory]: Agent {0} no longer in the scene", agentid); return; } IAvatarAppearanceModule appearance = sp.RequestModuleInterface <IAvatarAppearanceModule>(); //We're waiting to send them, so mark it as true appearance.InitialHasWearablesBeenSent = true; _initialSendQueue.Add(agentid); }
public void QueueAppearanceSave(UUID agentid) { if (MainConsole.Instance.Threshold <= Level.Debug) { MainConsole.Instance.DebugFormat("[AvatarFactory]: Queue appearance save for {0}", GetAgentName(agentid)); } IScenePresence sp = m_scene.GetScenePresence(agentid); if (sp == null) { MainConsole.Instance.WarnFormat("[AvatarFactory]: Agent {0} no longer in the scene", GetAgentName(agentid)); return; } IAvatarAppearanceModule appearance = sp.RequestModuleInterface <IAvatarAppearanceModule> (); _saveQueue.Add(agentid, appearance.Appearance); }
public void aaJoinCombat(LSL_Key uuid) { ScriptProtection.CheckThreatLevel(ThreatLevel.Low, "AAJoinCombat", m_host, "AA"); UUID avID; if (UUID.TryParse(uuid, out avID)) { IScenePresence SP = World.GetScenePresence(avID); if (SP != null) { ICombatPresence CP = SP.RequestModuleInterface <ICombatPresence>(); if (CP != null) { CP.JoinCombat(); } } } }
public LSL_String aaGetTeam(LSL_Key uuid) { UUID avID; if (UUID.TryParse(uuid, out avID)) { ScriptProtection.CheckThreatLevel(ThreatLevel.Low, "AAGetTeam", m_host, "AA"); IScenePresence SP = World.GetScenePresence(avID); if (SP != null) { ICombatPresence CP = SP.RequestModuleInterface <ICombatPresence>(); if (CP != null) { return(CP.Team); } } } return("No Team"); }
private void HandleAppearanceSend(UUID agentid) { IScenePresence sp = m_scene.GetScenePresence(agentid); if (sp == null) { m_log.WarnFormat("[AvatarFactory]: Agent {0} no longer in the scene to send appearance for.", agentid); return; } IAvatarAppearanceModule appearance = sp.RequestModuleInterface <IAvatarAppearanceModule> (); // m_log.WarnFormat("[AvatarFactory]: Handle appearance send for {0}", agentid); // Send the appearance to everyone in the scene appearance.SendAppearanceToAllOtherAgents(); // Send animations back to the avatar as well sp.Animator.SendAnimPack(); }
/// <summary> /// Do everything required once a client completes its movement into a region and becomes /// a root agent. /// </summary> private void HandleInitialAppearanceSend(UUID agentid) { IScenePresence sp = m_scene.GetScenePresence(agentid); if (sp == null) { m_log.WarnFormat("[AvatarFactory]: Agent {0} no longer in the scene to send appearance for.", agentid); return; } IAvatarAppearanceModule appearance = sp.RequestModuleInterface <IAvatarAppearanceModule> (); m_log.InfoFormat("[AvatarFactory]: Handle initial appearance send for {0}", agentid); //Only set this if we actually have sent the wearables appearance.InitialHasWearablesBeenSent = true; // This agent just became root. We are going to tell everyone about it. appearance.SendAvatarDataToAllAgents(); if (ValidateBakedTextureCache(sp.ControllingClient)) { appearance.SendAppearanceToAgent(sp); } else { m_log.ErrorFormat("[AvatarFactory]: baked textures are NOT in the cache for {0}", sp.Name); } sp.ControllingClient.SendWearables(appearance.Appearance.Wearables, appearance.Appearance.Serial); // If the avatars baked textures are all in the cache, then we have a // complete appearance... send it out, if not, then we'll send it when // the avatar finishes updating its appearance appearance.SendAppearanceToAllOtherAgents(); // This agent just became root. We are going to tell everyone about it. The process of // getting other avatars information was initiated in the constructor... don't do it // again here... appearance.SendAvatarDataToAllAgents(); //Tell us about everyone else as well now that we are here appearance.SendOtherAgentsAppearanceToMe(); }
/// <summary> /// Set appearance data (textureentry and slider settings) received from the client /// </summary> /// <param name="textureEntry"></param> /// <param name="visualParams"></param> /// <param name="client"></param> /// <param name="wearables"></param> /// <param name="serial"></param> public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCache[] wearables, uint serial) { IScenePresence sp = m_scene.GetScenePresence(client.AgentId); IAvatarAppearanceModule appearance = sp.RequestModuleInterface <IAvatarAppearanceModule>(); appearance.Appearance.Serial = (int)serial; //MainConsole.Instance.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId); bool texturesChanged = false; bool visualParamsChanged = false; // Process the texture entry transactionally, this doesn't guarantee that Appearance is // going to be handled correctly but it does serialize the updates to the appearance lock (m_setAppearanceLock) { if (textureEntry != null) { List <UUID> ChangedTextures = new List <UUID>(); texturesChanged = appearance.Appearance.SetTextureEntries(textureEntry, out ChangedTextures); } appearance.Appearance.SetCachedWearables(wearables); // Process the visual params, this may change height as well if (visualParams != null) { //Now update the visual params and see if they have changed visualParamsChanged = appearance.Appearance.SetVisualParams(visualParams); //Fix the height only if the parameters have changed if (visualParamsChanged && appearance.Appearance.AvatarHeight > 0) { sp.SetHeight(appearance.Appearance.AvatarHeight); } } } // If something changed in the appearance then queue an appearance save if (texturesChanged || visualParamsChanged) { QueueAppearanceSave(client.AgentId); QueueAppearanceSend(client.AgentId); } }
public LSL_Float aaGetHealth(LSL_Key uuid) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "AAGetHealth", m_host, "AA", m_itemID)) { return(new LSL_Float()); } UUID avID; if (UUID.TryParse(uuid, out avID)) { IScenePresence SP = World.GetScenePresence(avID); if (SP != null) { ICombatPresence cp = SP.RequestModuleInterface <ICombatPresence>(); return(new LSL_Float(cp.Health)); } } return(new LSL_Float(-1)); }
public void ResumeAvatar(IScenePresence presence) { Util.FireAndForget(delegate { IAvatarAppearanceModule appearance = presence.RequestModuleInterface <IAvatarAppearanceModule>(); if (null == appearance || null == appearance.Appearance) { MainConsole.Instance.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", presence.UUID); return; } //Create the avatar attachments plugin for the av AvatarAttachments attachmentsPlugin = new AvatarAttachments(presence); presence.RegisterModuleInterface(attachmentsPlugin); List <AvatarAttachment> attachments = appearance.Appearance.GetAttachments(); MainConsole.Instance.InfoFormat("[ATTACHMENTS MODULE]: Found {0} attachments to attach to avatar {1}", attachments.Count, presence.Name); foreach (AvatarAttachment attach in attachments) { try { RezSingleAttachmentFromInventory(presence.ControllingClient, attach.ItemID, attach.AssetID, 0, false); } catch (Exception e) { MainConsole.Instance.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}", e); } } presence.AttachmentsLoaded = true; lock (_usersToSendAttachmentsToWhenLoaded) { if (_usersToSendAttachmentsToWhenLoaded.ContainsKey(presence.UUID)) { foreach (var id in _usersToSendAttachmentsToWhenLoaded[presence.UUID]) { SendAttachmentsToPresence(id, presence); } _usersToSendAttachmentsToWhenLoaded.Remove(presence.UUID); } } }); }
protected void SendFullUpdateForPresence(IScenePresence presence) { Util.FireAndForget(delegate { m_presence.ControllingClient.SendAvatarDataImmediate(presence); //Send the animations too presence.Animator.SendAnimPackToClient(m_presence.ControllingClient); //Send the presence of this agent to us IAvatarAppearanceModule module = presence.RequestModuleInterface <IAvatarAppearanceModule>(); if (module != null) { module.SendAppearanceToAgent(m_presence); } //We need to send all attachments of this avatar as well IAttachmentsModule attmodule = m_presence.Scene.RequestModuleInterface <IAttachmentsModule>(); if (attmodule != null) { ISceneEntity[] entities = attmodule.GetAttachmentsForAvatar(m_presence.UUID); foreach (ISceneEntity entity in entities) { QueuePartForUpdate(entity.RootChild, PrimUpdateFlags.ForcedFullUpdate); #if (!ISWIN) foreach (ISceneChildEntity child in entity.ChildrenEntities()) { if (!child.IsRoot) { QueuePartForUpdate(child, PrimUpdateFlags.ForcedFullUpdate); } } #else foreach (ISceneChildEntity child in entity.ChildrenEntities().Where(child => !child.IsRoot)) { QueuePartForUpdate(child, PrimUpdateFlags.ForcedFullUpdate); } #endif } } }); }
public void ForceSendAvatarAppearance(UUID agentid) { //If the avatar changes appearance, then proptly logs out, this will break! IScenePresence sp = m_scene.GetScenePresence(agentid); if (sp == null || sp.IsChildAgent) { m_log.WarnFormat("[AvatarFactory]: Agent {0} no longer in the scene", agentid); return; } //Force send! IAvatarAppearanceModule appearance = sp.RequestModuleInterface <IAvatarAppearanceModule> (); sp.ControllingClient.SendWearables(appearance.Appearance.Wearables, appearance.Appearance.Serial); appearance.SendAvatarDataToAllAgents(); appearance.SendAppearanceToAgent(sp); appearance.SendAppearanceToAllOtherAgents(); }
/// <summary> /// Region side /// </summary> /// <param name="message"></param> /// <returns></returns> protected OSDMap OnMessageReceived (OSDMap message) { //We need to check and see if this is an AgentStatusChange if (message.ContainsKey ("Method") && message ["Method"] == "UpdateAvatarAppearance") { var appearance = new AvatarAppearance (message ["AgentID"], (OSDMap)message ["Appearance"]); ISceneManager manager = m_registry.RequestModuleInterface<ISceneManager> (); if (manager != null) { foreach (IScene scene in manager.Scenes) { IScenePresence sp = scene.GetScenePresence (appearance.Owner); if (sp != null && !sp.IsChildAgent) { var avappmodule = sp.RequestModuleInterface<IAvatarAppearanceModule> (); if (avappmodule != null) { avappmodule.Appearance = appearance; avappmodule.SendAppearanceToAgent (sp); avappmodule.SendAppearanceToAllOtherAgents (); } } } } } return null; }
/// <summary> /// Update what the avatar is wearing using an item from their inventory. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void AvatarIsWearing(IClientAPI client, AvatarWearingArgs e) { IScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp == null) { m_log.WarnFormat("[AvatarFactory]: AvatarIsWearing unable to find presence for {0}", client.AgentId); return; } m_log.DebugFormat("[AvatarFactory]: AvatarIsWearing called for {0}", client.AgentId); // operate on a copy of the appearance so we don't have to lock anything IAvatarAppearanceModule appearance = sp.RequestModuleInterface <IAvatarAppearanceModule> (); AvatarAppearance avatAppearance = new AvatarAppearance(appearance.Appearance, false); foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) { if (wear.Type < AvatarWearable.MAX_WEARABLES) { avatAppearance.Wearables[wear.Type].Add(wear.ItemID, UUID.Zero); } } avatAppearance.GetAssetsFrom(appearance.Appearance); // This could take awhile since it needs to pull inventory SetAppearanceAssets(sp.UUID, ref avatAppearance); // could get fancier with the locks here, but in the spirit of "last write wins" // this should work correctly, also, we don't need to send the appearance here // since the "iswearing" will trigger a new set of visual param and baked texture changes // when those complete, the new appearance will be sent appearance.Appearance = avatAppearance; //Send the wearables HERE so that the client knows what it is wearing //sp.ControllingClient.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial); //Do not save or send the appearance! The client loops back and sends a bunch of SetAppearance // (handled above) and that takes care of it }
public void llReleaseControls() { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } TaskInventoryItem item; lock (m_host.TaskInventory) { if (!m_host.TaskInventory.ContainsKey(InventorySelf())) { return; } item = m_host.TaskInventory[InventorySelf()]; } if (item.PermsGranter != UUID.Zero) { IScenePresence presence = World.GetScenePresence(item.PermsGranter); if (presence != null) { if ((item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) { // Unregister controls from Presence IScriptControllerModule m = presence.RequestModuleInterface <IScriptControllerModule>(); if (m != null) { m.UnRegisterControlEventsToScript(m_localID, m_itemID); } // Remove Take Control permission. item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS; } } } }
public void aaJoinCombatTeam(LSL_Key uuid, LSL_String team) { ScriptProtection.CheckThreatLevel(ThreatLevel.Low, "AAJoinCombatTeam", m_host, "AA"); UUID avID; if (UUID.TryParse(uuid, out avID)) { IScenePresence SP = World.GetScenePresence(avID); if (SP != null) { ICombatPresence CP = SP.RequestModuleInterface <ICombatPresence>(); if (CP != null) { if (team.m_string == "No Team") { SP.ControllingClient.SendAlertMessage("You cannot join this team."); return; } CP.Team = team.m_string; } } } }
/// <summary> /// Sets the Home Point. The LoginService uses this to know where to put a user when they log-in /// </summary> /// <param name="remoteClient"></param> /// <param name="regionHandle"></param> /// <param name="position"></param> /// <param name="lookAt"></param> /// <param name="flags"></param> public void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) { Scene scene = (Scene)remoteClient.Scene; if (scene == null) { return; } IScenePresence SP = scene.GetScenePresence(remoteClient.AgentId); IDialogModule module = scene.RequestModuleInterface <IDialogModule>(); if (SP != null) { if (scene.Permissions.CanSetHome(SP.UUID)) { IAvatarAppearanceModule appearance = SP.RequestModuleInterface <IAvatarAppearanceModule> (); position.Z += appearance.Appearance.AvatarHeight / 2; IAgentInfoService agentInfoService = scene.RequestModuleInterface <IAgentInfoService>(); if (agentInfoService != null && agentInfoService.SetHomePosition(remoteClient.AgentId.ToString(), scene.RegionInfo.RegionID, position, lookAt) && module != null) //Do this last so it doesn't screw up the rest { // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. module.SendAlertToUser(remoteClient, "Home position set."); } else if (module != null) { module.SendAlertToUser(remoteClient, "Set Home request failed."); } } else if (module != null) { module.SendAlertToUser(remoteClient, "Set Home request failed: Permissions do not allow the setting of home here."); } } }
public void IncurDamage(uint localID, double damage, string RegionName, Vector3 pos, Vector3 lookat, UUID OwnerID) { if (damage < 0) { return; } IScenePresence SP = m_SP.Scene.GetScenePresence(OwnerID); if (SP == null) { return; } ICombatPresence cp = SP.RequestModuleInterface <ICombatPresence>(); if (!cp.HasLeftCombat || !m_combatModule.ForceRequireCombatPermission) { if (damage > MaximumDamageToInflict) { damage = MaximumDamageToInflict; } float health = Health; health -= (float)damage; m_SP.ControllingClient.SendHealth(health); if (health <= 0) { KillAvatar(localID, false); m_SP.ControllingClient.SendTeleportStart((uint)TeleportFlags.ViaHome); IEntityTransferModule entityTransfer = m_SP.Scene.RequestModuleInterface <IEntityTransferModule>(); if (entityTransfer != null) { entityTransfer.RequestTeleportLocation(m_SP.ControllingClient, RegionName, pos, lookat, (uint)TeleportFlags.ViaHome); } } } }
public void QueueAppearanceSave(UUID agentid) { // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid); // 10000 ticks per millisecond, 1000 milliseconds per second long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); lock (m_savequeue) { IScenePresence sp = m_scene.GetScenePresence(agentid); if (sp == null) { m_log.WarnFormat("[AvatarFactory]: Agent {0} no longer in the scene", agentid); return; } IAvatarAppearanceModule appearance = sp.RequestModuleInterface <IAvatarAppearanceModule> (); m_savequeue[agentid] = timestamp; lock (m_saveQueueData) { m_saveQueueData[agentid] = appearance.Appearance; } m_updateTimer.Start(); } }
/// <summary> /// Attach the object to the avatar /// </summary> /// <param name="remoteClient">The client that is having the attachment done</param> /// <param name="localID">The localID (SceneObjectPart) that is being attached (for the attach script event)</param> /// <param name="group">The group (SceneObjectGroup) that is being attached</param> /// <param name="AttachmentPt">The point to where the attachment will go</param> /// <param name="assetID" /> /// <param name="forceUpdatePrim">Force updating of the prim the next time the user attempts to deattach it</param> /// <param name="isTempAttach">Is a temporary attachment</param> protected void FindAttachmentPoint(IClientAPI remoteClient, uint localID, ISceneEntity group, int AttachmentPt, UUID assetID, bool forceUpdatePrim, bool isTempAttach) { //Make sure that we arn't over the limit of attachments ISceneEntity[] attachments = GetAttachmentsForAvatar(remoteClient.AgentId); if (attachments.Length + 1 > m_maxNumberOfAttachments) { //Too many remoteClient.SendAgentAlertMessage( "You are wearing too many attachments. Take one off to attach this object", false); return; } Vector3 attachPos = group.GetAttachmentPos(); bool hasMultipleAttachmentsSet = (AttachmentPt & 0x7f) != 0 || AttachmentPt == 0; if (!m_allowMultipleAttachments) { hasMultipleAttachmentsSet = false; } AttachmentPt &= 0x7f; //Disable it! Its evil! //Did the attachment change position or attachment point? bool changedPositionPoint = false; // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. //Simplier terms: the attachment point changed, set it to the default 0,0,0 location if (AttachmentPt != 0 && AttachmentPt != (group.GetAttachmentPoint() & 0x7f)) { attachPos = Vector3.Zero; changedPositionPoint = true; } else { // AttachmentPt 0 means the client chose to 'wear' the attachment. if (AttachmentPt == 0) { // Check object for stored attachment point AttachmentPt = group.GetSavedAttachmentPoint() & 0x7f; attachPos = group.GetAttachmentPos(); } //Check state afterwards... use the newer GetSavedAttachmentPoint and Pos above first if (AttachmentPt == 0) { // Check object for older stored attachment point AttachmentPt = group.RootChild.Shape.State & 0x7f; } // if we still didn't find a suitable attachment point, force it to the default //This happens on the first time an avatar 'wears' an object if (AttachmentPt == 0) { // Stick it on right hand with Zero Offset from the attachment point. AttachmentPt = (int)AttachmentPoint.RightHand; //Default location attachPos = Vector3.Zero; changedPositionPoint = true; } } MainConsole.Instance.DebugFormat( "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2} localID {3}", group.Name, remoteClient.Name, AttachmentPt, group.LocalId); //Update where we are put group.SetAttachmentPoint((byte)AttachmentPt); //Fix the position with the one we found group.AbsolutePosition = attachPos; // Remove any previous attachments IScenePresence presence = m_scene.GetScenePresence(remoteClient.AgentId); if (presence == null) { return; } UUID itemID = UUID.Zero; //Check for multiple attachment bits and whether we should remove the old if (!hasMultipleAttachmentsSet) { foreach (ISceneEntity grp in attachments) { if (grp.GetAttachmentPoint() == (byte)AttachmentPt) { itemID = grp.RootChild.FromUserInventoryItemID; break; } } if (itemID != UUID.Zero) { DetachSingleAttachmentToInventory(itemID, remoteClient); } } itemID = group.RootChild.FromUserInventoryItemID; group.RootChild.AttachedAvatar = presence.UUID; List <ISceneChildEntity> parts = group.ChildrenEntities(); foreach (ISceneChildEntity t in parts) { t.AttachedAvatar = presence.UUID; } if (group.RootChild.PhysActor != null) { m_scene.PhysicsScene.DeletePrim(group.RootChild.PhysActor); group.RootChild.PhysActor = null; } group.RootChild.AttachedPos = attachPos; group.RootChild.IsAttachment = true; group.AbsolutePosition = attachPos; group.RootChild.SetParentLocalId(presence.LocalId); group.SetAttachmentPoint(Convert.ToByte(AttachmentPt)); // Killing it here will cause the client to deselect it // It then reappears on the avatar, deselected // through the full update below if (group.IsSelected) { foreach (ISceneChildEntity part in group.ChildrenEntities()) { part.CreateSelected = true; } } //NOTE: This MUST be here, otherwise we limit full updates during attachments when they are selected and it will block the first update. // So until that is changed, this MUST stay. The client will instantly reselect it, so this value doesn't stay borked for long. group.IsSelected = false; if (!isTempAttach) { if (itemID == UUID.Zero) { //Delete the object inworld to inventory List <ISceneEntity> groups = new List <ISceneEntity>(1) { group }; IInventoryAccessModule inventoryAccess = m_scene.RequestModuleInterface <IInventoryAccessModule>(); if (inventoryAccess != null) { inventoryAccess.DeleteToInventory(DeRezAction.AcquireToUserInventory, UUID.Zero, groups, remoteClient.AgentId, out itemID); } } else { //it came from an item, we need to start the scripts // Fire after attach, so we don't get messy perms dialogs. group.CreateScriptInstances(0, true, StateSource.AttachedRez, UUID.Zero, false); } if (UUID.Zero == itemID) { MainConsole.Instance.Error( "[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID."); remoteClient.SendAgentAlertMessage( "Unable to save attachment. Error inventory item ID.", false); return; } // XXYY!! if (assetID == UUID.Zero) { assetID = m_scene.InventoryService.GetItemAssetID(remoteClient.AgentId, itemID); //Update the ItemID with the new item group.SetFromItemID(itemID, assetID); } } else { // Fire after attach, so we don't get messy perms dialogs. group.CreateScriptInstances(0, true, StateSource.AttachedRez, UUID.Zero, false); group.RootChild.FromUserInventoryItemID = UUID.Zero; } AvatarAttachments attPlugin = presence.RequestModuleInterface <AvatarAttachments>(); if (attPlugin != null) { attPlugin.AddAttachment(group); presence.SetAttachments(attPlugin.Get()); if (!isTempAttach) { IAvatarAppearanceModule appearance = presence.RequestModuleInterface <IAvatarAppearanceModule>(); appearance.Appearance.SetAttachments(attPlugin.Get()); AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); } } // In case it is later dropped again, don't let // it get cleaned up group.RootChild.RemFlag(PrimFlags.TemporaryOnRez); group.HasGroupChanged = changedPositionPoint || forceUpdatePrim; //Now recreate it so that it is selected group.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); m_scene.EventManager.TriggerOnAttach(localID, group.RootChild.FromUserInventoryItemID, remoteClient.AgentId); }
public virtual void Teleport(IScenePresence sp, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) { sp.ControllingClient.SendTeleportStart(teleportFlags); sp.ControllingClient.SendTeleportProgress(teleportFlags, "requesting"); // Reset animations; the viewer does that in teleports. if (sp.Animator != null) sp.Animator.ResetAnimations(); try { string reason = ""; if (finalDestination.RegionHandle == sp.Scene.RegionInfo.RegionHandle) { //First check whether the user is allowed to move at all if (!sp.Scene.Permissions.AllowedOutgoingLocalTeleport(sp.UUID, out reason)) { sp.ControllingClient.SendTeleportFailed(reason); return; } //Now respect things like parcel bans with this if ( !sp.Scene.Permissions.AllowedIncomingTeleport(sp.UUID, position, teleportFlags, out position, out reason)) { sp.ControllingClient.SendTeleportFailed(reason); return; } MainConsole.Instance.DebugFormat( "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", position, sp.Scene.RegionInfo.RegionName); sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); sp.RequestModuleInterface<IScriptControllerModule>() .HandleForceReleaseControls(sp.ControllingClient, sp.UUID); sp.Teleport(position); } else // Another region possibly in another simulator { // Make sure the user is allowed to leave this region if (!sp.Scene.Permissions.AllowedOutgoingRemoteTeleport(sp.UUID, out reason)) { sp.ControllingClient.SendTeleportFailed(reason); return; } DoTeleport(sp, finalDestination, position, lookAt, teleportFlags); } } catch (Exception e) { MainConsole.Instance.ErrorFormat("[ENTITY TRANSFER MODULE]: Exception on teleport: {0}\n{1}", e.Message, e.StackTrace); sp.ControllingClient.SendTeleportFailed("Internal error"); } }
public void RezAttachments (IScenePresence presence) { IAvatarAppearanceModule appearance = presence.RequestModuleInterface<IAvatarAppearanceModule> (); if(null == appearance || null == appearance.Appearance) { m_log.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", presence.UUID); return; } //Create the avatar attachments plugin for the av AvatarAttachments attachmentsPlugin = new AvatarAttachments(presence); presence.RegisterModuleInterface <AvatarAttachments>(attachmentsPlugin); List<AvatarAttachment> attachments = appearance.Appearance.GetAttachments (); foreach (AvatarAttachment attach in attachments) { int p = attach.AttachPoint; UUID itemID = attach.ItemID; try { RezSingleAttachmentFromInventory(presence.ControllingClient, itemID, p); } catch (Exception e) { m_log.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}{1}", e.Message, e.StackTrace); } } foreach(IScenePresence sp in presence.Scene.GetScenePresences()) sp.SceneViewer.QueuePresenceForFullUpdate(presence, true); }
/// <summary> /// Adding a New Client and Create a Presence for it. /// Called by the LLClientView when the UseCircuitCode packet comes in /// Used by NPCs to add themselves to the Scene /// </summary> /// <param name="client"></param> /// <param name="completed"></param> public void AddNewClient(IClientAPI client, BlankHandler completed) { lock (m_events) m_events.Add(delegate { try { System.Net.IPEndPoint ep = (System.Net.IPEndPoint)client.GetClientEP(); AgentCircuitData aCircuit = AuthenticateHandler.AuthenticateSession(client.SessionId, client.AgentId, client.CircuitCode, ep); if (aCircuit == null) // no good, didn't pass NewUserConnection successfully { completed(); return; } m_clientManager.Add(client); //Create the scenepresence IScenePresence sp = CreateAndAddChildScenePresence(client); sp.IsChildAgent = aCircuit.child; sp.DrawDistance = aCircuit.DrawDistance; //Trigger events m_eventManager.TriggerOnNewPresence(sp); //Make sure the appearanace is updated IAvatarAppearanceModule appearance = sp.RequestModuleInterface <IAvatarAppearanceModule>(); if (appearance != null) { appearance.Appearance = aCircuit.Appearance ?? sp.Scene.AvatarService.GetAppearance(sp.UUID); if (appearance.Appearance == null) { MainConsole.Instance.Error("[AsyncScene]: NO AVATAR APPEARANCE FOUND FOR " + sp.Name); appearance.Appearance = new AvatarAppearance(sp.UUID); } } if (GetScenePresence(client.AgentId) != null) { EventManager.TriggerOnNewClient(client); if ((aCircuit.teleportFlags & (uint)TeleportFlags.ViaLogin) != 0) { EventManager.TriggerOnClientLogin(client); } } //Add the client to login stats ILoginMonitor monitor3 = (ILoginMonitor)RequestModuleInterface <IMonitorModule>().GetMonitor("", MonitorModuleHelper.LoginMonitor); if ((aCircuit.teleportFlags & (uint)TeleportFlags.ViaLogin) != 0 && monitor3 != null) { monitor3.AddSuccessfulLogin(); } if (sp.IsChildAgent)//If we're a child, trigger this so that we get updated in the modules { sp.TriggerSignificantClientMovement(); } completed(); } catch (Exception ex) { MainConsole.Instance.Warn("[Scene]: Error in AddNewClient: " + ex); } }); }
public void ResumeAvatar(IScenePresence presence) { Util.FireAndForget(delegate { IAvatarAppearanceModule appearance = presence.RequestModuleInterface<IAvatarAppearanceModule>(); if (null == appearance || null == appearance.Appearance) { MainConsole.Instance.WarnFormat( "[ATTACHMENT]: Appearance has not been initialized for agent {0}", presence.UUID); return; } //Create the avatar attachments plugin for the av AvatarAttachments attachmentsPlugin = new AvatarAttachments(presence); presence.RegisterModuleInterface(attachmentsPlugin); List<AvatarAttachment> attachments = appearance.Appearance.GetAttachments(); MainConsole.Instance.InfoFormat( "[ATTACHMENTS MODULE]: Found {0} attachments to attach to avatar {1}", attachments.Count, presence.Name); foreach (AvatarAttachment attach in attachments) { try { RezSingleAttachmentFromInventory(presence.ControllingClient, attach.ItemID, attach.AssetID, 0, false); } catch (Exception e) { MainConsole.Instance.ErrorFormat( "[ATTACHMENT]: Unable to rez attachment: {0}", e); } } presence.AttachmentsLoaded = true; lock (_usersToSendAttachmentsToWhenLoaded) { if (_usersToSendAttachmentsToWhenLoaded.ContainsKey(presence.UUID)) { foreach (var id in _usersToSendAttachmentsToWhenLoaded[presence.UUID]) { SendAttachmentsToPresence(id, presence); } _usersToSendAttachmentsToWhenLoaded.Remove(presence.UUID); } } }); }
public virtual void DoTeleport(IScenePresence sp, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) { sp.ControllingClient.SendTeleportProgress(teleportFlags, "sending_dest"); if (finalDestination == null) { sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); return; } m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Request Teleport to {0}:{1}/{2}", finalDestination.ServerURI, finalDestination.RegionName, position); sp.ControllingClient.SendTeleportProgress(teleportFlags, "arriving"); // Fixing a bug where teleporting while sitting results in the avatar ending up removed from // both regions if (sp.ParentID != UUID.Zero) sp.StandUp(); //Make sure that all attachments are ready for the teleport IAttachmentsModule attModule = sp.Scene.RequestModuleInterface<IAttachmentsModule>(); if (attModule != null) attModule.ValidateAttachments(sp.UUID); AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); agentCircuit.startpos = position; //The agent will be a root agent agentCircuit.child = false; //Make sure the appearnace is right IAvatarAppearanceModule appearance = sp.RequestModuleInterface<IAvatarAppearanceModule> (); if(appearance != null) agentCircuit.Appearance = appearance.Appearance; AgentData agent = new AgentData(); sp.CopyTo(agent); //Fix the position agent.Position = position; IEventQueueService eq = sp.Scene.RequestModuleInterface<IEventQueueService>(); if (eq != null) { ISyncMessagePosterService syncPoster = sp.Scene.RequestModuleInterface<ISyncMessagePosterService>(); if (syncPoster != null) { AgentCircuitData oldCircuit = sp.Scene.AuthenticateHandler.AgentCircuitsByUUID[sp.UUID]; agentCircuit.ServiceURLs = oldCircuit.ServiceURLs; agentCircuit.firstname = oldCircuit.firstname; agentCircuit.lastname = oldCircuit.lastname; agentCircuit.ServiceSessionID = oldCircuit.ServiceSessionID; //This does CreateAgent and sends the EnableSimulator/EstablishAgentCommunication/TeleportFinish // messages if they need to be called and deals with the callback OSDMap map = syncPoster.Get(SyncMessageHelper.TeleportAgent((int)sp.DrawDistance, agentCircuit, agent, teleportFlags, finalDestination, sp.Scene.RegionInfo.RegionHandle), sp.UUID, sp.Scene.RegionInfo.RegionHandle); bool result = false; if(map != null) result = map["Success"].AsBoolean(); if (!result) { // Fix the agent status sp.IsChildAgent = false; //Fix user's attachments attModule.RezAttachments (sp); if (map != null) sp.ControllingClient.SendTeleportFailed (map["Reason"].AsString ()); else sp.ControllingClient.SendTeleportFailed ("Teleport Failed"); return; } else { //Get the new destintation, it may have changed if(map.ContainsKey("Destination")) { finalDestination = new GridRegion(); finalDestination.FromOSD((OSDMap)map["Destination"]); } } } } MakeChildAgent(sp, finalDestination); }
/// <summary> /// Update what the avatar is wearing using an item from their inventory. /// </summary> /// <param name="client"></param> /// <param name="e"></param> public void AvatarIsWearing(IClientAPI client, AvatarWearingArgs e) { IScenePresence sp = m_scene.GetScenePresence(client.AgentId); var agentName = GetAgentName(client.AgentId); if (sp == null) { MainConsole.Instance.WarnFormat("[AvatarFactory]: AvatarIsWearing unable to find presence for {0}", agentName); return; } MainConsole.Instance.DebugFormat("[AvatarFactory]: AvatarIsWearing called for {0}", agentName); // operate on a copy of the appearance so we don't have to lock anything IAvatarAppearanceModule appearance = sp.RequestModuleInterface <IAvatarAppearanceModule> (); AvatarAppearance avatAppearance = new AvatarAppearance(appearance.Appearance, false); #region Teen Mode Stuff IOpenRegionSettingsModule module = m_scene.RequestModuleInterface <IOpenRegionSettingsModule> (); bool NeedsRebake = false; if (module != null && module.EnableTeenMode) { foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) { if (wear.Type == 10 & wear.ItemID == UUID.Zero && module.DefaultUnderpants != UUID.Zero) { NeedsRebake = true; wear.ItemID = module.DefaultUnderpants; InventoryItemBase item = new InventoryItemBase(UUID.Random()) { InvType = (int)InventoryType.Wearable, AssetType = (int)AssetType.Clothing, Name = "Default Underpants", Folder = m_scene.InventoryService.GetFolderForType(client.AgentId, InventoryType.Wearable, FolderType.Clothing).ID, Owner = client.AgentId, CurrentPermissions = 0, CreatorId = UUID.Zero.ToString(), AssetID = module.DefaultUnderpants }; // Locked client.SendInventoryItemCreateUpdate(item, 0); } else if (wear.Type == 10 & wear.ItemID == UUID.Zero) { NeedsRebake = true; InventoryItemBase item = new InventoryItemBase(UUID.Random()) { InvType = (int)InventoryType.Wearable, AssetType = (int)AssetType.Clothing, Name = "Default Underpants", Folder = m_scene.InventoryService.GetFolderForType(client.AgentId, InventoryType.Wearable, FolderType.Clothing).ID, Owner = client.AgentId, CurrentPermissions = 0 }; // Locked if (m_underPantsUUID == UUID.Zero) { m_underPantsUUID = UUID.Random(); AssetBase asset = new AssetBase(m_underPantsUUID, "Default Underpants", AssetType.Clothing, UUID.Zero) { Data = Utils.StringToBytes(m_defaultUnderPants) }; asset.ID = m_scene.AssetService.Store(asset); m_underPantsUUID = asset.ID; } item.CreatorId = UUID.Zero.ToString(); item.AssetID = m_underPantsUUID; m_scene.InventoryService.AddItemAsync(item, null); client.SendInventoryItemCreateUpdate(item, 0); wear.ItemID = item.ID; } if (wear.Type == 11 && wear.ItemID == UUID.Zero && module.DefaultUndershirt != UUID.Zero) { NeedsRebake = true; wear.ItemID = module.DefaultUndershirt; InventoryItemBase item = new InventoryItemBase(UUID.Random()) { InvType = (int)InventoryType.Wearable, AssetType = (int)AssetType.Clothing, Name = "Default Undershirt", Folder = m_scene.InventoryService.GetFolderForType(client.AgentId, InventoryType.Wearable, FolderType.Clothing).ID, Owner = client.AgentId, CurrentPermissions = 0, CreatorId = UUID.Zero.ToString(), AssetID = module.DefaultUndershirt }; // Locked client.SendInventoryItemCreateUpdate(item, 0); } else if (wear.Type == 11 & wear.ItemID == UUID.Zero) { NeedsRebake = true; InventoryItemBase item = new InventoryItemBase(UUID.Random()) { InvType = (int)InventoryType.Wearable, AssetType = (int)AssetType.Clothing, Name = "Default Undershirt", Folder = m_scene.InventoryService.GetFolderForType(client.AgentId, InventoryType.Wearable, FolderType.Clothing).ID, Owner = client.AgentId, CurrentPermissions = 0 }; //Locked if (m_underShirtUUID == UUID.Zero) { m_underShirtUUID = UUID.Random(); AssetBase asset = new AssetBase(m_underShirtUUID, "Default Undershirt", AssetType.Clothing, UUID.Zero) { Data = Utils.StringToBytes(m_defaultUnderShirt) }; asset.ID = m_scene.AssetService.Store(asset); m_underShirtUUID = asset.ID; } item.CreatorId = UUID.Zero.ToString(); item.AssetID = m_underShirtUUID; m_scene.InventoryService.AddItemAsync(item, null); client.SendInventoryItemCreateUpdate(item, 0); wear.ItemID = item.ID; } } } #endregion foreach ( AvatarWearingArgs.Wearable wear in e.NowWearing.Where(wear => wear.Type < AvatarWearable.MAX_WEARABLES)) { avatAppearance.Wearables [wear.Type].Add(wear.ItemID, UUID.Zero); } avatAppearance.GetAssetsFrom(appearance.Appearance); // This could take awhile since it needs to pull inventory SetAppearanceAssets(sp.UUID, e.NowWearing, appearance.Appearance, ref avatAppearance); // could get fancier with the locks here, but in the spirit of "last write wins" // this should work correctly, also, we don't need to send the appearance here // since the "iswearing" will trigger a new set of visual param and baked texture changes // when those complete, the new appearance will be sent appearance.Appearance = avatAppearance; //This only occurs if something has been forced on afterwards (teen mode stuff) if (NeedsRebake) { //Tell the client about the new things it is wearing sp.ControllingClient.SendWearables(appearance.Appearance.Wearables, appearance.Appearance.Serial); //Then forcefully tell it to rebake foreach ( Primitive.TextureEntryFace face in appearance.Appearance.Texture.FaceTextures.Select(t => (t)).Where(face => face != null)) { sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID); } } QueueAppearanceSave(sp.UUID); //Send the wearables HERE so that the client knows what it is wearing //sp.ControllingClient.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial); //Do not save or send the appearance! The client loops back and sends a bunch of SetAppearance // (handled above) and that takes care of it }
/// <summary> /// Creates a new bot inworld /// </summary> /// <param name = "FirstName"></param> /// <param name = "LastName"></param> /// <param name = "cloneAppearanceFrom">UUID of the avatar whos appearance will be copied to give this bot an appearance</param> /// <returns>ID of the bot</returns> public UUID CreateAvatar(string FirstName, string LastName, IScene scene, UUID cloneAppearanceFrom, UUID creatorID, Vector3 startPos) { AgentCircuitData m_aCircuitData = new AgentCircuitData { child = false, circuitcode = (uint)Util.RandomClass.Next(), Appearance = GetAppearance(cloneAppearanceFrom, scene) }; //Add the circuit data so they can login //Sets up appearance if (m_aCircuitData.Appearance == null) { m_aCircuitData.Appearance = new AvatarAppearance { Wearables = AvatarWearable.DefaultWearables }; } //Create the new bot data BotClientAPI m_character = new BotClientAPI(scene, m_aCircuitData) { FirstName = FirstName, LastName = LastName }; m_aCircuitData.AgentID = m_character.AgentId; m_aCircuitData.Appearance.Owner = m_character.AgentId; List <AvatarAttachment> attachments = m_aCircuitData.Appearance.GetAttachments(); m_aCircuitData.Appearance.ClearAttachments(); foreach (AvatarAttachment t in attachments) { InventoryItemBase item = scene.InventoryService.GetItem(new InventoryItemBase(t.ItemID)); if (item != null) { item.ID = UUID.Random(); item.Owner = m_character.AgentId; item.Folder = UUID.Zero; scene.InventoryService.AddItemAsync(item, null); //Now fix the ItemID m_aCircuitData.Appearance.SetAttachment(t.AttachPoint, item.ID, t.AssetID); } } scene.AuthenticateHandler.AgentCircuits.Add(m_character.CircuitCode, m_aCircuitData); //This adds them to the scene and sets them inworld AddAndWaitUntilAgentIsAdded(scene, m_character); IScenePresence SP = scene.GetScenePresence(m_character.AgentId); if (SP == null) { return(UUID.Zero); //Failed! } Bot bot = new Bot(); bot.Initialize(SP, creatorID); SP.MakeRootAgent(startPos, false, true); //Move them SP.Teleport(startPos); foreach (var presence in scene.GetScenePresences()) { presence.SceneViewer.QueuePresenceForUpdate(SP, PrimUpdateFlags.ForcedFullUpdate); } IAttachmentsModule attModule = SP.Scene.RequestModuleInterface <IAttachmentsModule>(); if (attModule != null) { foreach (AvatarAttachment att in attachments) { attModule.RezSingleAttachmentFromInventory(SP.ControllingClient, att.ItemID, att.AssetID, 0, true); } } IAvatarAppearanceModule appearance = SP.RequestModuleInterface <IAvatarAppearanceModule>(); appearance.InitialHasWearablesBeenSent = true; //Save them in the bots list m_bots.Add(m_character.AgentId, bot); AddTagToBot(m_character.AgentId, "AllBots", bot.AvatarCreatorID); MainConsole.Instance.Info("[RexBotManager]: Added bot " + m_character.Name + " to scene."); //Return their UUID return(m_character.AgentId); }
public void PhysicsActor_OnCollisionUpdate(EventArgs e) { if (m_SP == null || m_SP.Invulnerable) { return; } if (HasLeftCombat) { return; } if (e == null) { return; } CollisionEventUpdate collisionData = (CollisionEventUpdate)e; Dictionary <uint, ContactPoint> coldata = collisionData.m_objCollisionList; float starthealth = Health; uint killerObj = 0; foreach (uint localid in coldata.Keys) { ISceneChildEntity part = m_SP.Scene.GetSceneObjectPart(localid); if (part != null) { if (part.ParentEntity.Damage != -1.0f) { continue; } IScenePresence otherAvatar = m_SP.Scene.GetScenePresence(part.OwnerID); if (otherAvatar != null) // If the avatar is null, the person is not inworld, and not on a team { if (otherAvatar.RequestModuleInterface <ICombatPresence>().HasLeftCombat) { //If they have left combat, do not let them cause any damage. continue; } } if (part.ParentEntity.Damage > MaximumDamageToInflict) { part.ParentEntity.Damage = MaximumDamageToInflict; } if (AllowTeams) { if (otherAvatar != null) // If the avatar is null, the person is not inworld, and not on a team { ICombatPresence OtherAvatarCP = otherAvatar.RequestModuleInterface <ICombatPresence>(); if (OtherAvatarCP.Team == Team) { float Hits = 0; if (!TeamHits.TryGetValue(otherAvatar.UUID, out Hits)) { Hits = 0; } Hits++; if (SendTeamKillerInfo && Hits == TeamHitsBeforeSend) { otherAvatar.ControllingClient.SendAlertMessage("You have shot too many teammates and " + DamageToTeamKillers + " health has been taken from you!"); OtherAvatarCP.Health -= DamageToTeamKillers; otherAvatar.ControllingClient.SendHealth(OtherAvatarCP.Health); if (OtherAvatarCP.Health <= 0) { KillAvatar(otherAvatar.LocalId, true); } Hits = 0; } TeamHits[otherAvatar.UUID] = Hits; if (AllowTeamKilling) //Green light on team killing { Health -= part.ParentEntity.Damage; } } else //Object, hit em { Health -= part.ParentEntity.Damage; } } else //Other team, hit em { Health -= part.ParentEntity.Damage; } } else //Free for all, hit em { Health -= part.ParentEntity.Damage; } } else { float Z = m_SP.Velocity.Length() / 20; if (coldata[localid].PenetrationDepth >= 0.05f && Math.Abs(m_SP.Velocity.X) < 1 && Math.Abs(m_SP.Velocity.Y) < 1) { Z = Math.Min(Z, 1.5f); float damage = Math.Min(coldata[localid].PenetrationDepth, 15f); Health -= damage * Z; } } if (Health > m_combatModule.MaximumHealth) { Health = m_combatModule.MaximumHealth; } if (Health <= 0.0f) { if (localid != 0) { killerObj = localid; } } //m_log.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString()); } if (starthealth != Health) { m_SP.ControllingClient.SendHealth(Health); } if (Health <= 0) { KillAvatar(killerObj, true); } }
/// <summary> /// Set appearance data (textureentry and slider settings) received from the client /// </summary> /// <param name="texture"></param> /// <param name="visualParam"></param> public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCache[] wearables) { IScenePresence sp = m_scene.GetScenePresence(client.AgentId); IAvatarAppearanceModule appearance = sp.RequestModuleInterface <IAvatarAppearanceModule> (); if (sp == null) { m_log.WarnFormat("[AvatarFactory]: SetAppearance unable to find presence for {0}", client.AgentId); return; } //m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId); // Process the texture entry transactionally, this doesn't guarantee that Appearance is // going to be handled correctly but it does serialize the updates to the appearance lock (m_setAppearanceLock) { bool texturesChanged = false; bool visualParamsChanged = false; if (textureEntry != null) { List <UUID> ChangedTextures = new List <UUID>(); texturesChanged = appearance.Appearance.SetTextureEntries(textureEntry, out ChangedTextures); // m_log.WarnFormat("[AVFACTORY]: Prepare to check textures for {0}",client.AgentId); //Do this async as it accesses the asset service (could be remote) multiple times Util.FireAndForget(delegate(object o) { //Validate all the textures now that we've updated ValidateBakedTextureCache(client, false); //The client wants us to cache the baked textures CacheWearableData(sp, textureEntry, wearables); }); // m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId); } // Process the visual params, this may change height as well if (visualParams != null) { //Now update the visual params and see if they have changed visualParamsChanged = appearance.Appearance.SetVisualParams(visualParams); //Fix the height only if the parameters have changed if (visualParamsChanged && appearance.Appearance.AvatarHeight > 0) { sp.SetHeight(appearance.Appearance.AvatarHeight); } } // Process the baked texture array if (textureEntry != null) { //Check for banned clients here Aurora.Framework.IBanViewersModule module = client.Scene.RequestModuleInterface <Aurora.Framework.IBanViewersModule>(); if (module != null) { module.CheckForBannedViewer(client, textureEntry); } } // If something changed in the appearance then queue an appearance save if (texturesChanged || visualParamsChanged) { QueueAppearanceSave(client.AgentId); } } // And always queue up an appearance update to send out QueueAppearanceSend(client.AgentId); // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); }
public virtual void DoTeleport(IScenePresence sp, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) { sp.ControllingClient.SendTeleportProgress(teleportFlags, "sending_dest"); if (finalDestination == null) { sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); return; } m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Request Teleport to {0}:{1}/{2}", finalDestination.ServerURI, finalDestination.RegionName, position); sp.ControllingClient.SendTeleportProgress(teleportFlags, "arriving"); // Fixing a bug where teleporting while sitting results in the avatar ending up removed from // both regions if (sp.ParentID != UUID.Zero) sp.StandUp(); //Make sure that all attachments are ready for the teleport IAttachmentsModule attModule = sp.Scene.RequestModuleInterface<IAttachmentsModule>(); if (attModule != null) attModule.ValidateAttachments(sp.UUID); AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); agentCircuit.startpos = position; //The agent will be a root agent agentCircuit.child = false; //Make sure the appearnace is right IAvatarAppearanceModule appearance = sp.RequestModuleInterface<IAvatarAppearanceModule> (); agentCircuit.Appearance = appearance.Appearance; AgentData agent = new AgentData(); sp.CopyTo(agent); //Fix the position agent.Position = position; IEventQueueService eq = sp.Scene.RequestModuleInterface<IEventQueueService>(); if (eq != null) { ISyncMessagePosterService syncPoster = sp.Scene.RequestModuleInterface<ISyncMessagePosterService>(); if (syncPoster != null) { //This does CreateAgent and sends the EnableSimulator/EstablishAgentCommunication/TeleportFinish // messages if they need to be called and deals with the callback OSDMap map = syncPoster.Get(SyncMessageHelper.TeleportAgent((int)sp.DrawDistance, agentCircuit, agent, teleportFlags, finalDestination, sp.Scene.RegionInfo.RegionHandle), sp.UUID, sp.Scene.RegionInfo.RegionHandle); bool result = false; if(map != null) result = map["Success"].AsBoolean(); if (!result) { // Fix the agent status sp.IsChildAgent = false; if(map != null) sp.ControllingClient.SendTeleportFailed(map["Reason"].AsString()); else sp.ControllingClient.SendTeleportFailed ("Teleport Failed"); return; } } } sp.Scene.AuroraEventManager.FireGenericEventHandler ("SendingAttachments", new object[2] { finalDestination, sp }); //Kill the groups here, otherwise they will become ghost attachments // and stay in the sim, they'll get readded below into the new sim KillAttachments(sp); // Well, this is it. The agent is over there. KillEntity(sp.Scene, sp); //Make it a child agent for now... the grid will kill us later if we need to close sp.MakeChildAgent(); }
protected void SendFullUpdateForPresence (IScenePresence presence) { m_presence.ControllingClient.SendAvatarDataImmediate (presence); //Send the animations too presence.Animator.SendAnimPackToClient (m_presence.ControllingClient); //Send the presence of this agent to us IAvatarAppearanceModule module = presence.RequestModuleInterface<IAvatarAppearanceModule>(); if(module != null) module.SendAppearanceToAgent(m_presence); //We need to send all attachments of this avatar as well IAttachmentsModule attmodule = m_presence.Scene.RequestModuleInterface<IAttachmentsModule>(); if (attmodule != null) { ISceneEntity[] entities = attmodule.GetAttachmentsForAvatar (m_presence.UUID); foreach (ISceneEntity entity in entities) { foreach (ISceneChildEntity child in entity.ChildrenEntities ()) { QueuePartForUpdate (child, PrimUpdateFlags.ForcedFullUpdate); } } } }
public void ResumeAvatar(IScenePresence presence) { Util.FireAndForget(delegate { IAvatarAppearanceModule appearance = presence.RequestModuleInterface<IAvatarAppearanceModule>(); if (null == appearance || null == appearance.Appearance) { MainConsole.Instance.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", presence.UUID); return; } //Create the avatar attachments plugin for the av AvatarAttachments attachmentsPlugin = new AvatarAttachments(presence); presence.RegisterModuleInterface(attachmentsPlugin); List<AvatarAttachment> attachments = appearance.Appearance.GetAttachments(); foreach (AvatarAttachment attach in attachments) { try { RezSingleAttachmentFromInventory(presence.ControllingClient, attach.ItemID, 0); } catch (Exception e) { MainConsole.Instance.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}", e); } } }); }
// What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? protected void DetachSingleAttachmentToInventoryInternal(UUID itemID, IClientAPI remoteClient, bool fireEvent) { if (itemID == UUID.Zero) // If this happened, someone made a mistake.... { return; } // We can NOT use the dictionaries here, as we are looking // for an entity by the fromAssetID, which is NOT the prim UUID ISceneEntity[] attachments = GetAttachmentsForAvatar(remoteClient.AgentId); foreach (ISceneEntity group in attachments) { if (group.RootChild.FromUserInventoryItemID == itemID) { if (fireEvent) { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); group.DetachToInventoryPrep(); } IScenePresence presence = m_scene.GetScenePresence(remoteClient.AgentId); if (presence != null) { AvatarAttachments attModule = presence.RequestModuleInterface <AvatarAttachments>(); if (attModule != null) { attModule.RemoveAttachment(group); } } m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); //Update the saved attach points if (group.RootChild.AttachedPos != group.RootChild.SavedAttachedPos || group.RootChild.SavedAttachmentPoint != group.RootChild.AttachmentPoint) { group.RootChild.SavedAttachedPos = group.RootChild.AttachedPos; group.RootChild.SavedAttachmentPoint = group.RootChild.AttachmentPoint; //Make sure we get updated group.HasGroupChanged = true; } // If an item contains scripts, it's always changed. // This ensures script state is saved on detach foreach (ISceneChildEntity p in group.ChildrenEntities()) { if (p.Inventory.ContainsScripts()) { group.HasGroupChanged = true; break; } } UpdateKnownItem(remoteClient, group, group.RootChild.FromUserInventoryItemID, group.OwnerID); IBackupModule backup = m_scene.RequestModuleInterface <IBackupModule>(); if (backup != null) { backup.DeleteSceneObjects(new ISceneEntity[1] { group }, true); } return; //All done, end } } }
/// <summary> /// This Closes child agents on neighboring regions /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// </summary> protected IScenePresence CrossAgentToNewRegionAsync(IScenePresence agent, Vector3 pos, GridRegion crossingRegion, bool isFlying, bool positionIsAlreadyFixed) { m_log.DebugFormat("[EntityTransferModule]: Crossing agent {0} to region {1}", agent.Name, crossingRegion.RegionName); IScene m_scene = agent.Scene; try { if (crossingRegion != null) { //Make sure that all attachments are ready for the teleport IAttachmentsModule attModule = agent.Scene.RequestModuleInterface<IAttachmentsModule>(); if (attModule != null) attModule.ValidateAttachments(agent.UUID); if(!positionIsAlreadyFixed) { int xOffset = crossingRegion.RegionLocX - m_scene.RegionInfo.RegionLocX; int yOffset = crossingRegion.RegionLocY - m_scene.RegionInfo.RegionLocY; if(xOffset < 0) pos.X += m_scene.RegionInfo.RegionSizeX; else if(xOffset > 0) pos.X -= m_scene.RegionInfo.RegionSizeX; if(yOffset < 0) pos.Y += m_scene.RegionInfo.RegionSizeY; else if(yOffset > 0) pos.Y -= m_scene.RegionInfo.RegionSizeY; //Make sure that they are within bounds (velocity can push it out of bounds) if(pos.X < 0) pos.X = 1; if(pos.Y < 0) pos.Y = 1; if(pos.X > crossingRegion.RegionSizeX) pos.X = crossingRegion.RegionSizeX - 1; if(pos.Y > crossingRegion.RegionSizeY) pos.Y = crossingRegion.RegionSizeY - 1; } AgentData cAgent = new AgentData(); agent.CopyTo(cAgent); cAgent.Position = pos; if (isFlying) cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; AgentCircuitData agentCircuit = agent.ControllingClient.RequestClientInfo(); agentCircuit.startpos = pos; agentCircuit.child = false; agentCircuit.teleportFlags = (uint)TeleportFlags.ViaRegionID; IAvatarAppearanceModule appearance = agent.RequestModuleInterface<IAvatarAppearanceModule>(); if (appearance != null) agentCircuit.Appearance = appearance.Appearance; IEventQueueService eq = agent.Scene.RequestModuleInterface<IEventQueueService>(); if (eq != null) { //This does UpdateAgent and closing of child agents // messages if they need to be called ISyncMessagePosterService syncPoster = agent.Scene.RequestModuleInterface<ISyncMessagePosterService>(); if (syncPoster != null) { OSDMap map = syncPoster.Get(SyncMessageHelper.CrossAgent(crossingRegion, pos, agent.Velocity, agentCircuit, cAgent, agent.Scene.RegionInfo.RegionHandle), agent.UUID, agent.Scene.RegionInfo.RegionHandle); bool result = false; if (map != null) result = map["Success"].AsBoolean(); if (!result) { //Fix user's attachments attModule.RezAttachments (agent); if (map != null) { if (map.ContainsKey("Note") && !map["Note"].AsBoolean ()) return agent; agent.ControllingClient.SendTeleportFailed (map["Reason"].AsString ()); } else agent.ControllingClient.SendTeleportFailed ("TP Failed"); if (agent.PhysicsActor != null) agent.PhysicsActor.IsPhysical = true; //Fix the setting that we set earlier // In any case agent.FailedCrossingTransit(crossingRegion); return agent; } } } //We're killing the animator and the physics actor, so we don't need to worry about agent.PhysicsActor.IsPhysical agent.MakeChildAgent(crossingRegion); //Revolution- We already were in this region... we don't need updates about the avatars we already know about, right? // OLD: now we have a child agent in this region. Request and send all interesting data about (root) agents in the sim //agent.SendOtherAgentsAvatarDataToMe(); //agent.SendOtherAgentsAppearanceToMe(); //Kill the groups here, otherwise they will become ghost attachments // and stay in the sim, they'll get readded below into the new sim KillAttachments(agent); } } catch(Exception ex) { m_log.Warn("[EntityTransferModule]: Exception in crossing: " + ex.ToString()); } // In any case agent.SuccessfulCrossingTransit(crossingRegion); return agent; }
public void PhysicsActor_OnCollisionUpdate(EventArgs e) { if (m_SP == null || m_SP.Scene == null || m_SP.Invulnerable || HasLeftCombat || e == null) { return; } CollisionEventUpdate collisionData = (CollisionEventUpdate)e; Dictionary <uint, ContactPoint> coldata = collisionData.GetCollisionEvents(); float starthealth = Health; IScenePresence killingAvatar = null; foreach (uint localid in coldata.Keys) { ISceneChildEntity part = m_SP.Scene.GetSceneObjectPart(localid); IScenePresence otherAvatar = null; if (part != null && part.ParentEntity.Damage > 0) { otherAvatar = m_SP.Scene.GetScenePresence(part.OwnerID); ICombatPresence OtherAvatarCP = otherAvatar == null ? null : otherAvatar.RequestModuleInterface <ICombatPresence> (); if (OtherAvatarCP != null && OtherAvatarCP.HasLeftCombat) { // If the avatar is null, the person is not inworld, and not on a team //If they have left combat, do not let them cause any damage. continue; } //Check max damage to inflict if (part.ParentEntity.Damage > m_combatModule.MaximumDamageToInflict) { part.ParentEntity.Damage = m_combatModule.MaximumDamageToInflict; } // If the avatar is null, the person is not inworld, and not on a team if (m_combatModule.AllowTeams && OtherAvatarCP != null && otherAvatar.UUID != m_SP.UUID && OtherAvatarCP.Team == Team) { float Hits = 0; if (!TeamHits.TryGetValue(otherAvatar.UUID, out Hits)) { Hits = 0; } Hits++; if (m_combatModule.SendTeamKillerInfo && Hits == m_combatModule.TeamHitsBeforeSend) { otherAvatar.ControllingClient.SendAlertMessage("You have shot too many teammates and " + m_combatModule.DamageToTeamKillers + " health has been taken from you!"); OtherAvatarCP.IncurDamage(null, m_combatModule.DamageToTeamKillers); Hits = 0; } TeamHits [otherAvatar.UUID] = Hits; if (m_combatModule.AllowTeamKilling) //Green light on team killing { Health -= part.ParentEntity.Damage; } } else //Object, hit em { Health -= part.ParentEntity.Damage; } } else { float Z = m_SP.Velocity.Length(); if (coldata [localid].PenetrationDepth >= 0.05f && m_SP.Velocity.Z < -3 && !m_SP.PhysicsActor.Flying && !m_SP.PhysicsActor.IsJumping) { Z = Math.Max(Z, 1.5f) * 10; float damage = Math.Min(coldata [localid].PenetrationDepth, 15f); Health -= damage * Z; } } if (Health > m_combatModule.MaximumHealth) { Health = m_combatModule.MaximumHealth; } if (Health <= 0 && killingAvatar == null) { killingAvatar = otherAvatar; } //MainConsole.Instance.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString()); } if (starthealth != Health) { m_SP.ControllingClient.SendHealth(Health); } if (Health <= 0) { KillAvatar(killingAvatar, "You killed " + m_SP.Name, "You died!", true, true); } }
public void SuspendAvatar(IScenePresence presence, GridRegion destination) { IAvatarAppearanceModule appearance = presence.RequestModuleInterface<IAvatarAppearanceModule>(); presence.AttachmentsLoaded = false; ISceneEntity[] attachments = GetAttachmentsForAvatar(presence.UUID); foreach (ISceneEntity group in attachments) { if (group.RootChild.AttachedPos != group.RootChild.SavedAttachedPos || group.RootChild.SavedAttachmentPoint != group.RootChild.AttachmentPoint) { group.RootChild.SavedAttachedPos = group.RootChild.AttachedPos; group.RootChild.SavedAttachmentPoint = group.RootChild.AttachmentPoint; //Make sure we get updated group.HasGroupChanged = true; } // If an item contains scripts, it's always changed. // This ensures script state is saved on detach foreach (ISceneChildEntity p in group.ChildrenEntities()) { if (p.Inventory.ContainsScripts()) { group.HasGroupChanged = true; break; } } if (group.HasGroupChanged) { UUID assetID = UpdateKnownItem(presence.ControllingClient, group, group.RootChild.FromUserInventoryItemID, group.OwnerID); group.RootChild.FromUserInventoryAssetID = assetID; } } if (appearance != null) { appearance.Appearance.SetAttachments(attachments); presence.Scene.AvatarService.SetAppearance(presence.UUID, appearance.Appearance); } IBackupModule backup = presence.Scene.RequestModuleInterface<IBackupModule>(); if (backup != null) { bool sendUpdates = destination == null; if (!sendUpdates) { List<GridRegion> regions = presence.Scene.RequestModuleInterface<IGridRegisterModule>() .GetNeighbors(presence.Scene); regions.RemoveAll((r) => r.RegionID != destination.RegionID); sendUpdates = regions.Count == 0; } backup.DeleteSceneObjects(attachments, false, sendUpdates); } }
private void AvatarEnteringParcel(IScenePresence avatar, ILandObject oldParcel) { ILandObject obj = null; IParcelManagementModule parcelManagement = avatar.Scene.RequestModuleInterface<IParcelManagementModule>(); if (parcelManagement != null) { obj = parcelManagement.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); } if (obj == null) return; try { if ((obj.LandData.Flags & (uint) ParcelFlags.AllowDamage) != 0) { ICombatPresence CP = avatar.RequestModuleInterface<ICombatPresence>(); CP.Health = MaximumHealth; avatar.Invulnerable = false; } else { avatar.Invulnerable = true; } } catch (Exception) { } }
protected void EventManager_OnRemovePresence(IScenePresence presence) { PerClientSelectionParticles particles = presence.RequestModuleInterface<PerClientSelectionParticles>(); if (particles != null) { particles.Close(); presence.UnregisterModuleInterface(particles); } }
private void EventManager_OnRemovePresence(IScenePresence presence) { CombatPresence m = (CombatPresence) presence.RequestModuleInterface<ICombatPresence>(); if (m != null) { presence.UnregisterModuleInterface<ICombatPresence>(m); m.Close(); } }
private AgentCircuitData BuildCircuitDataForPresence(IScenePresence sp, Vector3 position) { AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); agentCircuit.startpos = position; //The agent will be a root agent agentCircuit.child = false; //Make sure the appearnace is right IAvatarAppearanceModule appearance = sp.RequestModuleInterface<IAvatarAppearanceModule>(); if (appearance != null && appearance.Appearance != null) agentCircuit.Appearance = appearance.Appearance; else MainConsole.Instance.Error("[EntityTransferModule]: No appearance is being packed as we could not find the appearance ? " + appearance == null); AgentCircuitData oldCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID); agentCircuit.ServiceURLs = oldCircuit.ServiceURLs; agentCircuit.firstname = oldCircuit.firstname; agentCircuit.lastname = oldCircuit.lastname; agentCircuit.ServiceSessionID = oldCircuit.ServiceSessionID; return agentCircuit; }
protected void MakeChildAgent (IScenePresence presence) { IAvatarAppearanceModule appearance = presence.RequestModuleInterface<IAvatarAppearanceModule> (); foreach (AvatarAttachment att in appearance.Appearance.GetAttachments ()) { //Don't fire events as we just want to remove them // and we don't want to remove the attachment from the av either DetachSingleAttachmentToInventoryInternal(att.ItemID, presence.ControllingClient, false); } }
protected LSL_Key SaveAppearanceToNotecard(IScenePresence sp, string notecard) { IAvatarAppearanceModule aa = sp.RequestModuleInterface<IAvatarAppearanceModule> (); if (aa != null) { var appearance = new AvatarAppearance (aa.Appearance); OSDMap appearancePacked = appearance.Pack (); TaskInventoryItem item = SaveNotecard (notecard, "Avatar Appearance", OSDParser.SerializeLLSDXmlString(appearancePacked), true); return new LSL_Key (item.AssetID.ToString ()); } return new LSL_Key(UUID.Zero.ToString()); }
public UUID CreateAvatar(string firstName, string lastName, IScene scene, AvatarAppearance avatarApp, UUID creatorID, Vector3 startPos) { //Add the circuit data so they can login AgentCircuitData m_aCircuitData = new AgentCircuitData { IsChildAgent = false, CircuitCode = (uint)Util.RandomClass.Next() }; //Create the new bot data BotClientAPI m_character = new BotClientAPI(scene, m_aCircuitData); m_character.Name = firstName + " " + lastName; m_aCircuitData.AgentID = m_character.AgentId; //Set up appearance var origOwner = avatarApp.Owner; avatarApp.Owner = m_character.AgentId; List <AvatarAttachment> attachments = avatarApp.GetAttachments(); avatarApp.ClearAttachments(); // get original attachments foreach (AvatarAttachment t in attachments) { InventoryItemBase item = scene.InventoryService.GetItem(origOwner, t.ItemID); if (item != null) { item.ID = UUID.Random(); item.Owner = m_character.AgentId; item.Folder = UUID.Zero; scene.InventoryService.AddCacheItemAsync(item); //Now fix the ItemID avatarApp.SetAttachment(t.AttachPoint, item.ID, t.AssetID); } } scene.AuthenticateHandler.AgentCircuits.Add(m_character.CircuitCode, m_aCircuitData); //This adds them to the scene and sets them in world AddAndWaitUntilAgentIsAdded(scene, m_character); IScenePresence SP = scene.GetScenePresence(m_character.AgentId); if (SP == null) { return(UUID.Zero); //Failed! } // set this as a NPC character SP.IsNpcAgent = true; IAvatarAppearanceModule appearance = SP.RequestModuleInterface <IAvatarAppearanceModule>(); appearance.Appearance = avatarApp; appearance.InitialHasWearablesBeenSent = true; Bot bot = new Bot(); bot.Initialize(SP, creatorID); try { SP.MakeRootAgent(startPos, false, true); } catch { MainConsole.Instance.ErrorFormat("[BotManager]: Error creating bot {0} as root agent!", m_character.AgentId); } //Move them SP.Teleport(startPos); foreach (var presence in scene.GetScenePresences()) { presence.SceneViewer.QueuePresenceForUpdate(SP, PrimUpdateFlags.ForcedFullUpdate); } IAttachmentsModule attModule = SP.Scene.RequestModuleInterface <IAttachmentsModule>(); if (attModule != null) { foreach (AvatarAttachment att in attachments) { attModule.RezSingleAttachmentFromInventory(SP.ControllingClient, att.ItemID, att.AssetID, 0, true); } } //Save them in the bots list m_bots.Add(m_character.AgentId, bot); AddTagToBot(m_character.AgentId, "AllBots", bot.AvatarCreatorID); MainConsole.Instance.InfoFormat("[BotManager]: Added bot {0} to region {1}", m_character.Name, scene.RegionInfo.RegionName); //Return their UUID return(m_character.AgentId); }
private void EventManager_OnRemovePresence(IScenePresence presence) { AvatarApperanceModule m = (AvatarApperanceModule) presence.RequestModuleInterface<IAvatarAppearanceModule>(); if (m != null) { m.Close(); presence.UnregisterModuleInterface<IAvatarAppearanceModule>(m); } }
private bool InBoundingBox(IScenePresence avatar, Vector3 point) { float height = avatar.RequestModuleInterface<IAvatarAppearanceModule>().Appearance.AvatarHeight; Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height / 2); Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height / 2); if (point.X > b1.X && point.X < b2.X && point.Y > b1.Y && point.Y < b2.Y && point.Z > b1.Z && point.Z < b2.Z) return true; return false; }