diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index ae6c44bb6a..f040ff78e0 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -224,7 +224,9 @@ namespace OpenSim.Capabilities.Handlers // sending back the last byte instead of an error status if (start >= texture.Data.Length) { - response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; +// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; + // viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters + response.StatusCode = (int)System.Net.HttpStatusCode.NotFound; } else { diff --git a/OpenSim/Framework/Console/RemoteConsole.cs b/OpenSim/Framework/Console/RemoteConsole.cs index eabb62dd01..e04ca1e1e0 100644 --- a/OpenSim/Framework/Console/RemoteConsole.cs +++ b/OpenSim/Framework/Console/RemoteConsole.cs @@ -233,7 +233,7 @@ namespace OpenSim.Framework.Console string uri = "/ReadResponses/" + sessionID.ToString() + "/"; m_Server.AddPollServiceHTTPHandler( - uri, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, sessionID)); + uri, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout XmlDocument xmldoc = new XmlDocument(); XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs index 3089351a69..bb43cd2d62 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs @@ -45,17 +45,27 @@ namespace OpenSim.Framework.Servers.HttpServer public NoEventsMethod NoEvents; public RequestMethod Request; public UUID Id; + public int TimeOutms; + public EventType Type; + + public enum EventType : int + { + Normal = 0, + LslHttp = 1 + } public PollServiceEventArgs( RequestMethod pRequest, HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, - UUID pId) + UUID pId, int pTimeOutms) { Request = pRequest; HasEvents = pHasEvents; GetEvents = pGetEvents; NoEvents = pNoEvents; Id = pId; + TimeOutms = pTimeOutms; + Type = EventType.Normal; } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index 5bc85ffa2f..3a14b6fe9b 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs @@ -33,8 +33,11 @@ using log4net; using HttpServer; using OpenSim.Framework; + +/* namespace OpenSim.Framework.Servers.HttpServer { + public class PollServiceRequestManager { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -158,3 +161,236 @@ namespace OpenSim.Framework.Servers.HttpServer } } } + */ + +using System.IO; +using System.Text; +using System.Collections.Generic; + +namespace OpenSim.Framework.Servers.HttpServer +{ + public class PollServiceRequestManager + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private readonly BaseHttpServer m_server; + + private BlockingQueue m_requests = new BlockingQueue(); + private static Queue m_slowRequests = new Queue(); + private static Queue m_retryRequests = new Queue(); + + private uint m_WorkerThreadCount = 0; + private Thread[] m_workerThreads; + private Thread m_retrysThread; + + private bool m_running = true; + private int slowCount = 0; + + // private int m_timeout = 250; // increase timeout 250; now use the event one + + public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout) + { + m_server = pSrv; + m_WorkerThreadCount = pWorkerThreadCount; + m_workerThreads = new Thread[m_WorkerThreadCount]; + + //startup worker threads + for (uint i = 0; i < m_WorkerThreadCount; i++) + { + m_workerThreads[i] + = Watchdog.StartThread( + PoolWorkerJob, + String.Format("PollServiceWorkerThread{0}", i), + ThreadPriority.Normal, + false, + true, + null, + int.MaxValue); + } + + m_retrysThread = Watchdog.StartThread( + this.CheckRetries, + "PollServiceWatcherThread", + ThreadPriority.Normal, + false, + true, + null, + 1000 * 60 * 10); + } + + + private void ReQueueEvent(PollServiceHttpRequest req) + { + if (m_running) + { + lock (m_retryRequests) + m_retryRequests.Enqueue(req); + } + } + + public void Enqueue(PollServiceHttpRequest req) + { + if (m_running) + { + if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LslHttp) + { + m_requests.Enqueue(req); + } + else + { + lock (m_slowRequests) + m_slowRequests.Enqueue(req); + } + } + } + + private void CheckRetries() + { + while (m_running) + { + Thread.Sleep(100); // let the world move .. back to faster rate + Watchdog.UpdateThread(); + lock (m_retryRequests) + { + while (m_retryRequests.Count > 0 && m_running) + m_requests.Enqueue(m_retryRequests.Dequeue()); + } + slowCount++; + if (slowCount >= 10) + { + slowCount = 0; + + lock (m_slowRequests) + { + while (m_slowRequests.Count > 0 && m_running) + m_requests.Enqueue(m_slowRequests.Dequeue()); + } + } + } + } + + ~PollServiceRequestManager() + { + m_running = false; +// m_timeout = -10000; // cause all to expire + Thread.Sleep(1000); // let the world move + + foreach (Thread t in m_workerThreads) + { + try + { + t.Abort(); + } + catch + { + } + } + + try + { + foreach (PollServiceHttpRequest req in m_retryRequests) + { + m_server.DoHTTPGruntWork( + req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id), + new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext)); + } + } + catch + { + } + + PollServiceHttpRequest wreq; + m_retryRequests.Clear(); + + lock (m_slowRequests) + { + while (m_slowRequests.Count > 0 && m_running) + m_requests.Enqueue(m_slowRequests.Dequeue()); + } + + while (m_requests.Count() > 0) + { + try + { + wreq = m_requests.Dequeue(0); + m_server.DoHTTPGruntWork( + wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id), + new OSHttpResponse(new HttpResponse(wreq.HttpContext, wreq.Request), wreq.HttpContext)); + } + catch + { + } + } + + m_requests.Clear(); + } + + // work threads + + private void PoolWorkerJob() + { + PollServiceHttpRequest req; + StreamReader str; + +// while (true) + while (m_running) + { + req = m_requests.Dequeue(5000); + + Watchdog.UpdateThread(); + if (req != null) + { + try + { + if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) + { + try + { + str = new StreamReader(req.Request.Body); + } + catch (System.ArgumentException) + { + // Stream was not readable means a child agent + // was closed due to logout, leaving the + // Event Queue request orphaned. + continue; + } + + try + { + Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd()); + m_server.DoHTTPGruntWork(responsedata, + new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext)); + } + catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream + { + // Ignore it, no need to reply + } + + str.Close(); + + } + else + { + // if ((Environment.TickCount - req.RequestTime) > m_timeout) + if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) + { + m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id), + new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext)); + } + else + { + ReQueueEvent(req); + } + } + } + catch (Exception e) + { + m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); + } + } + } + } + } +} + diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs index d305782071..1e3fbf0db5 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs @@ -25,6 +25,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* Ubit work moved to PollServiceRequestManager + using System; using System.Collections; using System.Collections.Generic; @@ -169,3 +171,4 @@ namespace OpenSim.Framework.Servers.HttpServer } } } +*/ \ No newline at end of file diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 0d7390b4de..ebfe68721e 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -377,7 +377,7 @@ namespace OpenSim.Region.ClientStack.Linden // TODO: Add EventQueueGet name/description for diagnostics MainServer.Instance.AddPollServiceHTTPHandler( eventQueueGetPath, - new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); + new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID, 1000)); // m_log.DebugFormat( // "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 18602f7917..34619713ae 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -5080,10 +5080,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP update.TextureEntry = Utils.EmptyBytes; // update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; +/* all this flags seem related to prims and not avatars. This allow for wrong viewer side move of a avatar in prim edition mode (anv mantis 854) update.UpdateFlags = (uint)( PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | PrimFlags.ObjectOwnerModify); +*/ + update.UpdateFlags = 0; return update; } @@ -6404,6 +6407,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP { handlerCompleteMovementToRegion(sender, true); } + else + m_log.Debug("HandleCompleteAgentMovement NULL handler"); + handlerCompleteMovementToRegion = null; return true; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index e55e2c53f8..754d9d29fb 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -779,14 +779,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP IClientAPI client; if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView)) { - //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); +// m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); return; } udpClient = ((LLClientView)client).UDPClient; if (!udpClient.IsConnected) + { +// m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName); return; + } #endregion Packet to Client Mapping diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index bc42fd1483..dbbb0aec7d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs @@ -351,9 +351,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat UUID fromAgentID, string fromName, ChatTypeEnum type, string message, ChatSourceType src) { - // don't send llRegionSay to child agents. Send normal chat because you - // can't talk across sim borders if it's not done - if (type == ChatTypeEnum.Broadcast && presence.IsChildAgent) return false; + // don't send chat to child agents + if (presence.IsChildAgent) return false; Vector3 fromRegionPos = fromPos + regionPos; Vector3 toRegionPos = presence.AbsolutePosition + diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 192b4f6fee..7f2f1478cc 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -184,9 +184,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp string uri = "/lslhttp/" + urlcode.ToString(); - m_HttpServer.AddPollServiceHTTPHandler( - uri, - new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); + PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000); + args.Type = PollServiceEventArgs.EventType.LslHttp; + m_HttpServer.AddPollServiceHTTPHandler(uri, args); m_log.DebugFormat( "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", @@ -232,7 +232,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp m_HttpsServer.AddPollServiceHTTPHandler( uri, - new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); + new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode,25000)); m_log.DebugFormat( "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", @@ -446,7 +446,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp } private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) { - UrlData url = null; + UrlData url = null; RequestData requestData = null; lock (m_RequestMap) diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index b7667b9049..4f067374d2 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -200,7 +200,7 @@ namespace OpenSim.Region.CoreModules.World.Land * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L); - m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax); + //m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax); return parcelMax; } } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 4c12496835..3390aba49b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -592,12 +592,12 @@ namespace OpenSim.Region.Framework.Scenes protected internal void AddPhysicalPrim(int number) { - m_physicalPrim++; + m_physicalPrim += number; } protected internal void RemovePhysicalPrim(int number) { - m_physicalPrim--; + m_physicalPrim -= number; } protected internal void AddToScriptLPS(int number) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 3db6710c8d..f68a5b339c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -656,6 +656,14 @@ namespace OpenSim.Region.Framework.Scenes if (triggerScriptEvent) part.TriggerScriptChangedEvent(Changed.POSITION); } + +/* + This seems not needed and should not be needed: + sp absolute position depends on sit part absolute position fixed above. + sp ParentPosition is not used anywhere. + Since presence is sitting, viewer considers it 'linked' to root prim, so it will move/rotate it + Sending a extra packet with avatar position is not only bandwidth waste, but may cause jitter in viewers due to UPD nature. + if (!m_dupeInProgress) { foreach (ScenePresence av in m_linkedAvatars) @@ -665,12 +673,12 @@ namespace OpenSim.Region.Framework.Scenes { Vector3 offset = p.GetWorldPosition() - av.ParentPosition; av.AbsolutePosition += offset; - av.ParentPosition = p.GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition +// av.ParentPosition = p.GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition av.SendAvatarDataToAllAgents(); } } } - +*/ //if (m_rootPart.PhysActor != null) //{ //m_rootPart.PhysActor.Position = @@ -701,8 +709,8 @@ namespace OpenSim.Region.Framework.Scenes if (agent.ParentUUID != UUID.Zero) { agent.ParentPart = null; - agent.ParentPosition = Vector3.Zero; - // agent.ParentUUID = UUID.Zero; +// agent.ParentPosition = Vector3.Zero; +// agent.ParentUUID = UUID.Zero; } } @@ -3815,7 +3823,7 @@ namespace OpenSim.Region.Framework.Scenes else // ugly rotation update of all parts { - group.AbsolutePosition = AbsolutePosition; + group.ResetChildPrimPhysicsPositions(); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index f1e781c8b7..7b1f5d2477 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1856,6 +1856,34 @@ namespace OpenSim.Region.Framework.Scenes } } +// SetVelocity for LSL llSetVelocity.. may need revision if having other uses in future + public void SetVelocity(Vector3 pVel, bool localGlobalTF) + { + if (ParentGroup == null || ParentGroup.IsDeleted) + return; + + if (ParentGroup.IsAttachment) + return; // don't work on attachments (for now ??) + + SceneObjectPart root = ParentGroup.RootPart; + + if (root.VehicleType != (int)Vehicle.TYPE_NONE) // don't mess with vehicles + return; + + PhysicsActor pa = root.PhysActor; + + if (pa == null || !pa.IsPhysical) + return; + + if (localGlobalTF) + { + pVel = pVel * GetWorldRotation(); + } + + ParentGroup.Velocity = pVel; + } + + /// /// hook to the physics scene to apply angular impulse /// This is sent up to the group, which then finds the root prim @@ -4512,7 +4540,8 @@ namespace OpenSim.Region.Framework.Scenes { if (pa != null) { - ParentGroup.Scene.RemovePhysicalPrim(1); + if(wasUsingPhysics) + ParentGroup.Scene.RemovePhysicalPrim(1); RemoveFromPhysics(); } @@ -4529,37 +4558,36 @@ namespace OpenSim.Region.Framework.Scenes { AddToPhysics(UsePhysics, SetPhantom, building, false); pa = PhysActor; - /* - if (pa != null) - { - if ( - // ((AggregateScriptEvents & scriptEvents.collision) != 0) || - // ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || - // ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || - // ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || - // ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || - // ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || - ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || - ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || - (CollisionSound != UUID.Zero) - ) - { - pa.OnCollisionUpdate += PhysicsCollision; - pa.SubscribeEvents(1000); - } - } - */ +/* + if (pa != null) + { + if ( +// ((AggregateScriptEvents & scriptEvents.collision) != 0) || +// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || +// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || +// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || +// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || +// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || + ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || + (CollisionSound != UUID.Zero) + ) + { + pa.OnCollisionUpdate += PhysicsCollision; + pa.SubscribeEvents(1000); + } + } +*/ } else // it already has a physical representation { DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. - /* moved into DoPhysicsPropertyUpdate - if(VolumeDetectActive) - pa.SetVolumeDetect(1); - else - pa.SetVolumeDetect(0); - */ - +/* moved into DoPhysicsPropertyUpdate + if(VolumeDetectActive) + pa.SetVolumeDetect(1); + else + pa.SetVolumeDetect(0); +*/ if (pa.Building != building) pa.Building = building; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 159a92ac7e..f0ceff66ea 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -439,7 +439,7 @@ namespace OpenSim.Region.Framework.Scenes get { return (IClientCore)ControllingClient; } } - public Vector3 ParentPosition { get; set; } +// public Vector3 ParentPosition { get; set; } /// /// Position of this avatar relative to the region the avatar is in @@ -497,7 +497,7 @@ namespace OpenSim.Region.Framework.Scenes if (ParentID == 0) { m_pos = value; - ParentPosition = Vector3.Zero; +// ParentPosition = Vector3.Zero; } //m_log.DebugFormat( @@ -865,11 +865,12 @@ namespace OpenSim.Region.Framework.Scenes part.ParentGroup.AddAvatar(UUID); if (part.SitTargetPosition != Vector3.Zero) part.SitTargetAvatar = UUID; - ParentPosition = part.GetWorldPosition(); +// ParentPosition = part.GetWorldPosition(); ParentID = part.LocalId; ParentPart = part; m_pos = m_prevSitOffset; - pos = ParentPosition; +// pos = ParentPosition; + pos = part.GetWorldPosition(); } ParentUUID = UUID.Zero; @@ -1944,11 +1945,12 @@ namespace OpenSim.Region.Framework.Scenes part.SitTargetAvatar = UUID.Zero; part.ParentGroup.DeleteAvatar(UUID); - ParentPosition = part.GetWorldPosition(); +// ParentPosition = part.GetWorldPosition(); ControllingClient.SendClearFollowCamProperties(part.ParentUUID); - m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); - ParentPosition = Vector3.Zero; +// m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); +// ParentPosition = Vector3.Zero; + m_pos += part.GetWorldPosition() + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); ParentID = 0; ParentPart = null; @@ -2399,13 +2401,13 @@ namespace OpenSim.Region.Framework.Scenes // m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset; Rotation = sitTargetOrient; - ParentPosition = part.AbsolutePosition; +// ParentPosition = part.AbsolutePosition; part.ParentGroup.AddAvatar(UUID); } else { m_pos -= part.AbsolutePosition; - ParentPosition = part.AbsolutePosition; +// ParentPosition = part.AbsolutePosition; part.ParentGroup.AddAvatar(UUID); // m_log.DebugFormat( @@ -3587,7 +3589,8 @@ namespace OpenSim.Region.Framework.Scenes // m_reprioritizationTimer.Dispose(); RemoveFromPhysicalScene(); - Animator.Close(); + if(Animator != null) + Animator.Close(); Animator = null; } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 286c7f0721..6c72324ba4 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -302,6 +302,7 @@ namespace OpenSim.Region.Physics.OdePlugin // split static geometry collision into a grid as before private IntPtr[,] staticPrimspace; + private IntPtr[] staticPrimspaceOffRegion; public Object OdeLock; private static Object SimulationLock; @@ -551,6 +552,7 @@ namespace OpenSim.Region.Physics.OdePlugin // create all spaces now int i, j; IntPtr newspace; + for (i = 0; i < spaceGridMaxX; i++) for (j = 0; j < spaceGridMaxY; j++) { @@ -573,6 +575,29 @@ namespace OpenSim.Region.Physics.OdePlugin // let this now be real maximum values spaceGridMaxX--; spaceGridMaxY--; + + // create 4 off world spaces (x<0,x>max,y<0,y>max) + staticPrimspaceOffRegion = new IntPtr[4]; + + for (i = 0; i < 4; i++) + { + newspace = d.HashSpaceCreate(StaticSpace); + d.GeomSetCategoryBits(newspace, (int)CollisionCategories.Space); + waitForSpaceUnlock(newspace); + d.SpaceSetSublevel(newspace, 2); + d.HashSpaceSetLevels(newspace, -2, 8); + d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space | + CollisionCategories.Geom | + CollisionCategories.Land | + CollisionCategories.Water | + CollisionCategories.Phantom | + CollisionCategories.VolumeDtc + )); + d.GeomSetCollideBits(newspace, 0); + + staticPrimspaceOffRegion[i] = newspace; + } + m_lastframe = DateTime.UtcNow; } @@ -1650,20 +1675,22 @@ namespace OpenSim.Region.Physics.OdePlugin public IntPtr calculateSpaceForGeom(Vector3 pos) { int x, y; + + if (pos.X < 0) + return staticPrimspaceOffRegion[0]; + + if (pos.Y < 0) + return staticPrimspaceOffRegion[2]; + x = (int)(pos.X * spacesPerMeter); - if (x < 0) - x = 0; - else if (x > spaceGridMaxX) - x = spaceGridMaxX; - + if (x > spaceGridMaxX) + return staticPrimspaceOffRegion[1]; + y = (int)(pos.Y * spacesPerMeter); - if (y < 0) - y = 0; - else if (y >spaceGridMaxY) - y = spaceGridMaxY; + if (y > spaceGridMaxY) + return staticPrimspaceOffRegion[3]; - IntPtr tmpSpace = staticPrimspace[x, y]; - return tmpSpace; + return staticPrimspace[x, y]; } #endregion diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 14dd2adcea..b257cd4f16 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -618,18 +618,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); double x,y,z,s; + v.x *= 0.5; + v.y *= 0.5; + v.z *= 0.5; + double c1 = Math.Cos(v.x); + double c2 = Math.Cos(v.y); + double c1c2 = c1 * c2; + double s1 = Math.Sin(v.x); + double s2 = Math.Sin(v.y); + double s1s2 = s1 * s2; + double c1s2 = c1 * s2; + double s1c2 = s1 * c2; + double c3 = Math.Cos(v.z); + double s3 = Math.Sin(v.z); - double c1 = Math.Cos(v.x * 0.5); - double c2 = Math.Cos(v.y * 0.5); - double c3 = Math.Cos(v.z * 0.5); - double s1 = Math.Sin(v.x * 0.5); - double s2 = Math.Sin(v.y * 0.5); - double s3 = Math.Sin(v.z * 0.5); - - x = s1 * c2 * c3 + c1 * s2 * s3; - y = c1 * s2 * c3 - s1 * c2 * s3; - z = s1 * s2 * c3 + c1 * c2 * s3; - s = c1 * c2 * c3 - s1 * s2 * s3; + x = s1c2 * c3 + c1s2 * s3; + y = c1s2 * c3 - s1c2 * s3; + z = s1s2 * c3 + c1c2 * s3; + s = c1c2 * c3 - s1s2 * s3; return new LSL_Rotation(x, y, z, s); } @@ -1869,11 +1875,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api Primitive.TextureEntry tex = part.Shape.Textures; Color4 texcolor; LSL_Vector rgb = new LSL_Vector(); + int nsides = GetNumberOfSides(part); + if (face == ScriptBaseClass.ALL_SIDES) { int i; - - for (i = 0 ; i < GetNumberOfSides(part); i++) + for (i = 0; i < nsides; i++) { texcolor = tex.GetFace((uint)i).RGBA; rgb.x += texcolor.R; @@ -1881,14 +1888,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api rgb.z += texcolor.B; } - rgb.x /= (float)GetNumberOfSides(part); - rgb.y /= (float)GetNumberOfSides(part); - rgb.z /= (float)GetNumberOfSides(part); + float invnsides = 1.0f / (float)nsides; + + rgb.x *= invnsides; + rgb.y *= invnsides; + rgb.z *= invnsides; return rgb; } - - if (face >= 0 && face < GetNumberOfSides(part)) + if (face >= 0 && face < nsides) { texcolor = tex.GetFace((uint)face).RGBA; rgb.x = texcolor.R; @@ -2288,15 +2296,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // (root prim). ParentID may be nonzero in attachments and // using it would cause attachments and HUDs to rotate // to the wrong positions. + SetRot(m_host, Rot2Quaternion(rot)); } else { // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. - SceneObjectPart rootPart = m_host.ParentGroup.RootPart; - if (rootPart != null) // better safe than sorry + SceneObjectPart rootPart; + if (m_host.ParentGroup != null) // better safe than sorry { - SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); + rootPart = m_host.ParentGroup.RootPart; + if (rootPart != null) + SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); } } @@ -2306,6 +2317,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSetLocalRot(LSL_Rotation rot) { m_host.AddScriptLPS(1); + SetRot(m_host, Rot2Quaternion(rot)); ScriptSleep(200); } @@ -2315,25 +2327,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; - part.UpdateRotation(rot); - // Update rotation does not move the object in the physics scene if it's a linkset. + bool isroot = (part == part.ParentGroup.RootPart); + bool isphys; -//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type -// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; - - // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line - // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt - // It's perfectly okay when the object is not an active physical body though. - // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against - // but only if the object is not physial and active. This is important for rotating doors. - // without the absoluteposition = absoluteposition happening, the doors do not move in the physics - // scene PhysicsActor pa = part.PhysActor; - if (pa != null && !pa.IsPhysical && part == part.ParentGroup.RootPart) + // keep using physactor ideia of isphysical + // it should be SOP ideia of that + // not much of a issue with ubitODE + if (pa != null && pa.IsPhysical) + isphys = true; + else + isphys = false; + + // SL doesn't let scripts rotate root of physical linksets + if (isroot && isphys) + return; + + part.UpdateRotation(rot); + + // Update rotation does not move the object in the physics engine if it's a non physical linkset + // so do a nasty update of parts positions if is a root part rotation + if (isroot && pa != null) // with if above implies non physical root part { part.ParentGroup.ResetChildPrimPhysicsPositions(); } + else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part + { + List sittingavas = part.ParentGroup.GetLinkedAvatars(); + if (sittingavas.Count > 0) + { + foreach (ScenePresence av in sittingavas) + { + if (isroot || part.LocalId == av.ParentID) + av.SendTerseUpdateToAllClients(); + } + } + } } /// @@ -2382,7 +2412,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Rotation llGetLocalRot() { m_host.AddScriptLPS(1); - return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); + Quaternion rot = m_host.RotationOffset; + return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W); } public void llSetForce(LSL_Vector force, int local) @@ -2466,6 +2497,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.ApplyImpulse(v, local != 0); } + public void llApplyRotationalImpulse(LSL_Vector force, int local) { m_host.AddScriptLPS(1); @@ -2492,6 +2524,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api llSetTorque(torque, local); } + public void llSetVelocity(LSL_Vector vel, int local) + { + m_host.AddScriptLPS(1); + m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0); + } + public LSL_Vector llGetVel() { m_host.AddScriptLPS(1); @@ -2518,10 +2556,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); } + + public void llSetAngularVelocity(LSL_Vector avel, int local) + { + m_host.AddScriptLPS(1); + // Still not done !!!! +// m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0); + } + public LSL_Vector llGetOmega() { m_host.AddScriptLPS(1); - return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); + Vector3 avel = m_host.AngularVelocity; + return new LSL_Vector(avel.X, avel.Y, avel.Z); } public LSL_Float llGetTimeOfDay() @@ -7740,7 +7787,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api Quaternion srot = sitpart.RotationOffset; rot = Quaternion.Conjugate(srot) * rot; // removed sit part offset rotation av.Rotation = rot; - av.SendAvatarDataToAllAgents(); +// av.SendAvatarDataToAllAgents(); + av.SendTerseUpdateToAllClients(); } break; @@ -7760,7 +7808,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api rot = Quaternion.Conjugate(srot) * rot; // remove sit part offset rotation } av.Rotation = rot; - av.SendAvatarDataToAllAgents(); +// av.SendAvatarDataToAllAgents(); + av.SendTerseUpdateToAllClients(); } break; @@ -7855,7 +7904,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { positionChanged = false; av.OffsetPosition = finalPos; - av.SendAvatarDataToAllAgents(); +// av.SendAvatarDataToAllAgents(); + av.SendTerseUpdateToAllClients(); } LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); @@ -7871,7 +7921,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (positionChanged) { av.OffsetPosition = finalPos; - av.SendAvatarDataToAllAgents(); +// av.SendAvatarDataToAllAgents(); + av.SendTerseUpdateToAllClients(); positionChanged = false; } } @@ -8280,6 +8331,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case (int)ScriptBaseClass.PRIM_ROT_LOCAL: if (remain < 1) return; + LSL_Rotation lr = rules.GetQuaternionItem(idx++); SetRot(part, Rot2Quaternion(lr)); break; @@ -8379,10 +8431,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String llXorBase64Strings(string str1, string str2) { - m_host.AddScriptLPS(1); - Deprecated("llXorBase64Strings"); + string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + ScriptSleep(300); - return String.Empty; + m_host.AddScriptLPS(1); + + if (str1 == String.Empty) + return String.Empty; + if (str2 == String.Empty) + return str1; + + int len = str2.Length; + if ((len % 4) != 0) // LL is EVIL!!!! + { + while (str2.EndsWith("=")) + str2 = str2.Substring(0, str2.Length - 1); + + len = str2.Length; + int mod = len % 4; + + if (mod == 1) + str2 = str2.Substring(0, str2.Length - 1); + else if (mod == 2) + str2 += "=="; + else if (mod == 3) + str2 += "="; + } + + byte[] data1; + byte[] data2; + try + { + data1 = Convert.FromBase64String(str1); + data2 = Convert.FromBase64String(str2); + } + catch (Exception) + { + return new LSL_String(String.Empty); + } + + // For cases where the decoded length of s2 is greater + // than the decoded length of s1, simply perform a normal + // decode and XOR + // + if (data2.Length >= data1.Length) + { + for (int pos = 0 ; pos < data1.Length ; pos++ ) + data1[pos] ^= data2[pos]; + + return Convert.ToBase64String(data1); + } + + // Remove padding + while (str1.EndsWith("=")) + str1 = str1.Substring(0, str1.Length - 1); + while (str2.EndsWith("=")) + str2 = str2.Substring(0, str2.Length - 1); + + byte[] d1 = new byte[str1.Length]; + byte[] d2 = new byte[str2.Length]; + + for (int i = 0 ; i < str1.Length ; i++) + { + int idx = b64.IndexOf(str1.Substring(i, 1)); + if (idx == -1) + idx = 0; + d1[i] = (byte)idx; + } + + for (int i = 0 ; i < str2.Length ; i++) + { + int idx = b64.IndexOf(str2.Substring(i, 1)); + if (idx == -1) + idx = 0; + d2[i] = (byte)idx; + } + + string output = String.Empty; + + for (int pos = 0 ; pos < d1.Length ; pos++) + output += b64[d1[pos] ^ d2[pos % d2.Length]]; + + while (output.Length % 3 > 0) + output += "="; + + return output; } public void llRemoteDataSetRegion() @@ -12254,7 +12387,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); - if (false)// World.SuportsRayCastFiltered()) + if (World.SuportsRayCastFiltered()) { if (dist == 0) return list; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 749fc97d8c..af352589ff 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -332,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llSensorRemove(); void llSensorRepeat(string name, string id, int type, double range, double arc, double rate); void llSetAlpha(double alpha, int face); + void llSetAngularVelocity(LSL_Vector angvelocity, int local); void llSetBuoyancy(double buoyancy); void llSetCameraAtOffset(LSL_Vector offset); void llSetCameraEyeOffset(LSL_Vector offset); @@ -381,6 +382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llSetVehicleRotationParam(int param, LSL_Rotation rot); void llSetVehicleType(int type); void llSetVehicleVectorParam(int param, LSL_Vector vec); + void llSetVelocity(LSL_Vector velocity, int local); void llShout(int channelID, string text); LSL_Float llSin(double f); void llSitTarget(LSL_Vector offset, LSL_Rotation rot); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 06f2c3cc1d..89b6eff417 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -1495,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llSetAlpha(alpha, face); } + public void llSetAngularVelocity(LSL_Vector angvelocity, int local) + { + m_LSL_Functions.llSetAngularVelocity(angvelocity, local); + } + public void llSetBuoyancy(double buoyancy) { m_LSL_Functions.llSetBuoyancy(buoyancy); @@ -1730,6 +1735,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llSetVehicleVectorParam(param, vec); } + public void llSetVelocity(LSL_Vector velocity, int local) + { + m_LSL_Functions.llSetVelocity(velocity, local); + } + public void llShout(int channelID, string text) { m_LSL_Functions.llShout(channelID, text);