diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs index e95db4120d..2ec9652b8a 100644 --- a/OpenSim/Addons/Groups/GroupsMessagingModule.cs +++ b/OpenSim/Addons/Groups/GroupsMessagingModule.cs @@ -627,6 +627,7 @@ namespace OpenSim.Groups , false //canVoiceChat , false //isModerator , false //text mute + , true // Enter ); } } @@ -669,6 +670,7 @@ namespace OpenSim.Groups , false //canVoiceChat , false //isModerator , false //text mute + , true ); } } diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs index 1afdd0fba3..e586dd7f34 100644 --- a/OpenSim/Addons/Groups/GroupsModule.cs +++ b/OpenSim/Addons/Groups/GroupsModule.cs @@ -249,7 +249,8 @@ namespace OpenSim.Groups // There might be some problem with the thread we're generating this on but not // doing the update at this time causes problems (Mantis #7920 and #7915) // TODO: move sending this update to a later time in the rootification of the client. - SendAgentGroupDataUpdate(sp.ControllingClient, false); + if(!sp.haveGroupInformation) + SendAgentGroupDataUpdate(sp.ControllingClient, false); } private void OnMakeChild(ScenePresence sp) diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index 72c2c346d7..74f18bf677 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -353,6 +353,10 @@ namespace OpenSim.Framework public UUID PreyAgent; public Byte AgentAccess; public UUID ActiveGroupID; + public string ActiveGroupName; + public string ActiveGroupTitle = null; + public UUID agentCOF; + public byte CrossingFlags; public AgentGroupData[] Groups; public Dictionary ChildrenCapSeeds = null; @@ -361,7 +365,6 @@ namespace OpenSim.Framework public Animation AnimState = null; public Byte MotionState = 0; - public UUID GranterID; public UUID ParentPart; public Vector3 SitOffset; @@ -374,12 +377,6 @@ namespace OpenSim.Framework MethodBase.GetCurrentMethod().DeclaringType); // DEBUG OFF -/* - public byte[] AgentTextures; - public byte[] VisualParams; - public UUID[] Wearables; - public AvatarAttachment[] Attachments; -*/ // Scripted public ControllerData[] Controllers; @@ -393,8 +390,6 @@ namespace OpenSim.Framework public virtual OSDMap Pack(EntityTransferContext ctx) { - int wearablesCount = -1; - // m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data"); OSDMap args = new OSDMap(); @@ -433,8 +428,14 @@ namespace OpenSim.Framework args["prey_agent"] = OSD.FromUUID(PreyAgent); args["agent_access"] = OSD.FromString(AgentAccess.ToString()); + args["agent_cof"] = OSD.FromUUID(agentCOF); + args["crossingflags"] = OSD.FromInteger(CrossingFlags); + args["active_group_id"] = OSD.FromUUID(ActiveGroupID); - + args["active_group_name"] = OSD.FromString(ActiveGroupName); + if(ActiveGroupTitle != null) + args["active_group_title"] = OSD.FromString(ActiveGroupTitle); + if ((Groups != null) && (Groups.Length > 0)) { OSDArray groups = new OSDArray(Groups.Length); @@ -497,48 +498,6 @@ namespace OpenSim.Framework if (Appearance != null) args["packed_appearance"] = Appearance.Pack(ctx); - //if ((AgentTextures != null) && (AgentTextures.Length > 0)) - //{ - // OSDArray textures = new OSDArray(AgentTextures.Length); - // foreach (UUID uuid in AgentTextures) - // textures.Add(OSD.FromUUID(uuid)); - // args["agent_textures"] = textures; - //} - - // The code to pack textures, visuals, wearables and attachments - // should be removed; packed appearance contains the full appearance - // This is retained for backward compatibility only - -/* then lets remove - if (Appearance.Texture != null) - { - byte[] rawtextures = Appearance.Texture.GetBytes(); - args["texture_entry"] = OSD.FromBinary(rawtextures); - } - - if ((Appearance.VisualParams != null) && (Appearance.VisualParams.Length > 0)) - args["visual_params"] = OSD.FromBinary(Appearance.VisualParams); - - // We might not pass this in all cases... - if ((Appearance.Wearables != null) && (Appearance.Wearables.Length > 0)) - { - OSDArray wears = new OSDArray(Appearance.Wearables.Length); - foreach (AvatarWearable awear in Appearance.Wearables) - wears.Add(awear.Pack()); - - args["wearables"] = wears; - } - - List attachments = Appearance.GetAttachments(); - if ((attachments != null) && (attachments.Count > 0)) - { - OSDArray attachs = new OSDArray(attachments.Count); - foreach (AvatarAttachment att in attachments) - attachs.Add(att.Pack()); - args["attachments"] = attachs; - } - // End of code to remove -*/ if ((Controllers != null) && (Controllers.Length > 0)) { OSDArray controls = new OSDArray(Controllers.Length); @@ -662,10 +621,22 @@ namespace OpenSim.Framework if (args["agent_access"] != null) Byte.TryParse(args["agent_access"].AsString(), out AgentAccess); - if (args["active_group_id"] != null) + if (args.ContainsKey("agent_cof") && args["agent_cof"] != null) + agentCOF = args["agent_cof"].AsUUID(); + + if (args.ContainsKey("crossingflags") && args["crossingflags"] != null) + CrossingFlags = (byte)args["crossingflags"].AsInteger(); + + if (args.ContainsKey("active_group_id") && args["active_group_id"] != null) ActiveGroupID = args["active_group_id"].AsUUID(); - if ((args["groups"] != null) && (args["groups"]).Type == OSDType.Array) + if (args.ContainsKey("active_group_name") && args["active_group_name"] != null) + ActiveGroupName = args["active_group_name"].AsString(); + + if(args.ContainsKey("active_group_title") && args["active_group_title"] != null) + ActiveGroupTitle = args["active_group_title"].AsString(); + + if (args.ContainsKey("groups") && (args["groups"] != null) && (args["groups"]).Type == OSDType.Array) { OSDArray groups = (OSDArray)(args["groups"]); Groups = new AgentGroupData[groups.Count]; diff --git a/OpenSim/Framework/GridInstantMessage.cs b/OpenSim/Framework/GridInstantMessage.cs index da3690c93b..53d98db236 100644 --- a/OpenSim/Framework/GridInstantMessage.cs +++ b/OpenSim/Framework/GridInstantMessage.cs @@ -47,6 +47,7 @@ namespace OpenSim.Framework public uint ParentEstateID; public Guid RegionID; public uint timestamp; + public Guid ID; public GridInstantMessage() { @@ -66,6 +67,8 @@ namespace OpenSim.Framework Position = im.Position; binaryBucket = im.binaryBucket; RegionID = im.RegionID; + ParentEstateID = im.ParentEstateID; + ID = im.ID; if (addTimestamp) timestamp = (uint)Util.UnixTimeSinceEpoch(); @@ -75,7 +78,7 @@ namespace OpenSim.Framework string _fromAgentName, UUID _toAgentID, byte _dialog, bool _fromGroup, string _message, UUID _imSessionID, bool _offline, Vector3 _position, - byte[] _binaryBucket, bool addTimestamp) + byte[] _binaryBucket, UUID _ID, bool addTimestamp) { fromAgentID = _fromAgentID.Guid; fromAgentName = _fromAgentName; @@ -84,6 +87,8 @@ namespace OpenSim.Framework fromGroup = _fromGroup; message = _message; imSessionID = _imSessionID.Guid; + ID = _ID.Guid; + if (_offline) offline = 1; else @@ -101,12 +106,22 @@ namespace OpenSim.Framework timestamp = (uint)Util.UnixTimeSinceEpoch(); } + public GridInstantMessage(IScene scene, UUID _fromAgentID, + string _fromAgentName, UUID _toAgentID, + byte _dialog, bool _fromGroup, string _message, + UUID _imSessionID, bool _offline, Vector3 _position, + byte[] _binaryBucket, bool addTimestamp) : this (scene, _fromAgentID, + _fromAgentName, _toAgentID, _dialog, _fromGroup, _message, + _imSessionID, _offline, _position, _binaryBucket, UUID.Zero, addTimestamp) + { + } + public GridInstantMessage(IScene scene, UUID _fromAgentID, string _fromAgentName, UUID _toAgentID, byte _dialog, string _message, bool _offline, Vector3 _position) : this(scene, _fromAgentID, _fromAgentName, _toAgentID, _dialog, false, _message, - _fromAgentID ^ _toAgentID, _offline, _position, new byte[0], true) + _fromAgentID ^ _toAgentID, _offline, _position, new byte[0], UUID.Zero, true) { } } diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index d9932eb544..9bf51f889c 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -727,11 +727,15 @@ namespace OpenSim.Framework UUID SecureSessionId { get; } - UUID ActiveGroupId { get; } + UUID ActiveGroupId { get; set; } - string ActiveGroupName { get; } + string ActiveGroupName { get; set;} - ulong ActiveGroupPowers { get; } + ulong ActiveGroupPowers { get; set;} + + Dictionary GetGroupPowers(); + + void SetGroupPowers(Dictionary powers); ulong GetGroupPowers(UUID groupID); diff --git a/OpenSim/Framework/IMoneyModule.cs b/OpenSim/Framework/IMoneyModule.cs index 55c9613b6a..be454385db 100644 --- a/OpenSim/Framework/IMoneyModule.cs +++ b/OpenSim/Framework/IMoneyModule.cs @@ -32,14 +32,13 @@ namespace OpenSim.Framework public delegate void ObjectPaid(UUID objectID, UUID agentID, int amount); public interface IMoneyModule { - bool ObjectGiveMoney(UUID objectID, UUID fromID, UUID toID, - int amount, UUID txn, out string reason); + bool ObjectGiveMoney(UUID objectID, UUID fromID, + UUID toID, int amount, UUID txn, out string reason); int GetBalance(UUID agentID); bool UploadCovered(UUID agentID, int amount); bool AmountCovered(UUID agentID, int amount); - void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type); - void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData); + void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData = ""); void ApplyUploadCharge(UUID agentID, int amount, string text); void MoveMoney(UUID fromUser, UUID toUser, int amount, string text); diff --git a/OpenSim/Framework/ISceneAgent.cs b/OpenSim/Framework/ISceneAgent.cs index be11931109..1848b1757e 100644 --- a/OpenSim/Framework/ISceneAgent.cs +++ b/OpenSim/Framework/ISceneAgent.cs @@ -55,6 +55,7 @@ namespace OpenSim.Framework /// bool IsChildAgent { get; } + bool Invulnerable { get; set; } /// /// Avatar appearance data. /// diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 3426d10d9b..1d4deac7bc 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -157,7 +157,16 @@ namespace OpenSim.Framework.Servers "[STARTUP]: Operating system version: {0}, .NET platform {1}, {2}-bit\n", Environment.OSVersion, Environment.OSVersion.Platform, Util.Is64BitProcess() ? "64" : "32"); - StartupSpecific(); + try + { + StartupSpecific(); + } + catch(Exception e) + { + m_log.FatalFormat("Fatal error: {0}", + (e.Message == null || e.Message == String.Empty) ? "Unknown reason":e.Message ); + Environment.Exit(1); + } TimeSpan timeTaken = DateTime.Now - m_startuptime; diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 41966ff325..52ded3d055 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -218,6 +218,13 @@ namespace OpenSim IConfig startupConfig = Config.Configs["Startup"]; if (startupConfig != null) { + // refuse to run MegaRegions + if(startupConfig.GetBoolean("CombineContiguousRegions", false)) + { + m_log.Fatal("CombineContiguousRegions (MegaRegions) option is no longer suported. Use a older version to save region contents as OAR, then import into a fresh install of this new version"); + throw new Exception("CombineContiguousRegions not suported"); + } + string pidFile = startupConfig.GetString("PIDFile", String.Empty); if (pidFile != String.Empty) CreatePIDFile(pidFile); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 18670f5ced..f3acacd649 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -568,12 +568,12 @@ namespace OpenSim.Region.ClientStack.Linden } - public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat, - bool isModerator, bool textMute) + public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, + bool isModerator, bool textMute, bool isEnterorLeave) { OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat, - isModerator, textMute); - Enqueue(item, fromAgent); + isModerator, textMute, isEnterorLeave); + Enqueue(item, toAgent); //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item); } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs index 8beeb95b09..d552914e81 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs @@ -308,20 +308,29 @@ namespace OpenSim.Region.ClientStack.Linden } public static OSD ChatterBoxSessionAgentListUpdates(UUID sessionID, - UUID agentID, bool canVoiceChat, bool isModerator, bool textMute) + UUID agentID, bool canVoiceChat, bool isModerator, bool textMute, bool isEnterorLeave) { OSDMap body = new OSDMap(); OSDMap agentUpdates = new OSDMap(); OSDMap infoDetail = new OSDMap(); OSDMap mutes = new OSDMap(); + // this should be a list of agents and parameters + // foreach agent mutes.Add("text", OSD.FromBoolean(textMute)); infoDetail.Add("can_voice_chat", OSD.FromBoolean(canVoiceChat)); infoDetail.Add("is_moderator", OSD.FromBoolean(isModerator)); infoDetail.Add("mutes", mutes); OSDMap info = new OSDMap(); info.Add("info", infoDetail); + if(isEnterorLeave) + info.Add("transition",OSD.FromString("ENTER")); + else + info.Add("transition",OSD.FromString("LEAVE")); agentUpdates.Add(agentID.ToString(), info); + + // foreach end + body.Add("agent_updates", agentUpdates); body.Add("session_id", OSD.FromUUID(sessionID)); body.Add("updates", new OSD()); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 6dd2ffd15b..0bb5dc68ea 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -421,9 +421,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP } public UUID AgentId { get { return m_agentId; } } public ISceneAgent SceneAgent { get; set; } - public UUID ActiveGroupId { get { return m_activeGroupID; } private set { m_activeGroupID = value; } } - public string ActiveGroupName { get { return m_activeGroupName; } private set { m_activeGroupName = value; } } - public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } private set { m_activeGroupPowers = value; } } + public UUID ActiveGroupId { get { return m_activeGroupID; } set { m_activeGroupID = value; } } + public string ActiveGroupName { get { return m_activeGroupName; } set { m_activeGroupName = value; } } + public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } set { m_activeGroupPowers = value; } } public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } public int PingTimeMS @@ -953,7 +953,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Send an instant message to this client /// // - // Don't remove transaction ID! Groups and item gives need to set it! public void SendInstantMessage(GridInstantMessage im) { if (((Scene)(m_scene)).Permissions.CanInstantMessage(new UUID(im.fromAgentID), new UUID(im.toAgentID))) @@ -962,14 +961,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP = (ImprovedInstantMessagePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedInstantMessage); msg.AgentData.AgentID = new UUID(im.fromAgentID); - msg.AgentData.SessionID = UUID.Zero; + msg.AgentData.SessionID = new UUID(im.imSessionID); msg.MessageBlock.FromAgentName = Util.StringToBytes256(im.fromAgentName); msg.MessageBlock.Dialog = im.dialog; msg.MessageBlock.FromGroup = im.fromGroup; - if (im.imSessionID == UUID.Zero.Guid) - msg.MessageBlock.ID = new UUID(im.fromAgentID) ^ new UUID(im.toAgentID); - else - msg.MessageBlock.ID = new UUID(im.imSessionID); + msg.MessageBlock.ID = new UUID(im.ID); msg.MessageBlock.Offline = im.offline; msg.MessageBlock.ParentEstateID = im.ParentEstateID; msg.MessageBlock.Position = im.Position; @@ -5786,6 +5782,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(packet, ThrottleOutPacketType.Task); } + public Dictionary GetGroupPowers() + { + lock(m_groupPowers) + { + return new Dictionary(m_groupPowers); + } + } + + public void SetGroupPowers(Dictionary powers) + { + lock(m_groupPowers) + { + m_groupPowers.Clear(); + m_groupPowers = powers; + } + } + public ulong GetGroupPowers(UUID groupID) { if (groupID == ActiveGroupId) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index d6c4d5bdf5..c88142a47f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -217,7 +217,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnClientClosed += OnClientClosed; - scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; +// scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; scene.EventManager.OnClientLogin += OnClientLogin; } @@ -255,6 +255,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return 0; } + private void OnMakeRootAgent(ScenePresence sp) + { + if(sp.gotCrossUpdate) + return; + + RecacheFriends(sp.ControllingClient); + + lock (m_NeedsToNotifyStatus) + { + if (m_NeedsToNotifyStatus.Remove(sp.UUID)) + { + // Inform the friends that this user is online. This can only be done once the client is a Root Agent. + StatusChange(sp.UUID, true); + } + } + } + private void OnNewClient(IClientAPI client) { client.OnInstantMessage += OnInstantMessage; @@ -327,20 +344,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } - private void OnMakeRootAgent(ScenePresence sp) - { - RecacheFriends(sp.ControllingClient); - - lock (m_NeedsToNotifyStatus) - { - if (m_NeedsToNotifyStatus.Remove(sp.UUID)) - { - // Inform the friends that this user is online. This can only be done once the client is a Root Agent. - StatusChange(sp.UUID, true); - } - } - } - private void OnClientLogin(IClientAPI client) { UUID agentID = client.AgentId; @@ -359,6 +362,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends m_NeedsListOfOnlineFriends.Add(agentID); } + public void IsNpwRoot(ScenePresence sp) + { + RecacheFriends(sp.ControllingClient); + + lock (m_NeedsToNotifyStatus) + { + if (m_NeedsToNotifyStatus.Remove(sp.UUID)) + { + // Inform the friends that this user is online. This can only be done once the client is a Root Agent. + StatusChange(sp.UUID, true); + } + } + } + public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client) { UUID agentID = client.AgentId; diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs index a1b918a3b6..63b3dba544 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs @@ -147,7 +147,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // "[HG INSTANT MESSAGE]: Looking for root agent {0} in {1}", // toAgentID.ToString(), scene.RegionInfo.RegionName); ScenePresence sp = scene.GetScenePresence(toAgentID); - if (sp != null && !sp.IsChildAgent) + if (sp != null && !sp.IsChildAgent && !sp.IsDeleted) { // Local message // m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID); @@ -159,25 +159,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } } - // try child avatar second - foreach (Scene scene in m_Scenes) - { -// m_log.DebugFormat( -// "[HG INSTANT MESSAGE]: Looking for child of {0} in {1}", -// toAgentID, scene.RegionInfo.RegionName); - ScenePresence sp = scene.GetScenePresence(toAgentID); - if (sp != null) - { - // Local message -// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID); - sp.ControllingClient.SendInstantMessage(im); - - // Message sent - result(true); - return; - } - } - // m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); // Is the user a local user? string url = string.Empty; @@ -224,7 +205,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage foreach (Scene scene in m_Scenes) { ScenePresence sp = scene.GetScenePresence(toAgentID); - if(sp != null && !sp.IsChildAgent) + if(sp != null && !sp.IsChildAgent && !sp.IsDeleted) { scene.EventManager.TriggerIncomingInstantMessage(gim); successful = true; @@ -310,7 +291,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage foreach (Scene scene in m_Scenes) { ScenePresence presence = scene.GetScenePresence(agentID); - if (presence != null && !presence.IsChildAgent) + if (presence != null && !presence.IsChildAgent && !presence.IsDeleted) return presence.ControllingClient; } } diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index 3c82fd9145..1366103328 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -142,47 +142,36 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if (toAgentID == UUID.Zero) return; + IClientAPI client = null; + // Try root avatar only first foreach (Scene scene in m_Scenes) { -// m_log.DebugFormat( -// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}", -// toAgentID.ToString(), scene.RegionInfo.RegionName); - ScenePresence sp = scene.GetScenePresence(toAgentID); - if (sp != null && !sp.IsChildAgent) + if (sp != null && !sp.IsDeleted && sp.ControllingClient.IsActive) { - // Local message + // actualy don't send via child agents + // ims can be complex things, and not sure viewers will not mess up + if(sp.IsChildAgent) + continue; + + client = sp.ControllingClient; + if(!sp.IsChildAgent) + break; + } + } + + if(client != null) + { + // Local message // m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID); - sp.ControllingClient.SendInstantMessage(im); + client.SendInstantMessage(im); // Message sent - result(true); - return; - } + result(true); + return; } - - // try child avatar second - foreach (Scene scene in m_Scenes) - { -// m_log.DebugFormat( -// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); - - ScenePresence sp = scene.GetScenePresence(toAgentID); - if (sp != null) - { - // Local message -// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID); - - sp.ControllingClient.SendInstantMessage(im); - - // Message sent - result(true); - return; - } - } - // m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); SendGridInstantMessageViaXMLRPC(im, result); @@ -227,6 +216,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage UUID fromAgentID = UUID.Zero; UUID toAgentID = UUID.Zero; UUID imSessionID = UUID.Zero; + UUID imID = UUID.Zero; uint timestamp = 0; string fromAgentName = ""; string message = ""; @@ -243,7 +233,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage float pos_z = 0; //m_log.Info("Processing IM"); - Hashtable requestData = (Hashtable)request.Params[0]; // Check if it's got all the data if (requestData.ContainsKey("from_agent_id") @@ -274,6 +263,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage UUID.TryParse((string)requestData["to_agent_id"], out toAgentID); UUID.TryParse((string)requestData["im_session_id"], out imSessionID); UUID.TryParse((string)requestData["region_id"], out RegionID); + UUID.TryParse((string)requestData["id"], out imID); try { @@ -401,6 +391,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage gim.ParentEstateID = ParentEstateID; gim.Position = Position; gim.binaryBucket = binaryBucket; + gim.ID = imID.Guid; // Trigger the Instant message in the scene. @@ -519,7 +510,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage UUID toAgentID = new UUID(im.toAgentID); PresenceInfo upd = null; - UUID regionID; bool lookupAgent = false; lock (m_UserRegionMap) @@ -712,6 +702,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage gim["from_agent_session"] = UUID.Zero.ToString(); gim["to_agent_id"] = msg.toAgentID.ToString(); gim["im_session_id"] = msg.imSessionID.ToString(); + if(msg.ID != Guid.Empty) + gim["id"] = msg.ID.ToString(); gim["timestamp"] = msg.timestamp.ToString(); gim["from_agent_name"] = msg.fromAgentName; gim["message"] = msg.message; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 696d1dd6d8..fbb99b0559 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -922,7 +922,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Let's send a full update of the agent. This is a synchronous call. AgentData agent = new AgentData(); - sp.CopyTo(agent); + sp.CopyTo(agent,false); if ((teleportFlags & (uint)TeleportFlags.IsFlying) != 0) agent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; @@ -1142,7 +1142,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Let's send a full update of the agent. AgentData agent = new AgentData(); - sp.CopyTo(agent); + sp.CopyTo(agent,false); agent.Position = agentCircuit.startpos; if ((teleportFlags & (uint)TeleportFlags.IsFlying) != 0) @@ -1560,7 +1560,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // We need this because of decimal number parsing of the protocols. Culture.SetCurrentCulture(); - Vector3 pos = agent.AbsolutePosition + agent.Velocity; + Vector3 pos = agent.AbsolutePosition + agent.Velocity * 0.2f; GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, pos, ctx, out newpos, out failureReason); @@ -1648,17 +1648,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer icon.EndInvoke(iar); } - public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion) - { - if (neighbourRegion == null) - return false; - - m_entityTransferStateMachine.SetInTransit(agent.UUID); - - agent.RemoveFromPhysicalScene(); - - return true; - } + /// /// This Closes child agents on neighbouring regions @@ -1673,16 +1663,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: new region={1} at <{2},{3}>. newpos={4}", LogHeader, neighbourRegion.RegionName, neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, pos); - if (!CrossAgentToNewRegionPrep(agent, neighbourRegion)) + if (neighbourRegion == null) { - m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: prep failed. Resetting transfer state", LogHeader); - m_entityTransferStateMachine.ResetFromTransit(agent.UUID); + m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: invalid destiny", LogHeader); + return agent; } + m_entityTransferStateMachine.SetInTransit(agent.UUID); + agent.RemoveFromPhysicalScene(); + if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying, ctx)) { m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: cross main failed. Resetting transfer state", LogHeader); m_entityTransferStateMachine.ResetFromTransit(agent.UUID); + return agent; } CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, ctx); @@ -1701,12 +1695,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer try { AgentData cAgent = new AgentData(); - agent.CopyTo(cAgent); + agent.CopyTo(cAgent,true); // agent.Appearance.WearableCacheItems = null; cAgent.Position = pos; - cAgent.ChildrenCapSeeds = agent.KnownRegions; if (isFlying) @@ -1787,15 +1780,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer capsPath); } -/* - // Backwards compatibility. Best effort - if (version == 0f) - { - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); - Thread.Sleep(3000); // wait a little now that we're not waiting for the callback - CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); - } -*/ // SUCCESS! m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); @@ -1814,18 +1798,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // but not sure yet what the side effects would be. m_entityTransferStateMachine.ResetFromTransit(agent.UUID); - - // TODO: Check since what version this wasn't needed anymore. May be as old as 0.6 -/* - // Backwards compatibility. Best effort - if (version == 0f) - { - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); - Thread.Sleep(3000); // wait a little now that we're not waiting for the callback - CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); - } -*/ - // the user may change their profile information in other region, // so the userinfo in UserProfileCache is not reliable any more, delete it // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! @@ -2080,66 +2052,63 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.KnownRegions = seeds; sp.SetNeighbourRegionSizeInfo(neighbours); - AgentPosition agentpos = new AgentPosition(); - agentpos.AgentID = new UUID(sp.UUID.Guid); - agentpos.SessionID = spClient.SessionId; - agentpos.Size = sp.Appearance.AvatarSize; - agentpos.Center = sp.CameraPosition; - agentpos.Far = sp.DrawDistance; - agentpos.Position = sp.AbsolutePosition; - agentpos.Velocity = sp.Velocity; - agentpos.RegionHandle = currentRegionHandler; - agentpos.Throttles = spClient.GetThrottlesPacked(1); - // agentpos.ChildrenCapSeeds = seeds; - - Util.FireAndForget(delegate + if(newneighbours.Count > 0 || previousRegionNeighbourHandles.Count > 0) { - Thread.Sleep(200); // the original delay that was at InformClientOfNeighbourAsync start - int count = 0; + AgentPosition agentpos = new AgentPosition(); + agentpos.AgentID = new UUID(sp.UUID.Guid); + agentpos.SessionID = spClient.SessionId; + agentpos.Size = sp.Appearance.AvatarSize; + agentpos.Center = sp.CameraPosition; + agentpos.Far = sp.DrawDistance; + agentpos.Position = sp.AbsolutePosition; + agentpos.Velocity = sp.Velocity; + agentpos.RegionHandle = currentRegionHandler; + agentpos.Throttles = spClient.GetThrottlesPacked(1); + // agentpos.ChildrenCapSeeds = seeds; - foreach (GridRegion neighbour in neighbours) + Util.FireAndForget(delegate { - ulong handler = neighbour.RegionHandle; - try + Thread.Sleep(200); // the original delay that was at InformClientOfNeighbourAsync start + int count = 0; + + foreach (GridRegion neighbour in neighbours) { - if (newneighbours.Contains(handler)) + ulong handler = neighbour.RegionHandle; + try { - InformClientOfNeighbourAsync(sp, cagents[count], neighbour, - neighbour.ExternalEndPoint, true); - count++; + if (newneighbours.Contains(handler)) + { + InformClientOfNeighbourAsync(sp, cagents[count], neighbour, + neighbour.ExternalEndPoint, true); + count++; + } + else if (!previousRegionNeighbourHandles.Contains(handler)) + { + spScene.SimulationService.UpdateAgent(neighbour, agentpos); + } } - else if (!previousRegionNeighbourHandles.Contains(handler)) + catch (ArgumentOutOfRangeException) { - spScene.SimulationService.UpdateAgent(neighbour, agentpos); + m_log.ErrorFormat( + "[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbour list. The following region will not display to the client: {0} for region {1} ({2}, {3}).", + neighbour.ExternalHostName, + neighbour.RegionHandle, + neighbour.RegionLocX, + neighbour.RegionLocY); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ENTITY TRANSFER MODULE]: Could not resolve external hostname {0} for region {1} ({2}, {3}). {4}", + neighbour.ExternalHostName, + neighbour.RegionHandle, + neighbour.RegionLocX, + neighbour.RegionLocY, + e); } } - catch (ArgumentOutOfRangeException) - { - m_log.ErrorFormat( - "[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbour list. The following region will not display to the client: {0} for region {1} ({2}, {3}).", - neighbour.ExternalHostName, - neighbour.RegionHandle, - neighbour.RegionLocX, - neighbour.RegionLocY); - } - catch (Exception e) - { - m_log.ErrorFormat( - "[ENTITY TRANSFER MODULE]: Could not resolve external hostname {0} for region {1} ({2}, {3}). {4}", - neighbour.ExternalHostName, - neighbour.RegionHandle, - neighbour.RegionLocX, - neighbour.RegionLocY, - e); - - // FIXME: Okay, even though we've failed, we're still going to throw the exception on, - // since I don't know what will happen if we just let the client continue - - // XXX: Well, decided to swallow the exception instead for now. Let us see how that goes. - // throw e; - } - } - }); + }); + } } // Computes the difference between two region bases. @@ -2534,11 +2503,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (newRegionSizeY == 0) newRegionSizeY = Constants.RegionSize; - newpos.X = targetPosition.X - (neighbourRegion.RegionLocX - (int)scene.RegionInfo.WorldLocX); newpos.Y = targetPosition.Y - (neighbourRegion.RegionLocY - (int)scene.RegionInfo.WorldLocY); - const float enterDistance = 0.2f; newpos.X = Util.Clamp(newpos.X, enterDistance, newRegionSizeX - enterDistance); newpos.Y = Util.Clamp(newpos.Y, enterDistance, newRegionSizeY - enterDistance); @@ -2546,72 +2513,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return neighbourRegion; } -/* not in use. -> CrossPrimGroupIntoNewRegion - /// - /// Move the given scene object into a new region depending on which region its absolute position has moved - /// into. - /// - /// Using the objects new world location, ask the grid service for a the new region and adjust the prim - /// position to be relative to the new region. - /// - /// the scene object that we're crossing - /// the attempted out of region position of the scene object. This position is - /// relative to the region the object currently is in. - /// if 'true', the deletion of the client from the region is not broadcast to the clients - public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent) - { - if (grp == null) - return; - if (grp.IsDeleted) - return; - - Scene scene = grp.Scene; - if (scene == null) - return; - - // Remember the old group position in case the region lookup fails so position can be restored. - Vector3 oldGroupPosition = grp.RootPart.GroupPosition; - - // Compute the absolute position of the object. - double objectWorldLocX = (double)scene.RegionInfo.WorldLocX + attemptedPosition.X; - double objectWorldLocY = (double)scene.RegionInfo.WorldLocY + attemptedPosition.Y; - - // Ask the grid service for the region that contains the passed address - GridRegion destination = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, - objectWorldLocX, objectWorldLocY); - - Vector3 pos = Vector3.Zero; - if (destination != null) - { - // Adjust the object's relative position from the old region (attemptedPosition) - // to be relative to the new region (pos). - pos = new Vector3( (float)(objectWorldLocX - (double)destination.RegionLocX), - (float)(objectWorldLocY - (double)destination.RegionLocY), - attemptedPosition.Z); - } - - if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) - { - m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID); - - // We are going to move the object back to the old position so long as the old position - // is in the region - oldGroupPosition.X = Util.Clamp(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1)); - oldGroupPosition.Y = Util.Clamp(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1)); - oldGroupPosition.Z = Util.Clamp(oldGroupPosition.Z, 1.0f, Constants.RegionHeight); - - grp.AbsolutePosition = oldGroupPosition; - grp.Velocity = Vector3.Zero; - if (grp.RootPart.PhysActor != null) - grp.RootPart.PhysActor.CrossingFailure(); - - if (grp.RootPart.KeyframeMotion != null) - grp.RootPart.KeyframeMotion.CrossingFailure(); - - grp.ScheduleGroupForFullUpdate(); - } - } -*/ /// /// Move the given scene object into a new region /// diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 781b9ffcbd..8c560e57fa 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -867,6 +867,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess return null; } + if(rezAsset.Data == null || rezAsset.Data.Length == 0) + { + m_log.WarnFormat( + "[INVENTORY ACCESS MODULE]: missing data in asset {0} to RezObject()", + assetID, remoteClient.Name); + remoteClient.SendAgentAlertMessage(string.Format("Unable to rez: missing data in asset {0} ", assetID), false); + return null; + } + SceneObjectGroup group = null; List objlist; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs index 2238c9077f..98ccc955c9 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs @@ -63,18 +63,31 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser scene.EventManager.OnNewClient -= OnNewClient; } - public void OnMakeRootAgent(ScenePresence sp) - { - if (sp.PresenceType != PresenceType.Npc) + public void OnMakeRootAgent(ScenePresence sp) + { + if (sp.isNPC) + return; + + if(sp.gotCrossUpdate) { - string userid; - //m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected root presence {0} in {1}", userid, sp.Scene.RegionInfo.RegionName); - if (sp.Scene.UserManagementModule.GetUserUUI(sp.UUID, out userid)) + Util.FireAndForget(delegate { - /* we only setposition on known agents that have a valid lookup */ - m_GridUserService.SetLastPosition( - userid, UUID.Zero, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); - } + DoOnMakeRootAgent(sp); + }, null, "ActivityDetector_MakeRoot"); + } + else + DoOnMakeRootAgent(sp); + } + + public void DoOnMakeRootAgent(ScenePresence sp) + { + string userid; + //m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected root presence {0} in {1}", userid, sp.Scene.RegionInfo.RegionName); + if (sp.Scene.UserManagementModule.GetUserUUI(sp.UUID, out userid)) + { + /* we only setposition on known agents that have a valid lookup */ + m_GridUserService.SetLastPosition( + userid, UUID.Zero, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs index 50c252c817..117f02c1c2 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs @@ -68,6 +68,22 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence public void OnMakeRootAgent(ScenePresence sp) { + if (sp.isNPC) + return; + + if(sp.gotCrossUpdate) + { + Util.FireAndForget(delegate + { + DoOnMakeRootAgent(sp); + }, null, "PresenceDetector_MakeRoot"); + } + else + DoOnMakeRootAgent(sp); + } + + public void DoOnMakeRootAgent(ScenePresence sp) + { // m_log.DebugFormat("[PRESENCE DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName); if (sp.PresenceType != PresenceType.Npc) m_PresenceService.ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID); diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 95b576f9bd..4324ddc421 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -1289,35 +1289,34 @@ namespace OpenSim.Region.CoreModules.World.Land bool needOverlay = false; if (land.UpdateLandProperties(args, remote_client, out snap_selection, out needOverlay)) { - //the proprieties to who changed them - ScenePresence av = m_scene.GetScenePresence(remote_client.AgentId); - if(av.IsChildAgent || land != GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y)) - land.SendLandProperties(-10000, false, LandChannel.LAND_RESULT_SINGLE, remote_client); - else - land.SendLandProperties(0, false, LandChannel.LAND_RESULT_SINGLE, remote_client); - UUID parcelID = land.LandData.GlobalID; m_scene.ForEachScenePresence(delegate(ScenePresence avatar) - { - if (avatar.IsDeleted || avatar.isNPC) - return; + { + if (avatar.IsDeleted || avatar.isNPC) + return; - IClientAPI client = avatar.ControllingClient; - if (needOverlay) - SendParcelOverlay(client); + IClientAPI client = avatar.ControllingClient; + if (needOverlay) + SendParcelOverlay(client); - if (avatar.IsChildAgent) - return; + if (avatar.IsChildAgent) + { + if(client == remote_client) + land.SendLandProperties(-10000, false, LandChannel.LAND_RESULT_SINGLE, client); + return; + } - ILandObject aland = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); - if (aland != null) - { - if (client != remote_client && land == aland) + ILandObject aland = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); + if (aland != null) + { + if(client == remote_client && land != aland) + land.SendLandProperties(-10000, false, LandChannel.LAND_RESULT_SINGLE, client); + else if (land == aland) aland.SendLandProperties(0, false, LandChannel.LAND_RESULT_SINGLE, client); - } - if (avatar.currentParcelUUID == parcelID) - avatar.currentParcelUUID = parcelID; // force parcel flags review - }); + } + if (avatar.currentParcelUUID == parcelID) + avatar.currentParcelUUID = parcelID; // force parcel flags review + }); } } diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 4cea7bb209..b00f2b0de3 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -374,6 +374,10 @@ namespace OpenSim.Region.CoreModules.World.Land public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) { + remote_client.SceneAgent.Invulnerable = + !m_scene.RegionInfo.RegionSettings.AllowDamage || + (m_landData.Flags & (uint)ParcelFlags.AllowDamage) == 0; + if (remote_client.SceneAgent.PresenceType == PresenceType.Npc) return; diff --git a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs index 4361310f34..b52576984a 100644 --- a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs +++ b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs @@ -56,7 +56,7 @@ namespace OpenSim.Region.Framework.Interfaces uint timeStamp, bool offline, int parentEstateID, Vector3 position, uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket); void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat, - bool isModerator, bool textMute); + bool isModerator, bool textMute, bool isEnterorLeave); void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID); void GroupMembershipData(UUID receiverAgent, GroupMembershipData[] data); OSD ScriptRunningEvent(UUID objectID, UUID itemID, bool running, bool mono); diff --git a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs index 7e87006706..5c43b366cd 100644 --- a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs @@ -28,6 +28,7 @@ using System.Collections.Generic; using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; namespace OpenSim.Region.Framework.Interfaces @@ -93,6 +94,7 @@ namespace OpenSim.Region.Framework.Interfaces /// These come from the FriendRights enum. void GrantRights(IClientAPI remoteClient, UUID friendID, int perms); + void IsNpwRoot(ScenePresence sp); bool SendFriendsOnlineIfNeeded(IClientAPI client); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index d556fd18ed..efc1413a12 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -346,9 +346,6 @@ namespace OpenSim.Region.Framework.Scenes get { return RootPart.VolumeDetectActive; } } - private Vector3 lastPhysGroupPos; - private Quaternion lastPhysGroupRot; - /// /// Is this entity set to be saved in persistent storage? /// @@ -702,10 +699,23 @@ namespace OpenSim.Region.Framework.Scenes foreach (ScenePresence av in sog.m_sittingAvatars) { + byte cflags = 1; + avtocrossInfo avinfo = new avtocrossInfo(); SceneObjectPart parentPart = sogScene.GetSceneObjectPart(av.ParentID); if (parentPart != null) + { av.ParentUUID = parentPart.UUID; + if(parentPart.SitTargetAvatar == av.UUID) + cflags = 7; // low 3 bits set + else + cflags = 3; + } + + // 1 is crossing + // 2 is sitting + // 4 is sitting at sittarget + av.crossingFlags = cflags; avinfo.av = av; avinfo.ParentID = av.ParentID; @@ -750,7 +760,7 @@ namespace OpenSim.Region.Framework.Scenes av.ParentUUID = UUID.Zero; // In any case av.IsInTransit = false; - + av.crossingFlags = 0; m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", av.Firstname, av.Lastname); } else @@ -768,6 +778,7 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence av = avinfo.av; av.ParentUUID = UUID.Zero; av.ParentID = avinfo.ParentID; + av.crossingFlags = 0; } } avsToCross.Clear(); @@ -1228,13 +1239,6 @@ namespace OpenSim.Region.Framework.Scenes ApplyPhysics(); - if (RootPart.PhysActor != null) - RootPart.Force = RootPart.Force; - if (RootPart.PhysActor != null) - RootPart.Torque = RootPart.Torque; - if (RootPart.PhysActor != null) - RootPart.Buoyancy = RootPart.Buoyancy; - // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled // for the same object with very different properties. The caller must schedule the update. //ScheduleGroupForFullUpdate(); @@ -2166,10 +2170,9 @@ namespace OpenSim.Region.Framework.Scenes } // Hack to get the physics scene geometries in the right spot // ResetChildPrimPhysicsPositions(); + if (m_rootPart.PhysActor != null) - { m_rootPart.PhysActor.Building = false; - } } else { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a46232c69a..0b8076abdb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2213,7 +2213,7 @@ namespace OpenSim.Region.Framework.Scenes dupe.Shape.ExtraParams = extraP; dupe.m_sittingAvatars = new HashSet(); - + dupe.SitTargetAvatar = UUID.Zero; // safeguard actual copy is done in sog.copy dupe.KeyframeMotion = null; dupe.PayPrice = (int[])PayPrice.Clone(); @@ -4883,6 +4883,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter pa.GravModifier = GravityModifier; pa.Friction = Friction; pa.Restitution = Restitution; + pa.Buoyancy = Buoyancy; if(LocalId == ParentGroup.RootPart.LocalId) { @@ -4927,7 +4928,6 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter { Velocity = velocity; AngularVelocity = rotationalVelocity; - pa.RotationalVelocity = rotationalVelocity; // if not vehicle and root part apply force and torque if ((m_vehicleParams == null || m_vehicleParams.Type == Vehicle.TYPE_NONE)) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f20d06523a..3167282dd6 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -277,6 +277,7 @@ namespace OpenSim.Region.Framework.Scenes private Quaternion m_lastRotation; private Vector3 m_lastVelocity; private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f); + private bool SentInitialData = false; private bool m_followCamAuto = false; @@ -342,8 +343,10 @@ namespace OpenSim.Region.Framework.Scenes private const float FLY_ROLL_RESET_RADIANS_PER_UPDATE = 0.02f; private float m_health = 100f; + private float m_healRate = 1f; + private float m_healRatePerFrame = 0.05f; - protected ulong crossingFromRegion; +// protected ulong crossingFromRegion; private readonly Vector3[] Dir_Vectors = new Vector3[12]; @@ -565,19 +568,17 @@ namespace OpenSim.Region.Framework.Scenes public string Firstname { get; private set; } public string Lastname { get; private set; } + public bool haveGroupInformation; + public bool gotCrossUpdate; + public byte crossingFlags; + public string Grouptitle { - get { return UseFakeGroupTitle ? "(Loading)" : m_groupTitle; } + get { return m_groupTitle; } set { m_groupTitle = value; } } private string m_groupTitle; - /// - /// When this is 'true', return a dummy group title instead of the real group title. This is - /// used as part of a hack to force viewers to update the displayed avatar name. - /// - public bool UseFakeGroupTitle { get; set; } - // Agent's Draw distance. private float m_drawDistance = 255f; public float DrawDistance @@ -860,6 +861,26 @@ namespace OpenSim.Region.Framework.Scenes set { m_health = value; } } + public float HealRate + { + get { return m_healRate; } + set + { + if(value > 100.0f) + m_healRate = 100.0f; + else if (value <= 0.0) + m_healRate = 0.0f; + else + m_healRate = value; + + if(Scene != null) + m_healRatePerFrame = m_healRate * Scene.FrameTime; + else + m_healRatePerFrame = 0.05f; + } + } + + /// /// Gets the world rotation of this presence. /// @@ -1039,9 +1060,9 @@ namespace OpenSim.Region.Framework.Scenes if (account != null) UserLevel = account.UserLevel; - IGroupsModule gm = m_scene.RequestModuleInterface(); - if (gm != null) - Grouptitle = gm.GetGroupTitle(m_uuid); + // IGroupsModule gm = m_scene.RequestModuleInterface(); + // if (gm != null) + // Grouptitle = gm.GetGroupTitle(m_uuid); m_scriptEngines = m_scene.RequestModuleInterfaces(); @@ -1063,6 +1084,8 @@ namespace OpenSim.Region.Framework.Scenes m_stateMachine = new ScenePresenceStateMachine(this); + HealRate = 0.5f; + IConfig sconfig = m_scene.Config.Configs["EntityTransfer"]; if (sconfig != null) { @@ -1073,6 +1096,8 @@ namespace OpenSim.Region.Framework.Scenes } + private float lastHealthSent = 0; + private void RegionHeartbeatEnd(Scene scene) { if (IsChildAgent) @@ -1095,7 +1120,24 @@ namespace OpenSim.Region.Framework.Scenes } else { - m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd; +// m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd; + } + } + + if(m_healRatePerFrame != 0f && Health != 100.0f) + { + float last = Health; + Health += m_healRatePerFrame; + if(Health > 100.0f) + { + Health = 100.0f; + lastHealthSent = Health; + ControllingClient.SendHealth(Health); + } + else if(Math.Abs(Health - lastHealthSent) > 1.0) + { + lastHealthSent = Health; + ControllingClient.SendHealth(Health); } } } @@ -1190,8 +1232,10 @@ namespace OpenSim.Region.Framework.Scenes else { part.AddSittingAvatar(this); - if (part.SitTargetPosition != Vector3.Zero) - part.SitTargetAvatar = UUID; + // if not actually on the target invalidate it + if(gotCrossUpdate && (crossingFlags & 0x04) == 0) + part.SitTargetAvatar = UUID.Zero; + ParentID = part.LocalId; ParentPart = part; m_pos = PrevSitOffset; @@ -1214,11 +1258,6 @@ namespace OpenSim.Region.Framework.Scenes // Should not be needed if we are not trying to tell this region to close // DoNotCloseAfterTeleport = false; - IGroupsModule gm = m_scene.RequestModuleInterface(); - if (gm != null) - Grouptitle = gm.GetGroupTitle(m_uuid); - - m_log.DebugFormat("[MakeRootAgent] Grouptitle: {0}ms", Util.EnvironmentTickCountSubtract(ts)); RegionHandle = m_scene.RegionInfo.RegionHandle; @@ -1467,6 +1506,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void MakeChildAgent(ulong newRegionHandle) { + haveGroupInformation = false; + gotCrossUpdate = false; + crossingFlags = 0; m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd; RegionHandle = newRegionHandle; @@ -1934,25 +1976,29 @@ namespace OpenSim.Region.Framework.Scenes m_log.DebugFormat("[CompleteMovement] MakeRootAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); - -// start sending terrain patchs - if (!isNPC) - Scene.SendLayerData(ControllingClient); - - if (!IsChildAgent && !isNPC) + if(!haveGroupInformation && !IsChildAgent && !isNPC) { + // oh crap.. lets retry it directly + IGroupsModule gm = m_scene.RequestModuleInterface(); + if (gm != null) + Grouptitle = gm.GetGroupTitle(m_uuid); + + m_log.DebugFormat("[CompleteMovement] Missing Grouptitle: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + InventoryFolderBase cof = m_scene.InventoryService.GetFolderForType(client.AgentId, (FolderType)46); if (cof == null) COF = UUID.Zero; else COF = cof.ID; - m_log.DebugFormat("[ScenePresence]: CompleteMovement COF for {0} is {1}", client.AgentId, COF); + m_log.DebugFormat("[CompleteMovement]: Missing COF for {0} is {1}", client.AgentId, COF); } + // Tell the client that we're totally ready ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); + m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts)); if (!string.IsNullOrEmpty(m_callbackURI)) @@ -1985,6 +2031,10 @@ namespace OpenSim.Region.Framework.Scenes m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); +// start sending terrain patchs + if (!gotCrossUpdate && !isNPC) + Scene.SendLayerData(ControllingClient); + m_previusParcelHide = false; m_previusParcelUUID = UUID.Zero; m_currentParcelHide = false; @@ -2143,8 +2193,12 @@ namespace OpenSim.Region.Framework.Scenes { IFriendsModule friendsModule = m_scene.RequestModuleInterface(); if (friendsModule != null) - friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); - + { + if(gotCrossUpdate) + friendsModule.IsNpwRoot(this); + else + friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); + } m_log.DebugFormat("[CompleteMovement] friendsModule: {0}ms", Util.EnvironmentTickCountSubtract(ts)); } @@ -2160,6 +2214,10 @@ namespace OpenSim.Region.Framework.Scenes // m_currentParcelHide = newhide; // } + haveGroupInformation = true; + gotCrossUpdate = false; + crossingFlags = 0; + m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd; m_log.DebugFormat("[CompleteMovement] end: {0}ms", Util.EnvironmentTickCountSubtract(ts)); @@ -3114,6 +3172,7 @@ namespace OpenSim.Region.Framework.Scenes ResetMoveToTarget(); Velocity = Vector3.Zero; + m_AngularVelocity = Vector3.Zero; part.AddSittingAvatar(this); @@ -3439,9 +3498,10 @@ namespace OpenSim.Region.Framework.Scenes part.AddSittingAvatar(this); ParentPart = part; ParentID = m_requestedSitTargetID; + + RemoveFromPhysicalScene(); m_AngularVelocity = Vector3.Zero; Velocity = Vector3.Zero; - RemoveFromPhysicalScene(); m_requestedSitTargetID = 0; @@ -3464,13 +3524,15 @@ namespace OpenSim.Region.Framework.Scenes return; // m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.. - m_AngularVelocity = Vector3.Zero; sitAnimation = "SIT_GROUND_CONSTRAINED"; // Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); // TriggerScenePresenceUpdated(); SitGround = true; RemoveFromPhysicalScene(); + m_AngularVelocity = Vector3.Zero; + Velocity = Vector3.Zero; + Animator.SetMovementAnimations("SITGROUND"); TriggerScenePresenceUpdated(); } @@ -3758,6 +3820,7 @@ namespace OpenSim.Region.Framework.Scenes public void SendInitialDataToMe() { // Send all scene object to the new client + SentInitialData = true; Util.FireAndForget(delegate { // we created a new ScenePresence (a new child agent) in a fresh region. @@ -3993,6 +4056,12 @@ namespace OpenSim.Region.Framework.Scenes if(IsDeleted || !ControllingClient.IsActive) return; + if(!SentInitialData) + { + SendInitialDataToMe(); + return; + } + if(m_reprioritizationBusy) return; @@ -4142,19 +4211,21 @@ namespace OpenSim.Region.Framework.Scenes { // we don't have entity transfer module Vector3 pos = AbsolutePosition; + vel = Velocity; float px = pos.X; if (px < 0) - pos.X += Velocity.X * 2; + pos.X += vel.X * 2; else if (px > m_scene.RegionInfo.RegionSizeX) - pos.X -= Velocity.X * 2; + pos.X -= vel.X * 2; float py = pos.Y; if (py < 0) - pos.Y += Velocity.Y * 2; + pos.Y += vel.Y * 2; else if (py > m_scene.RegionInfo.RegionSizeY) - pos.Y -= Velocity.Y * 2; + pos.Y -= vel.Y * 2; Velocity = Vector3.Zero; + m_AngularVelocity = Vector3.Zero; AbsolutePosition = pos; } } @@ -4167,19 +4238,21 @@ namespace OpenSim.Region.Framework.Scenes RemoveFromPhysicalScene(); Vector3 pos = AbsolutePosition; + Vector3 vel = Velocity; float px = pos.X; if (px < 0) - pos.X += Velocity.X * 2; + pos.X += vel.X * 2; else if (px > m_scene.RegionInfo.RegionSizeX) - pos.X -= Velocity.X * 2; + pos.X -= vel.X * 2; float py = pos.Y; if (py < 0) - pos.Y += Velocity.Y * 2; + pos.Y += vel.Y * 2; else if (py > m_scene.RegionInfo.RegionSizeY) - pos.Y -= Velocity.Y * 2; + pos.Y -= vel.Y * 2; Velocity = Vector3.Zero; + m_AngularVelocity = Vector3.Zero; AbsolutePosition = pos; AddToPhysicalScene(isFlying); @@ -4419,7 +4492,7 @@ namespace OpenSim.Region.Framework.Scenes checkRePrioritization(); } - public void CopyTo(AgentData cAgent) + public void CopyTo(AgentData cAgent, bool isCrossUpdate) { cAgent.CallbackURI = m_callbackURI; @@ -4483,6 +4556,28 @@ namespace OpenSim.Region.Framework.Scenes if (Scene.AttachmentsModule != null) Scene.AttachmentsModule.CopyAttachments(this, cAgent); + + cAgent.CrossingFlags = isCrossUpdate ? crossingFlags : (byte)0; + + if(isCrossUpdate && haveGroupInformation) + { + cAgent.agentCOF = COF; + cAgent.ActiveGroupID = ControllingClient.ActiveGroupId; + cAgent.ActiveGroupName = ControllingClient.ActiveGroupName; + cAgent.ActiveGroupTitle = Grouptitle; + Dictionary gpowers = ControllingClient.GetGroupPowers(); + if(gpowers.Count >0) + { + cAgent.Groups = new AgentGroupData[gpowers.Count]; + int i = 0; + foreach (UUID gid in gpowers.Keys) + { + // WARNING we dont' have AcceptNotices in cache.. sending as true mb no one notices ;) + AgentGroupData agd = new AgentGroupData(gid,gpowers[gid],true); + cAgent.Groups[i++] = agd; + } + } + } } private void CopyFrom(AgentData cAgent) @@ -4578,6 +4673,45 @@ namespace OpenSim.Region.Framework.Scenes if (Scene.AttachmentsModule != null) Scene.AttachmentsModule.CopyAttachments(cAgent, this); + haveGroupInformation = false; + + // using this as protocol detection don't want to mess with the numbers for now + if(cAgent.ActiveGroupTitle != null) + { + COF = cAgent.agentCOF; + ControllingClient.ActiveGroupId = cAgent.ActiveGroupID; + ControllingClient.ActiveGroupName = cAgent.ActiveGroupName; + ControllingClient.ActiveGroupPowers = 0; + Grouptitle = cAgent.ActiveGroupTitle; + int ngroups = cAgent.Groups.Length; + if(ngroups > 0) + { + Dictionary gpowers = new Dictionary(ngroups); + for(int i = 0 ; i < ngroups; i++) + { + AgentGroupData agd = cAgent.Groups[i]; + gpowers[agd.GroupID] = agd.GroupPowers; + } + + ControllingClient.SetGroupPowers(gpowers); + + if(cAgent.ActiveGroupID == UUID.Zero) + haveGroupInformation = true; + else if(gpowers.ContainsKey(cAgent.ActiveGroupID)) + { + ControllingClient.ActiveGroupPowers = gpowers[cAgent.ActiveGroupID]; + haveGroupInformation = true; + } + } + else if(cAgent.ActiveGroupID == UUID.Zero) + { + haveGroupInformation = true; + } + } + + crossingFlags = cAgent.CrossingFlags; + gotCrossUpdate = (crossingFlags != 0); + lock (m_originRegionIDAccessLock) m_originRegionID = cAgent.RegionID; } @@ -4585,7 +4719,7 @@ namespace OpenSim.Region.Framework.Scenes public bool CopyAgent(out IAgentData agent) { agent = new CompleteAgentData(); - CopyTo((AgentData)agent); + CopyTo((AgentData)agent, false); return true; } @@ -4667,18 +4801,19 @@ namespace OpenSim.Region.Framework.Scenes /// public void PhysicsCollisionUpdate(EventArgs e) { - if (IsChildAgent || Animator == null) + if (IsChildAgent) return; if(IsInTransit) return; + //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( // as of this comment the interval is set in AddToPhysicalScene // if (m_updateCount > 0) // { - if (Animator.UpdateMovementAnimations()) + if (Animator != null && Animator.UpdateMovementAnimations()) TriggerScenePresenceUpdated(); // m_updateCount--; // } @@ -4686,7 +4821,6 @@ namespace OpenSim.Region.Framework.Scenes CollisionEventUpdate collisionData = (CollisionEventUpdate)e; Dictionary coldata = collisionData.m_objCollisionList; - // // No collisions at all means we may be flying. Update always // // to make falling work // if (m_lastColCount != coldata.Count || coldata.Count == 0) @@ -4697,42 +4831,24 @@ namespace OpenSim.Region.Framework.Scenes if (coldata.Count != 0) { -/* - switch (Animator.CurrentMovementAnimation) + ContactPoint lowest; + lowest.SurfaceNormal = Vector3.Zero; + lowest.Position = Vector3.Zero; + lowest.Position.Z = float.MaxValue; + + foreach (ContactPoint contact in coldata.Values) { - case "STAND": - case "WALK": - case "RUN": - case "CROUCH": - case "CROUCHWALK": - { - */ - ContactPoint lowest; - lowest.SurfaceNormal = Vector3.Zero; - lowest.Position = Vector3.Zero; - lowest.Position.Z = float.MaxValue; - - foreach (ContactPoint contact in coldata.Values) - { - - if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z) - { - lowest = contact; - } - } - - if (lowest.Position.Z != float.MaxValue) - { - lowest.SurfaceNormal = -lowest.SurfaceNormal; - CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); - } - else - CollisionPlane = Vector4.UnitW; -/* - } - break; + if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z) + lowest = contact; } -*/ + + if (lowest.Position.Z != float.MaxValue) + { + lowest.SurfaceNormal = -lowest.SurfaceNormal; + CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); + } + else + CollisionPlane = Vector4.UnitW; } else CollisionPlane = Vector4.UnitW; @@ -4745,73 +4861,66 @@ namespace OpenSim.Region.Framework.Scenes // The following may be better in the ICombatModule // probably tweaking of the values for ground and normal prim collisions will be needed - float starthealth = Health; - uint killerObj = 0; - SceneObjectPart part = null; - foreach (uint localid in coldata.Keys) + float startHealth = Health; + if(coldata.Count > 0) { - if (localid == 0) + uint killerObj = 0; + SceneObjectPart part = null; + float rvel; // relative velocity, negative on approch + foreach (uint localid in coldata.Keys) { - part = null; - } - else - { - part = Scene.GetSceneObjectPart(localid); - } - if (part != null) - { - // Ignore if it has been deleted or volume detect - if (!part.ParentGroup.IsDeleted && !part.ParentGroup.IsVolumeDetect) + if (localid == 0) { - if (part.ParentGroup.Damage > 0.0f) + // 0 is the ground + rvel = coldata[0].RelativeSpeed; + if(rvel < -5.0f) + Health -= 0.01f * rvel * rvel; + } + else + { + part = Scene.GetSceneObjectPart(localid); + + if(part != null && !part.ParentGroup.IsVolumeDetect) { - // Something with damage... - Health -= part.ParentGroup.Damage; - part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false); + if (part.ParentGroup.Damage > 0.0f) + { + // Something with damage... + Health -= part.ParentGroup.Damage; + part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false); + } + else + { + // An ordinary prim + rvel = coldata[localid].RelativeSpeed; + if(rvel < -5.0f) + { + Health -= 0.005f * rvel * rvel; + } + } } else { - // An ordinary prim - if (coldata[localid].PenetrationDepth >= 0.10f) - Health -= coldata[localid].PenetrationDepth * 5.0f; + } } - } - else - { - // 0 is the ground - // what about collisions with other avatars? - if (localid == 0 && coldata[localid].PenetrationDepth >= 0.10f) - Health -= coldata[localid].PenetrationDepth * 5.0f; + + if (Health <= 0.0f) + { + if (localid != 0) + killerObj = localid; + } } - - if (Health <= 0.0f) - { - if (localid != 0) - killerObj = localid; - } - //m_log.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString()); - } - //Health = 100; - if (!Invulnerable) - { - if (starthealth != Health) - { - ControllingClient.SendHealth(Health); - } if (Health <= 0) { - m_scene.EventManager.TriggerAvatarKill(killerObj, this); - } - if (starthealth == Health && Health < 100.0f) - { - Health += 0.03f; - if (Health > 100.0f) - Health = 100.0f; ControllingClient.SendHealth(Health); + m_scene.EventManager.TriggerAvatarKill(killerObj, this); + return; } } + + if(Math.Abs(Health - startHealth) > 1.0) + ControllingClient.SendHealth(Health); } public void setHealthWithUpdate(float health) diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index f34dbe8b0c..50be3aced7 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -570,18 +570,28 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public UUID ActiveGroupId { get { return UUID.Zero; } + set {} } public string ActiveGroupName { get { return "IRCd User"; } + set {} } public ulong ActiveGroupPowers { get { return 0; } + set {} } + public Dictionary GetGroupPowers() + { + return new Dictionary(); + } + + public void SetGroupPowers(Dictionary powers) { } + public ulong GetGroupPowers(UUID groupID) { return 0; diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index e1b6abb3ae..0aaf95c78c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -296,15 +296,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups attemptDeliveryUuidSet = new HashSet(Array.ConvertAll(onlineAgents, pi => pi.UserID)); - - //Array.ForEach(onlineAgents, pi => attemptDeliveryUuidSet.Add(pi.UserID)); - - //groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList(); - - // if (m_debugEnabled) -// m_log.DebugFormat( -// "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members, {2} online", -// groupID, groupMembersCount, groupMembers.Count()); } else { @@ -387,7 +378,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups member.AgentID, Environment.TickCount - startTick); } } - else + else if(im.dialog != (byte)InstantMessageDialog.SessionAdd && + im.dialog != (byte)InstantMessageDialog.SessionDrop) { int startTick = Environment.TickCount; @@ -443,21 +435,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { IClientAPI client = null; - if (msg.dialog == (byte)InstantMessageDialog.SessionSend) + client = GetActiveClient(new UUID(msg.toAgentID)); + + if (client == null) { - client = GetActiveClient(new UUID(msg.toAgentID)); + m_log.WarnFormat("[GROUPS-MESSAGING]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID); - if (client != null) - { - if (m_debugEnabled) - m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} locally", client.Name); - } - else - { - m_log.WarnFormat("[GROUPS-MESSAGING]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID); - - return; - } + return; } ProcessMessageFromGroupSession(msg, client); @@ -471,78 +455,96 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups "[GROUPS-MESSAGING]: Session message from {0} going to agent {1}, sessionID {2}, type {3}", msg.fromAgentName, msg.toAgentID, msg.imSessionID, (InstantMessageDialog)msg.dialog); - UUID AgentID = new UUID(msg.fromAgentID); + UUID fromAgentID = new UUID(msg.fromAgentID); UUID GroupID = new UUID(msg.imSessionID); + IEventQueue eq = client.Scene.RequestModuleInterface(); switch (msg.dialog) { case (byte)InstantMessageDialog.SessionAdd: - m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); + m_groupData.AgentInvitedToGroupChatSession(fromAgentID, GroupID); + if(eq != null) + eq.ChatterBoxSessionAgentListUpdates( + GroupID + , fromAgentID + , client.AgentId + , false //canVoiceChat + , false //isModerator + , false //text mute + , true // enter + ); break; case (byte)InstantMessageDialog.SessionDrop: - m_groupData.AgentDroppedFromGroupChatSession(AgentID, GroupID); - break; - - case (byte)InstantMessageDialog.SessionSend: - if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID) - && !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID, GroupID) - ) - { - // Agent not in session and hasn't dropped from session - // Add them to the session for now, and Invite them - m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); - - GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); - if (groupInfo != null) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); - - // Force? open the group session dialog??? - // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); - IEventQueue eq = client.Scene.RequestModuleInterface(); - eq.ChatterboxInvitation( + m_groupData.AgentDroppedFromGroupChatSession(fromAgentID, GroupID); + if(eq != null) + eq.ChatterBoxSessionAgentListUpdates( GroupID - , groupInfo.GroupName - , new UUID(msg.fromAgentID) - , msg.message - , new UUID(msg.toAgentID) - , msg.fromAgentName - , msg.dialog - , msg.timestamp - , msg.offline == 1 - , (int)msg.ParentEstateID - , msg.Position - , 1 - , new UUID(msg.imSessionID) - , msg.fromGroup - , Utils.StringToBytes(groupInfo.GroupName) - ); - - eq.ChatterBoxSessionAgentListUpdates( - new UUID(GroupID) - , new UUID(msg.fromAgentID) - , new UUID(msg.toAgentID) + , fromAgentID + , client.AgentId , false //canVoiceChat , false //isModerator , false //text mute + , false // leave ); + break; + + case (byte)InstantMessageDialog.SessionSend: + if (!m_groupData.hasAgentDroppedGroupChatSession(client.AgentId, GroupID)) + { + if(!m_groupData.hasAgentBeenInvitedToGroupChatSession(client.AgentId, GroupID)) + { + + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); + if (groupInfo != null) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); + + if(eq != null) + { + eq.ChatterboxInvitation( + GroupID + , groupInfo.GroupName + , fromAgentID + , msg.message + , client.AgentId + , msg.fromAgentName + , msg.dialog + , msg.timestamp + , msg.offline == 1 + , (int)msg.ParentEstateID + , msg.Position + , 1 + , new UUID(msg.imSessionID) + , msg.fromGroup + , Utils.StringToBytes(groupInfo.GroupName) + ); + } + } + } + else + { + client.SendInstantMessage(msg); } - break; +// if (!m_groupData.hasAgentBeenInvitedToGroupChatSession(fromAgentID, GroupID)) + { + m_groupData.AgentInvitedToGroupChatSession(fromAgentID, GroupID); + eq.ChatterBoxSessionAgentListUpdates( + GroupID + , fromAgentID + , client.AgentId + , false //canVoiceChat + , false //isModerator + , false //text mute + , true // enter + ); + } } - else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID)) - { - // User hasn't dropped, so they're in the session, - // maybe we should deliver it. - client.SendInstantMessage(msg); - } - break; default: client.SendInstantMessage(msg); - break;; } } @@ -559,14 +561,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups DebugGridInstantMessage(im); } + UUID GroupID = new UUID(im.imSessionID); + UUID AgentID = new UUID(im.fromAgentID); + // Start group IM session if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID); - UUID GroupID = new UUID(im.imSessionID); - UUID AgentID = new UUID(im.fromAgentID); - GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); if (groupInfo != null) @@ -575,24 +577,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); - IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); - queue.ChatterBoxSessionAgentListUpdates( - GroupID - , AgentID - , new UUID(im.toAgentID) - , false //canVoiceChat - , false //isModerator - , false //text mute - ); + // we need to send here a list of known participants. + im.dialog = (byte)InstantMessageDialog.SessionAdd; + SendMessageToGroup(im, GroupID); } } // Send a message from locally connected client to a group if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) { - UUID GroupID = new UUID(im.imSessionID); - UUID AgentID = new UUID(im.fromAgentID); - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); @@ -601,6 +594,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SendMessageToGroup(im, GroupID); } + + if ((im.dialog == (byte)InstantMessageDialog.SessionDrop)) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); + + m_groupData.AgentDroppedFromGroupChatSession(AgentID, GroupID); + + SendMessageToGroup(im, GroupID); + } } #endregion diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index ddeac6689a..5205eae72c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -278,7 +278,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // There might be some problem with the thread we're generating this on but not // doing the update at this time causes problems (Mantis #7920 and #7915) // TODO: move sending this update to a later time in the rootification of the client. - SendAgentGroupDataUpdate(sp.ControllingClient, false); + if(!sp.haveGroupInformation) + SendAgentGroupDataUpdate(sp.ControllingClient, false); } private void OnMakeChild(ScenePresence sp) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 2dda3a18bc..83f08e0e4b 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -803,11 +803,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) { + if (m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID)) + m_groupsAgentsInvitedToChatSession[groupID].Remove(agentID); + // If not in dropped list, add if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) - { m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID); - } } } @@ -818,10 +819,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // If nessesary, remove from dropped list if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) - { m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID); - } - } + + if (!m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID)) + m_groupsAgentsInvitedToChatSession[groupID].Add(agentID); + } private void CreateGroupChatSessionTracking(UUID groupID) { diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index bdac6aa6a1..4275192a33 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -591,11 +591,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC public string ActiveGroupName { get { return String.Empty; } + set { } } public ulong ActiveGroupPowers { get { return 0; } + set { } } public bool IsGroupMember(UUID groupID) @@ -603,6 +605,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC return (m_hostGroupID == groupID); } + public Dictionary GetGroupPowers() + { + return new Dictionary(); + } + + public void SetGroupPowers(Dictionary powers) { } + public ulong GetGroupPowers(UUID groupID) { return 0; diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs index a70d1b80da..bb21f0cf78 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs @@ -508,7 +508,7 @@ public abstract class BSPhysObject : PhysicsActor relvel = RawVelocity; if (collidee != null && collidee.IsPhysical) relvel -= collidee.RawVelocity; - newContact.RelativeSpeed = OMV.Vector3.Dot(relvel, contactNormal); + newContact.RelativeSpeed = -OMV.Vector3.Dot(relvel, contactNormal); // DetailLog("{0},{1}.Collision.AddCollider,vel={2},contee.vel={3},relvel={4},relspeed={5}", // LocalID, TypeName, RawVelocity, (collidee == null ? OMV.Vector3.Zero : collidee.RawVelocity), relvel, newContact.RelativeSpeed); diff --git a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs index 393afaeabd..04ccbf03ed 100644 --- a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs +++ b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs @@ -126,9 +126,20 @@ namespace OpenSim.Region.PhysicsModules.SharedBase m_objCollisionList.Add(localID, contact); } else - { + { + float lastVel = m_objCollisionList[localID].RelativeSpeed; if (m_objCollisionList[localID].PenetrationDepth < contact.PenetrationDepth) + { + if(Math.Abs(lastVel) > Math.Abs(contact.RelativeSpeed)) + contact.RelativeSpeed = lastVel; m_objCollisionList[localID] = contact; + } + else if(Math.Abs(lastVel) < Math.Abs(contact.RelativeSpeed)) + { + ContactPoint tmp = m_objCollisionList[localID]; + tmp.RelativeSpeed = contact.RelativeSpeed; + m_objCollisionList[localID] = tmp; + } } } @@ -385,6 +396,7 @@ namespace OpenSim.Region.PhysicsModules.SharedBase } public abstract Vector3 Velocity { get; set; } + public virtual Vector3 rootVelocity { get { return Vector3.Zero; } } public abstract Vector3 Torque { get; set; } public abstract float CollisionScore { get; set;} diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs b/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs index 55619c00f6..7d855f1ce2 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs @@ -80,6 +80,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde private Vector3 m_rotationalVelocity; private Vector3 m_size; private Vector3 m_collideNormal; + private Vector3 m_lastFallVel; private Quaternion m_orientation; private Quaternion m_orientation2D; private float m_mass = 80f; @@ -109,6 +110,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde private bool m_alwaysRun = false; private bool _zeroFlag = false; + private bool m_haveLastFallVel = false; private uint m_localID = 0; @@ -605,6 +607,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde set { return; } } + public override Vector3 rootVelocity + { + get + { + return _velocity; + } + } + public override Vector3 Velocity { get @@ -1086,6 +1096,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (ctz.Z < 0) ctz.Z = 0; + if(!m_haveLastFallVel) + { + m_lastFallVel = vel; + m_haveLastFallVel = true; + } + Vector3 n = _parent_scene.GetTerrainNormalAtXY(posch.X, posch.Y); float depth = terrainheight - chrminZ; @@ -1114,7 +1130,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_iscollidingGround = true; - ContactPoint contact = new ContactPoint(); contact.PenetrationDepth = depth; contact.Position.X = localpos.X; @@ -1123,9 +1138,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde contact.SurfaceNormal.X = -n.X; contact.SurfaceNormal.Y = -n.Y; contact.SurfaceNormal.Z = -n.Z; - contact.RelativeSpeed = -vel.Z; + contact.RelativeSpeed = Vector3.Dot(m_lastFallVel, n); contact.CharacterFeet = true; AddCollisionEvent(0, contact); + m_lastFallVel = vel; // vec.Z *= 0.5f; } @@ -1143,6 +1159,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde } else { + m_haveLastFallVel = false; m_colliderGroundfilter -= 5; if (m_colliderGroundfilter <= 0) { diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs index 6ed42d927f..aaa2203a70 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs @@ -542,6 +542,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde } } + public override Vector3 rootVelocity + { + get + { + if(_parent != null) + return ((OdePrim)_parent).Velocity; + return Velocity; + } + } + public override Vector3 Velocity { get @@ -560,7 +570,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde { m_log.WarnFormat("[PHYSICS]: Got NaN Velocity in Object {0}", Name); } - } } diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs index e0644e38ea..8d87c30299 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs @@ -874,7 +874,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde break; case (int)ActorTypes.Prim: - Vector3 relV = p1.Velocity - p2.Velocity; + Vector3 relV = p1.rootVelocity - p2.rootVelocity; float relVlenSQ = relV.LengthSquared(); if (relVlenSQ > 0.0001f) { @@ -899,7 +899,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde bounce = contactdata1.bounce * TerrainBounce; mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); - if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f) + Vector3 v1 = p1.rootVelocity; + if (Math.Abs(v1.X) > 0.1f || Math.Abs(v1.Y) > 0.1f) mu *= frictionMovementMult; p1.CollidingGround = true; @@ -925,8 +926,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde // if (curContact.side1 > 0) // should be 2 ? // IgnoreNegSides = true; - - if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f) + Vector3 v2 = p2.rootVelocity; + if (Math.Abs(v2.X) > 0.1f || Math.Abs(v2.Y) > 0.1f) mu *= frictionMovementMult; if(d.GeomGetClass(g2) == d.GeomClassID.TriMeshClass) @@ -980,7 +981,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde p1.CollidingObj = true; p2.CollidingObj = true; } - else if (p2.Velocity.LengthSquared() > 0.0f) + else if (p2.rootVelocity.LengthSquared() > 0.0f) p2.CollidingObj = true; } else @@ -995,7 +996,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde p1.CollidingObj = true; p2.CollidingObj = true; } - else if (p2.Velocity.LengthSquared() > 0.0f) + else if (p1.rootVelocity.LengthSquared() > 0.0f) p1.CollidingObj = true; } else @@ -1068,10 +1069,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde Vector3 vel = Vector3.Zero; if (p2 != null && p2.IsPhysical) - vel = p2.Velocity; + vel = p2.rootVelocity; if (p1 != null && p1.IsPhysical) - vel -= p1.Velocity; + vel -= p1.rootVelocity; contact.RelativeSpeed = Vector3.Dot(vel, contact.SurfaceNormal); @@ -1079,44 +1080,45 @@ namespace OpenSim.Region.PhysicsModule.ubOde { case ActorTypes.Agent: case ActorTypes.Prim: + { + switch ((ActorTypes)p2.PhysicsActorType) { - switch ((ActorTypes)p2.PhysicsActorType) - { - case ActorTypes.Agent: - case ActorTypes.Prim: - if (p2events) - { - AddCollisionEventReporting(p2); - p2.AddCollisionEvent(p1.ParentActor.LocalID, contact); - } - obj2LocalID = p2.ParentActor.LocalID; - break; + case ActorTypes.Agent: + case ActorTypes.Prim: + if (p2events) + { + AddCollisionEventReporting(p2); + p2.AddCollisionEvent(p1.ParentActor.LocalID, contact); + } + obj2LocalID = p2.ParentActor.LocalID; + break; - case ActorTypes.Ground: - case ActorTypes.Unknown: - default: - obj2LocalID = 0; - break; - } - if (p1events) - { - contact.SurfaceNormal = -contact.SurfaceNormal; - AddCollisionEventReporting(p1); - p1.AddCollisionEvent(obj2LocalID, contact); - } - break; + case ActorTypes.Ground: + case ActorTypes.Unknown: + default: + obj2LocalID = 0; + break; } + if (p1events) + { + contact.SurfaceNormal = -contact.SurfaceNormal; + contact.RelativeSpeed = -contact.RelativeSpeed; + AddCollisionEventReporting(p1); + p1.AddCollisionEvent(obj2LocalID, contact); + } + break; + } case ActorTypes.Ground: case ActorTypes.Unknown: default: + { + if (p2events && !p2.IsVolumeDtc) { - if (p2events && !p2.IsVolumeDtc) - { - AddCollisionEventReporting(p2); - p2.AddCollisionEvent(0, contact); - } - break; + AddCollisionEventReporting(p2); + p2.AddCollisionEvent(0, contact); } + break; + } } } @@ -1722,8 +1724,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde case ActorTypes.Prim: OdePrim pobj = (OdePrim)obj; - if (pobj.Body == IntPtr.Zero || (d.BodyIsEnabled(pobj.Body) && !pobj.m_outbounds)) - if (!pobj.m_outbounds) + if (!pobj.m_outbounds && (pobj.Body == IntPtr.Zero || d.BodyIsEnabled(pobj.Body))) { pobj.AddCollisionFrameTime((int)(odetimestepMS)); pobj.SendCollisions(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 064eb0a993..6d2e2c8b94 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -15678,6 +15678,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api try { + if (amount <= 0) + { + replydata = "INVALID_AMOUNT"; + return; + } + TaskInventoryItem item = m_item; if (item == null) { @@ -15685,6 +15691,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } + if (m_host.OwnerID == m_host.GroupID) + { + replydata = "GROUP_OWNED"; + return; + } + m_host.AddScriptLPS(1); if (item.PermsGranter == UUID.Zero) @@ -15707,6 +15719,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } + UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, toID); + if (account == null) + { + replydata = "LINDENDOLLAR_ENTITYDOESNOTEXIST"; + return; + } + IMoneyModule money = World.RequestModuleInterface(); if (money == null) @@ -15716,8 +15735,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } string reason; - bool result = money.ObjectGiveMoney( - m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn, out reason); + bool result = money.ObjectGiveMoney( m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn, out reason); if (result) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 204f73e318..7a2b24f251 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -3469,6 +3469,49 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + public void osSetHealth(string avatar, double health) + { + CheckThreatLevel(ThreatLevel.High, "osSetHealth"); + m_host.AddScriptLPS(1); + + UUID avatarId = new UUID(avatar); + ScenePresence presence = World.GetScenePresence(avatarId); + + if (presence != null && World.ScriptDanger(m_host.LocalId, m_host.GetWorldPosition())) + { + if (health > 100.0) + health = 100.0; + else if (health < 1.0) + health = 1.0; + + presence.setHealthWithUpdate((float)health); + } + } + + public void osSetHealRate(string avatar, double healrate) + { + CheckThreatLevel(ThreatLevel.High, "osSetHealRate"); + m_host.AddScriptLPS(1); + + UUID avatarId = new UUID(avatar); + ScenePresence presence = World.GetScenePresence(avatarId); + + if (presence != null && World.ScriptDanger(m_host.LocalId, m_host.GetWorldPosition())) + presence.HealRate = (float)healrate; + } + + public LSL_Float osGetHealRate(string avatar) + { + CheckThreatLevel(ThreatLevel.None, "osGetHealRate"); + m_host.AddScriptLPS(1); + + LSL_Float rate = new LSL_Float(0); + ScenePresence presence = World.GetScenePresence(new UUID(avatar)); + if (presence != null) + rate = presence.HealRate; + return rate; + } + public LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules) { CheckThreatLevel(ThreatLevel.High, "osGetPrimitiveParams"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index c1a177a1a9..c99679e08d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -368,6 +368,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osSetSpeed(string UUID, LSL_Float SpeedModifier); LSL_Float osGetHealth(string avatar); void osCauseHealing(string avatar, double healing); + void osSetHealth(string avatar, double health); + void osSetHealRate(string avatar, double health); + LSL_Float osGetHealRate(string avatar); void osCauseDamage(string avatar, double damage); void osForceOtherSit(string avatar); void osForceOtherSit(string avatar, string target); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index d58629081f..35eee5992e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -945,6 +945,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osCauseHealing(avatar, healing); } + public void osSetHealth(string avatar, double health) + { + m_OSSL_Functions.osSetHealth(avatar, health); + } + + public void osSetHealRate(string avatar, double health) + { + m_OSSL_Functions.osSetHealRate(avatar, health); + } + + public LSL_Float osGetHealRate(string avatar) + { + return m_OSSL_Functions.osGetHealRate(avatar); + } + public void osForceOtherSit(string avatar) { m_OSSL_Functions.osForceOtherSit(avatar); diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 98a98c069c..4f8e986771 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -404,16 +404,19 @@ namespace OpenSim.Tests.Common public UUID ActiveGroupId { get { return UUID.Zero; } + set { } } public string ActiveGroupName { get { return String.Empty; } + set { } } public ulong ActiveGroupPowers { get { return 0; } + set { } } public bool IsGroupMember(UUID groupID) @@ -421,6 +424,13 @@ namespace OpenSim.Tests.Common return false; } + public Dictionary GetGroupPowers() + { + return new Dictionary(); + } + + public void SetGroupPowers(Dictionary powers) { } + public ulong GetGroupPowers(UUID groupID) { return 0; diff --git a/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs b/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs index 6ed9a16c5b..417efce63c 100644 --- a/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs +++ b/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs @@ -147,9 +147,9 @@ namespace OpenSim.Tests.Common timeStamp, offline, parentEstateID, position, ttl, transactionID, fromGroup, binaryBucket); } - public void ChatterBoxSessionAgentListUpdates (UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, bool isModerator, bool textMute) + public void ChatterBoxSessionAgentListUpdates (UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, bool isModerator, bool textMute , bool isEnterorLeave) { - AddEvent(toAgent, "ChatterBoxSessionAgentListUpdates", sessionID, fromAgent, canVoiceChat, isModerator, textMute); + AddEvent(toAgent, "ChatterBoxSessionAgentListUpdates", sessionID, fromAgent, canVoiceChat, isModerator, textMute, isEnterorLeave); } public void ParcelProperties (OpenMetaverse.Messages.Linden.ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID) diff --git a/bin/config-include/osslEnable.ini b/bin/config-include/osslEnable.ini index 0a03d4c238..8f9702dc12 100644 --- a/bin/config-include/osslEnable.ini +++ b/bin/config-include/osslEnable.ini @@ -157,6 +157,9 @@ ; ThreatLevel High Allow_osCauseDamage = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osCauseHealing = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetHealth = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetHealRate = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetHealRate = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osForceAttachToAvatar = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osForceAttachToAvatarFromInventory = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osForceCreateLink = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER