Merge branch 'master' into careminster

Conflicts:
	OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
	OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
	OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
	OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
	OpenSim/Region/Framework/Scenes/Scene.cs
	OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
	OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
	OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
avinationmerge
Melanie 2013-07-13 00:47:58 +01:00
commit a53a10ad27
107 changed files with 2119 additions and 955 deletions

View File

@ -485,7 +485,7 @@ namespace OpenSim.Groups
return; return;
//// 16 bytes are the UUID. Maybe. //// 16 bytes are the UUID. Maybe.
UUID folderID = new UUID(im.binaryBucket, 0); // UUID folderID = new UUID(im.binaryBucket, 0);
UUID noticeID = new UUID(im.imSessionID); UUID noticeID = new UUID(im.imSessionID);
GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteClient.AgentId.ToString(), noticeID); GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteClient.AgentId.ToString(), noticeID);

View File

@ -543,7 +543,6 @@ namespace OpenSim.Groups
List<string> urls = new List<string>(); List<string> urls = new List<string>();
foreach (GroupMembersData m in members) foreach (GroupMembersData m in members)
{ {
UUID userID = UUID.Zero;
if (!m_UserManagement.IsLocalGridUser(m.AgentID)) if (!m_UserManagement.IsLocalGridUser(m.AgentID))
{ {
string gURL = m_UserManagement.GetUserServerURL(m.AgentID, "GroupsServerURI"); string gURL = m_UserManagement.GetUserServerURL(m.AgentID, "GroupsServerURI");

View File

@ -47,7 +47,6 @@ namespace OpenSim.Groups
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private HGGroupsService m_GroupsService; private HGGroupsService m_GroupsService;
private string m_HomeURI = string.Empty;
private string m_ConfigName = "Groups"; private string m_ConfigName = "Groups";
// Called by Robust shell // Called by Robust shell
@ -113,7 +112,7 @@ namespace OpenSim.Groups
m_GroupsService = service; m_GroupsService = service;
} }
public override byte[] Handle(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); StreamReader sr = new StreamReader(requestData);
@ -209,7 +208,6 @@ namespace OpenSim.Groups
UUID groupID = new UUID(request["GroupID"].ToString()); UUID groupID = new UUID(request["GroupID"].ToString());
string agentID = request["AgentID"].ToString(); string agentID = request["AgentID"].ToString();
string token = request["AccessToken"].ToString(); string token = request["AccessToken"].ToString();
string reason = string.Empty;
m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token); m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token);
} }

View File

@ -75,7 +75,7 @@ namespace OpenSim.Groups
m_GroupsService = service; m_GroupsService = service;
} }
public override byte[] Handle(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); StreamReader sr = new StreamReader(requestData);
@ -269,7 +269,6 @@ namespace OpenSim.Groups
UUID groupID = new UUID(request["GroupID"].ToString()); UUID groupID = new UUID(request["GroupID"].ToString());
string agentID = request["AgentID"].ToString(); string agentID = request["AgentID"].ToString();
string requestingAgentID = request["RequestingAgentID"].ToString(); string requestingAgentID = request["RequestingAgentID"].ToString();
string reason = string.Empty;
m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID); m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID);
} }
@ -500,7 +499,6 @@ namespace OpenSim.Groups
else else
{ {
string op = request["OP"].ToString(); string op = request["OP"].ToString();
string reason = string.Empty;
bool success = false; bool success = false;
if (op == "ADD") if (op == "ADD")
@ -568,7 +566,6 @@ namespace OpenSim.Groups
else else
{ {
string op = request["OP"].ToString(); string op = request["OP"].ToString();
string reason = string.Empty;
if (op == "GROUP") if (op == "GROUP")
{ {
@ -631,7 +628,6 @@ namespace OpenSim.Groups
else else
{ {
string op = request["OP"].ToString(); string op = request["OP"].ToString();
string reason = string.Empty;
if (op == "ADD" && request.ContainsKey("GroupID") && request.ContainsKey("RoleID") && request.ContainsKey("AgentID")) if (op == "ADD" && request.ContainsKey("GroupID") && request.ContainsKey("RoleID") && request.ContainsKey("AgentID"))
{ {

View File

@ -75,7 +75,7 @@ namespace OpenSim.OfflineIM
m_OfflineIMService = service; m_OfflineIMService = service;
} }
public override byte[] Handle(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); StreamReader sr = new StreamReader(requestData);

View File

@ -145,8 +145,8 @@ namespace OpenSim.Framework.Capabilities
/// <param name="handler"></param> /// <param name="handler"></param>
public void RegisterHandler(string capName, IRequestHandler handler) public void RegisterHandler(string capName, IRequestHandler handler)
{ {
m_capsHandlers[capName] = handler;
//m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path); //m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path);
m_capsHandlers[capName] = handler;
} }
/// <summary> /// <summary>

View File

@ -184,5 +184,17 @@ namespace OpenSim.Framework.Capabilities
return caps; return caps;
} }
/// <summary>
/// Returns a copy of the dictionary of all the HTTP cap handlers
/// </summary>
/// <returns>
/// The dictionary copy. The key is the capability name, the value is the HTTP handler.
/// </returns>
public Dictionary<string, IRequestHandler> GetCapsHandlers()
{
lock (m_capsHandlers)
return new Dictionary<string, IRequestHandler>(m_capsHandlers);
}
} }
} }

View File

@ -56,7 +56,7 @@ namespace OpenSim.Capabilities.Handlers
m_PeopleService = peopleService; m_PeopleService = peopleService;
} }
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
// Try to parse the texture ID from the request URL // Try to parse the texture ID from the request URL
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);

View File

@ -48,7 +48,7 @@ namespace OpenSim.Framework.Capabilities
m_method = method; m_method = method;
} }
public override byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
//Encoding encoding = Util.UTF8; //Encoding encoding = Util.UTF8;

View File

@ -33,12 +33,13 @@ namespace OpenSim.Framework
{ {
public class ClientInfo public class ClientInfo
{ {
public AgentCircuitData agentcircuit; public readonly DateTime StartedTime = DateTime.Now;
public AgentCircuitData agentcircuit = null;
public Dictionary<uint, byte[]> needAck; public Dictionary<uint, byte[]> needAck;
public List<byte[]> out_packets; public List<byte[]> out_packets = new List<byte[]>();
public Dictionary<uint, uint> pendingAcks; public Dictionary<uint, uint> pendingAcks = new Dictionary<uint,uint>();
public EndPoint proxyEP; public EndPoint proxyEP;
public uint sequence; public uint sequence;
@ -53,5 +54,9 @@ namespace OpenSim.Framework
public int assetThrottle; public int assetThrottle;
public int textureThrottle; public int textureThrottle;
public int totalThrottle; public int totalThrottle;
public Dictionary<string, int> SyncRequests = new Dictionary<string,int>();
public Dictionary<string, int> AsyncRequests = new Dictionary<string,int>();
public Dictionary<string, int> GenericRequests = new Dictionary<string,int>();
} }
} }

View File

@ -132,10 +132,6 @@ namespace OpenSim.Framework
{ {
List<string> keysToRemove = null; List<string> keysToRemove = null;
// Hard-coded special case that needs to be removed in the future. Normally, modules themselves should
// handle reading data from old locations
bool osMaterialsMigrationRequired = false;
OSDMap namespacesMap = daMap.m_map; OSDMap namespacesMap = daMap.m_map;
foreach (string key in namespacesMap.Keys) foreach (string key in namespacesMap.Keys)

View File

@ -689,7 +689,7 @@ namespace OpenSim.Framework.Servers.HttpServer
if (buffer != null) if (buffer != null)
{ {
if (!response.SendChunked) if (!response.SendChunked && response.ContentLength64 <= 0)
response.ContentLength64 = buffer.LongLength; response.ContentLength64 = buffer.LongLength;
response.OutputStream.Write(buffer, 0, buffer.Length); response.OutputStream.Write(buffer, 0, buffer.Length);

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.IO;
namespace OpenSim.Framework.Servers.HttpServer
{
/// <summary>
/// Base handler for writing to an output stream
/// </summary>
/// <remarks>
/// Inheriting classes should override ProcessRequest() rather than Handle()
/// </remarks>
public abstract class BaseOutputStreamHandler : BaseRequestHandler, IRequestHandler
{
protected BaseOutputStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
protected BaseOutputStreamHandler(string httpMethod, string path, string name, string description)
: base(httpMethod, path, name, description) {}
public virtual void Handle(
string path, Stream request, Stream response, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
RequestsReceived++;
ProcessRequest(path, request, response, httpRequest, httpResponse);
RequestsHandled++;
}
protected virtual void ProcessRequest(
string path, Stream request, Stream response, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
}
}
}

View File

@ -31,6 +31,10 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
public abstract class BaseRequestHandler public abstract class BaseRequestHandler
{ {
public int RequestsReceived { get; protected set; }
public int RequestsHandled { get; protected set; }
public virtual string ContentType public virtual string ContentType
{ {
get { return "application/xml"; } get { return "application/xml"; }

View File

@ -29,14 +29,35 @@ using System.IO;
namespace OpenSim.Framework.Servers.HttpServer namespace OpenSim.Framework.Servers.HttpServer
{ {
/// <summary>
/// Base streamed request handler.
/// </summary>
/// <remarks>
/// Inheriting classes should override ProcessRequest() rather than Handle()
/// </remarks>
public abstract class BaseStreamHandler : BaseRequestHandler, IStreamedRequestHandler public abstract class BaseStreamHandler : BaseRequestHandler, IStreamedRequestHandler
{ {
public abstract byte[] Handle(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse);
protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {} protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
protected BaseStreamHandler(string httpMethod, string path, string name, string description) protected BaseStreamHandler(string httpMethod, string path, string name, string description)
: base(httpMethod, path, name, description) {} : base(httpMethod, path, name, description) {}
public virtual byte[] Handle(
string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
RequestsReceived++;
byte[] result = ProcessRequest(path, request, httpRequest, httpResponse);
RequestsHandled++;
return result;
}
protected virtual byte[] ProcessRequest(
string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
return null;
}
} }
} }

View File

@ -45,7 +45,7 @@ namespace OpenSim.Framework.Servers.HttpServer
m_method = binaryMethod; m_method = binaryMethod;
} }
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
byte[] data = ReadFully(request); byte[] data = ReadFully(request);
string param = GetParam(path); string param = GetParam(path);

View File

@ -32,7 +32,6 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
public interface IRequestHandler public interface IRequestHandler
{ {
/// <summary> /// <summary>
/// Name for this handler. /// Name for this handler.
/// </summary> /// </summary>
@ -59,6 +58,19 @@ namespace OpenSim.Framework.Servers.HttpServer
// Return path // Return path
string Path { get; } string Path { get; }
/// <summary>
/// Number of requests received by this handler
/// </summary>
int RequestsReceived { get; }
/// <summary>
/// Number of requests handled.
/// </summary>
/// <remarks>
/// Should be equal to RequestsReceived unless requested are being handled slowly or there is deadlock.
/// </remarks>
int RequestsHandled { get; }
} }
public interface IStreamedRequestHandler : IRequestHandler public interface IStreamedRequestHandler : IRequestHandler
@ -69,7 +81,6 @@ namespace OpenSim.Framework.Servers.HttpServer
public interface IStreamHandler : IRequestHandler public interface IStreamHandler : IRequestHandler
{ {
// Handle request stream, return byte array
void Handle(string path, Stream request, Stream response, IOSHttpRequest httpReqbuest, IOSHttpResponse httpResponse); void Handle(string path, Stream request, Stream response, IOSHttpRequest httpReqbuest, IOSHttpResponse httpResponse);
} }

View File

@ -33,7 +33,7 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
public delegate TResponse RestDeserialiseMethod<TRequest, TResponse>(TRequest request); public delegate TResponse RestDeserialiseMethod<TRequest, TResponse>(TRequest request);
public class RestDeserialiseHandler<TRequest, TResponse> : BaseRequestHandler, IStreamHandler public class RestDeserialiseHandler<TRequest, TResponse> : BaseOutputStreamHandler, IStreamHandler
where TRequest : new() where TRequest : new()
{ {
private RestDeserialiseMethod<TRequest, TResponse> m_method; private RestDeserialiseMethod<TRequest, TResponse> m_method;
@ -48,7 +48,7 @@ namespace OpenSim.Framework.Servers.HttpServer
m_method = method; m_method = method;
} }
public void Handle(string path, Stream request, Stream responseStream, protected override void ProcessRequest(string path, Stream request, Stream responseStream,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
TRequest deserial; TRequest deserial;

View File

@ -183,7 +183,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public delegate bool CheckIdentityMethod(string sid, string aid); public delegate bool CheckIdentityMethod(string sid, string aid);
public class RestDeserialiseSecureHandler<TRequest, TResponse> : BaseRequestHandler, IStreamHandler public class RestDeserialiseSecureHandler<TRequest, TResponse> : BaseOutputStreamHandler, IStreamHandler
where TRequest : new() where TRequest : new()
{ {
private static readonly ILog m_log private static readonly ILog m_log
@ -201,7 +201,7 @@ namespace OpenSim.Framework.Servers.HttpServer
m_method = method; m_method = method;
} }
public void Handle(string path, Stream request, Stream responseStream, protected override void ProcessRequest(string path, Stream request, Stream responseStream,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
RestSessionObject<TRequest> deserial = default(RestSessionObject<TRequest>); RestSessionObject<TRequest> deserial = default(RestSessionObject<TRequest>);
@ -237,7 +237,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public delegate bool CheckTrustedSourceMethod(IPEndPoint peer); public delegate bool CheckTrustedSourceMethod(IPEndPoint peer);
public class RestDeserialiseTrustedHandler<TRequest, TResponse> : BaseRequestHandler, IStreamHandler public class RestDeserialiseTrustedHandler<TRequest, TResponse> : BaseOutputStreamHandler, IStreamHandler
where TRequest : new() where TRequest : new()
{ {
private static readonly ILog m_log private static readonly ILog m_log
@ -260,7 +260,7 @@ namespace OpenSim.Framework.Servers.HttpServer
m_method = method; m_method = method;
} }
public void Handle(string path, Stream request, Stream responseStream, protected override void ProcessRequest(string path, Stream request, Stream responseStream,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
TRequest deserial = default(TRequest); TRequest deserial = default(TRequest);
@ -293,5 +293,4 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
} }
} }
} }

View File

@ -48,7 +48,7 @@ namespace OpenSim.Framework.Servers.HttpServer
m_restMethod = restMethod; m_restMethod = restMethod;
} }
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
Encoding encoding = Encoding.UTF8; Encoding encoding = Encoding.UTF8;
StreamReader streamReader = new StreamReader(request, encoding); StreamReader streamReader = new StreamReader(request, encoding);

View File

@ -141,6 +141,11 @@ namespace OpenSim.Framework
public static FireAndForgetMethod DefaultFireAndForgetMethod = FireAndForgetMethod.SmartThreadPool; public static FireAndForgetMethod DefaultFireAndForgetMethod = FireAndForgetMethod.SmartThreadPool;
public static FireAndForgetMethod FireAndForgetMethod = DefaultFireAndForgetMethod; public static FireAndForgetMethod FireAndForgetMethod = DefaultFireAndForgetMethod;
public static bool IsPlatformMono
{
get { return Type.GetType("Mono.Runtime") != null; }
}
/// <summary> /// <summary>
/// Gets the name of the directory where the current running executable /// Gets the name of the directory where the current running executable
/// is located /// is located
@ -1338,7 +1343,7 @@ namespace OpenSim.Framework
ru = "OSX/Mono"; ru = "OSX/Mono";
else else
{ {
if (Type.GetType("Mono.Runtime") != null) if (IsPlatformMono)
ru = "Win/Mono"; ru = "Win/Mono";
else else
ru = "Win/.NET"; ru = "Win/.NET";

View File

@ -843,73 +843,49 @@ namespace OpenSim
/// <summary> /// <summary>
/// Handler to supply the current status of this sim /// Handler to supply the current status of this sim
/// </summary> /// </summary>
/// <remarks>
/// Currently this is always OK if the simulator is still listening for connections on its HTTP service /// Currently this is always OK if the simulator is still listening for connections on its HTTP service
public class SimStatusHandler : IStreamedRequestHandler /// </remarks>
public class SimStatusHandler : BaseStreamHandler
{ {
public byte[] Handle(string path, Stream request, public SimStatusHandler() : base("GET", "/simstatus", "SimStatus", "Simulator Status") {}
protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
return Util.UTF8.GetBytes("OK"); return Util.UTF8.GetBytes("OK");
} }
public string Name { get { return "SimStatus"; } } public override string ContentType
public string Description { get { return "Simulator Status"; } }
public string ContentType
{ {
get { return "text/plain"; } get { return "text/plain"; }
} }
public string HttpMethod
{
get { return "GET"; }
}
public string Path
{
get { return "/simstatus"; }
}
} }
/// <summary> /// <summary>
/// Handler to supply the current extended status of this sim /// Handler to supply the current extended status of this sim
/// Sends the statistical data in a json serialization /// Sends the statistical data in a json serialization
/// </summary> /// </summary>
public class XSimStatusHandler : IStreamedRequestHandler public class XSimStatusHandler : BaseStreamHandler
{ {
OpenSimBase m_opensim; OpenSimBase m_opensim;
string osXStatsURI = String.Empty;
public string Name { get { return "XSimStatus"; } }
public string Description { get { return "Simulator XStatus"; } }
public XSimStatusHandler(OpenSimBase sim) public XSimStatusHandler(OpenSimBase sim)
: base("GET", "/" + Util.SHA1Hash(sim.osSecret), "XSimStatus", "Simulator XStatus")
{ {
m_opensim = sim; m_opensim = sim;
osXStatsURI = Util.SHA1Hash(sim.osSecret);
} }
public byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
return Util.UTF8.GetBytes(m_opensim.StatReport(httpRequest)); return Util.UTF8.GetBytes(m_opensim.StatReport(httpRequest));
} }
public string ContentType public override string ContentType
{ {
get { return "text/plain"; } get { return "text/plain"; }
} }
public string HttpMethod
{
get { return "GET"; }
}
public string Path
{
// This is for the OpenSimulator instance and is the osSecret hashed
get { return "/" + osXStatsURI; }
}
} }
/// <summary> /// <summary>
@ -918,42 +894,26 @@ namespace OpenSim
/// If the request contains a key, "callback" the response will be wrappend in the /// If the request contains a key, "callback" the response will be wrappend in the
/// associated value for jsonp used with ajax/javascript /// associated value for jsonp used with ajax/javascript
/// </summary> /// </summary>
public class UXSimStatusHandler : IStreamedRequestHandler protected class UXSimStatusHandler : BaseStreamHandler
{ {
OpenSimBase m_opensim; OpenSimBase m_opensim;
string osUXStatsURI = String.Empty;
public string Name { get { return "UXSimStatus"; } }
public string Description { get { return "Simulator UXStatus"; } }
public UXSimStatusHandler(OpenSimBase sim) public UXSimStatusHandler(OpenSimBase sim)
: base("GET", "/" + sim.userStatsURI, "UXSimStatus", "Simulator UXStatus")
{ {
m_opensim = sim; m_opensim = sim;
osUXStatsURI = sim.userStatsURI;
} }
public byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
return Util.UTF8.GetBytes(m_opensim.StatReport(httpRequest)); return Util.UTF8.GetBytes(m_opensim.StatReport(httpRequest));
} }
public string ContentType public override string ContentType
{ {
get { return "text/plain"; } get { return "text/plain"; }
} }
public string HttpMethod
{
get { return "GET"; }
}
public string Path
{
// This is for the OpenSimulator instance and is the user provided URI
get { return "/" + osUXStatsURI; }
}
} }
#endregion #endregion

View File

@ -282,13 +282,19 @@ namespace OpenSim.Region.ClientStack.Linden
m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler("POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData);
IRequestHandler getObjectPhysicsDataHandler
= new RestStreamHandler(
"POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData, "GetObjectPhysicsData", null);
m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler); m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost); IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost);
m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler); m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler);
IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler("POST", capsBase + m_ResourceCostSelectedPath, ResourceCostSelected); IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler("POST", capsBase + m_ResourceCostSelectedPath, ResourceCostSelected);
m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler); m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
IRequestHandler UpdateAgentInformationHandler = new RestStreamHandler("POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation);
IRequestHandler UpdateAgentInformationHandler
= new RestStreamHandler(
"POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation, "UpdateAgentInformation", null);
m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler); m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler);
m_HostCapsObj.RegisterHandler( m_HostCapsObj.RegisterHandler(

View File

@ -366,7 +366,8 @@ namespace OpenSim.Region.ClientStack.Linden
// EventQueueGet when it receive capability information, but then we replace the rest handler immediately // EventQueueGet when it receive capability information, but then we replace the rest handler immediately
// afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but
// really it should be possible to directly register the poll handler as a capability. // really it should be possible to directly register the poll handler as a capability.
caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null)); caps.RegisterHandler(
"EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null, "EventQueueGet", null));
// delegate(Hashtable m_dhttpMethod) // delegate(Hashtable m_dhttpMethod)
// { // {
// return ProcessQueue(m_dhttpMethod, agentID, caps); // return ProcessQueue(m_dhttpMethod, agentID, caps);

View File

@ -183,7 +183,7 @@ namespace OpenSim.Region.ClientStack.Linden
m_isGod = m_scene.Permissions.IsGod(agentID); m_isGod = m_scene.Permissions.IsGod(agentID);
} }
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader reader = new StreamReader(request); StreamReader reader = new StreamReader(request);
string message = reader.ReadToEnd(); string message = reader.ReadToEnd();

View File

@ -349,6 +349,8 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
while (true) while (true)
{ {
Watchdog.UpdateThread();
aPollRequest poolreq = m_queue.Dequeue(); aPollRequest poolreq = m_queue.Dequeue();
poolreq.thepoll.Process(poolreq); poolreq.thepoll.Process(poolreq);

View File

@ -710,12 +710,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//there is a local handler for this packet type //there is a local handler for this packet type
if (pprocessor.Async) if (pprocessor.Async)
{ {
ClientInfo cinfo = UDPClient.GetClientInfo();
if (!cinfo.AsyncRequests.ContainsKey(packet.Type.ToString()))
cinfo.AsyncRequests[packet.Type.ToString()] = 0;
cinfo.AsyncRequests[packet.Type.ToString()]++;
object obj = new AsyncPacketProcess(this, pprocessor.method, packet); object obj = new AsyncPacketProcess(this, pprocessor.method, packet);
Util.FireAndForget(ProcessSpecificPacketAsync, obj); Util.FireAndForget(ProcessSpecificPacketAsync, obj);
result = true; result = true;
} }
else else
{ {
ClientInfo cinfo = UDPClient.GetClientInfo();
if (!cinfo.SyncRequests.ContainsKey(packet.Type.ToString()))
cinfo.SyncRequests[packet.Type.ToString()] = 0;
cinfo.SyncRequests[packet.Type.ToString()]++;
result = pprocessor.method(this, packet); result = pprocessor.method(this, packet);
} }
} }
@ -730,6 +740,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
if (found) if (found)
{ {
ClientInfo cinfo = UDPClient.GetClientInfo();
if (!cinfo.GenericRequests.ContainsKey(packet.Type.ToString()))
cinfo.GenericRequests[packet.Type.ToString()] = 0;
cinfo.GenericRequests[packet.Type.ToString()]++;
result = method(this, packet); result = method(this, packet);
} }
} }
@ -5376,7 +5391,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject); AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject);
AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject); AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject);
AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand); AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand);
AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply); AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, false);
AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest); AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest);
AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance); AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance);
AddLocalPacketHandler(PacketType.AgentIsNowWearing, HandlerAgentIsNowWearing); AddLocalPacketHandler(PacketType.AgentIsNowWearing, HandlerAgentIsNowWearing);
@ -5437,8 +5452,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AddLocalPacketHandler(PacketType.ScriptAnswerYes, HandleScriptAnswerYes, false); AddLocalPacketHandler(PacketType.ScriptAnswerYes, HandleScriptAnswerYes, false);
AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false); AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false);
AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false); AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false);
AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage); AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage, false);
AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest); AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest, false);
AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest); AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest);
AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer); AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer);
AddLocalPacketHandler(PacketType.SendXferPacket, HandleSendXferPacket); AddLocalPacketHandler(PacketType.SendXferPacket, HandleSendXferPacket);
@ -5470,7 +5485,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel); AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel);
AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest); AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest);
AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest, false); AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest, false);
AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest); AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest, false);
AddLocalPacketHandler(PacketType.ParcelInfoRequest, HandleParcelInfoRequest); AddLocalPacketHandler(PacketType.ParcelInfoRequest, HandleParcelInfoRequest);
AddLocalPacketHandler(PacketType.ParcelAccessListRequest, HandleParcelAccessListRequest, false); AddLocalPacketHandler(PacketType.ParcelAccessListRequest, HandleParcelAccessListRequest, false);
AddLocalPacketHandler(PacketType.ParcelAccessListUpdate, HandleParcelAccessListUpdate, false); AddLocalPacketHandler(PacketType.ParcelAccessListUpdate, HandleParcelAccessListUpdate, false);
@ -7868,14 +7883,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request"); //m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request");
TransferRequestPacket transfer = (TransferRequestPacket)Pack; TransferRequestPacket transfer = (TransferRequestPacket)Pack;
//m_log.Debug("Transfer Request: " + transfer.ToString());
// Validate inventory transfers
// Has to be done here, because AssetCache can't do it
//
UUID taskID = UUID.Zero; UUID taskID = UUID.Zero;
if (transfer.TransferInfo.SourceType == (int)SourceType.SimInventoryItem) if (transfer.TransferInfo.SourceType == (int)SourceType.SimInventoryItem)
{ {
taskID = new UUID(transfer.TransferInfo.Params, 48); if (!(((Scene)m_scene).Permissions.BypassPermissions()))
{
// We're spawning a thread because the permissions check can block this thread
Util.FireAndForget(delegate
{
// This requests the asset if needed
HandleSimInventoryTransferRequestWithPermsCheck(sender, transfer);
});
return true;
}
}
else if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
{
//TransferRequestPacket does not include covenant uuid?
//get scene covenant uuid
taskID = m_scene.RegionInfo.RegionSettings.Covenant;
}
// This is non-blocking
MakeAssetRequest(transfer, taskID);
return true;
}
private void HandleSimInventoryTransferRequestWithPermsCheck(IClientAPI sender, TransferRequestPacket transfer)
{
UUID taskID = new UUID(transfer.TransferInfo.Params, 48);
UUID itemID = new UUID(transfer.TransferInfo.Params, 64); UUID itemID = new UUID(transfer.TransferInfo.Params, 64);
UUID requestID = new UUID(transfer.TransferInfo.Params, 80); UUID requestID = new UUID(transfer.TransferInfo.Params, 80);
@ -7883,8 +7920,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}", // "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
// requestID, itemID, taskID, Name); // requestID, itemID, taskID, Name);
if (!(((Scene)m_scene).Permissions.BypassPermissions())) //m_log.Debug("Transfer Request: " + transfer.ToString());
{ // Validate inventory transfers
// Has to be done here, because AssetCache can't do it
//
if (taskID != UUID.Zero) // Prim if (taskID != UUID.Zero) // Prim
{ {
SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID); SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID);
@ -7894,7 +7933,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.WarnFormat( m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist", "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist",
Name, requestID, itemID, taskID); Name, requestID, itemID, taskID);
return true; return;
} }
TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID); TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID);
@ -7903,18 +7942,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.WarnFormat( m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist", "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist",
Name, requestID, itemID, taskID); Name, requestID, itemID, taskID);
return true; return;
} }
if (tii.Type == (int)AssetType.LSLText) if (tii.Type == (int)AssetType.LSLText)
{ {
if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId)) if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId))
return true; return;
} }
else if (tii.Type == (int)AssetType.Notecard) else if (tii.Type == (int)AssetType.Notecard)
{ {
if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId)) if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId))
return true; return;
} }
else else
{ {
@ -7925,7 +7964,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.WarnFormat( m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}", "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}",
Name, requestID, itemID, taskID, part.OwnerID); Name, requestID, itemID, taskID, part.OwnerID);
return true; return;
} }
if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0)
@ -7933,7 +7972,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.WarnFormat( m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set", "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set",
Name, requestID, itemID, taskID); Name, requestID, itemID, taskID);
return true; return;
} }
if (tii.OwnerID != AgentId) if (tii.OwnerID != AgentId)
@ -7941,7 +7980,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.WarnFormat( m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}", "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}",
Name, requestID, itemID, taskID, tii.OwnerID); Name, requestID, itemID, taskID, tii.OwnerID);
return true; return;
} }
if (( if ((
@ -7951,7 +7990,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.WarnFormat( m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer", "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer",
Name, requestID, itemID, taskID); Name, requestID, itemID, taskID);
return true; return;
} }
if (tii.AssetID != requestID) if (tii.AssetID != requestID)
@ -7959,7 +7998,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.WarnFormat( m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}", "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}",
Name, requestID, itemID, taskID, tii.AssetID); Name, requestID, itemID, taskID, tii.AssetID);
return true; return;
} }
} }
} }
@ -7969,28 +8008,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (invAccess != null) if (invAccess != null)
{ {
if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID)) if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID))
return false; return;
} }
else else
{ {
return false; return;
} }
} }
}
}
else
if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
{
//TransferRequestPacket does not include covenant uuid?
//get scene covenant uuid
taskID = m_scene.RegionInfo.RegionSettings.Covenant;
}
// Permissions out of the way, let's request the asset
MakeAssetRequest(transfer, taskID); MakeAssetRequest(transfer, taskID);
return true;
} }
private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack) private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack)
{ {
AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack; AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
@ -12378,6 +12409,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ClientInfo info = m_udpClient.GetClientInfo(); ClientInfo info = m_udpClient.GetClientInfo();
info.proxyEP = null; info.proxyEP = null;
if (info.agentcircuit == null)
info.agentcircuit = RequestClientInfo(); info.agentcircuit = RequestClientInfo();
return info; return info;

View File

@ -160,6 +160,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private int m_maxRTO = 60000; private int m_maxRTO = 60000;
public bool m_deliverPackets = true; public bool m_deliverPackets = true;
private ClientInfo m_info = new ClientInfo();
/// <summary> /// <summary>
/// Default constructor /// Default constructor
/// </summary> /// </summary>
@ -241,20 +243,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// TODO: This data structure is wrong in so many ways. Locking and copying the entire lists // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists
// of pending and needed ACKs for every client every time some method wants information about // of pending and needed ACKs for every client every time some method wants information about
// this connection is a recipe for poor performance // this connection is a recipe for poor performance
ClientInfo info = new ClientInfo();
info.pendingAcks = new Dictionary<uint, uint>();
info.needAck = new Dictionary<uint, byte[]>();
info.resendThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate; m_info.resendThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate;
info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; m_info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate;
info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; m_info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate;
info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; m_info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate;
info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; m_info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate;
info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate;
info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate;
info.totalThrottle = (int)m_throttleCategory.DripRate; m_info.totalThrottle = (int)m_throttleCategory.DripRate;
return info; return m_info;
} }
/// <summary> /// <summary>

View File

@ -1686,6 +1686,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
IncomingPacket incomingPacket = null; IncomingPacket incomingPacket = null;
/*
// HACK: This is a test to try and rate limit packet handling on Mono. // HACK: This is a test to try and rate limit packet handling on Mono.
// If it works, a more elegant solution can be devised // If it works, a more elegant solution can be devised
if (Util.FireAndForgetCount() < 2) if (Util.FireAndForgetCount() < 2)
@ -1693,6 +1694,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//m_log.Debug("[LLUDPSERVER]: Incoming packet handler is sleeping"); //m_log.Debug("[LLUDPSERVER]: Incoming packet handler is sleeping");
Thread.Sleep(30); Thread.Sleep(30);
} }
*/
if (packetInbox.Dequeue(100, ref incomingPacket)) if (packetInbox.Dequeue(100, ref incomingPacket))
{ {

View File

@ -73,7 +73,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
} }
[SetUp] [SetUp]
public void SetUp() public override void SetUp()
{ {
base.SetUp(); base.SetUp();

View File

@ -498,7 +498,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
{ {
m_log.DebugFormat("[FRIENDS]: Entering StatusNotify for {0}", userID); //m_log.DebugFormat("[FRIENDS]: Entering StatusNotify for {0}", userID);
List<string> friendStringIds = friendList.ConvertAll<string>(friend => friend.Friend); List<string> friendStringIds = friendList.ConvertAll<string>(friend => friend.Friend);
List<string> remoteFriendStringIds = new List<string>(); List<string> remoteFriendStringIds = new List<string>();
@ -527,15 +527,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// let's guard against sessions-gone-bad // let's guard against sessions-gone-bad
if (friendSession != null && friendSession.RegionID != UUID.Zero) if (friendSession != null && friendSession.RegionID != UUID.Zero)
{ {
m_log.DebugFormat("[FRIENDS]: Get region {0}", friendSession.RegionID); //m_log.DebugFormat("[FRIENDS]: Get region {0}", friendSession.RegionID);
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
if (region != null) if (region != null)
{ {
m_FriendsSimConnector.StatusNotify(region, userID, friendSession.UserID, online); m_FriendsSimConnector.StatusNotify(region, userID, friendSession.UserID, online);
} }
} }
else //else
m_log.DebugFormat("[FRIENDS]: friend session is null or the region is UUID.Zero"); // m_log.DebugFormat("[FRIENDS]: friend session is null or the region is UUID.Zero");
} }
} }

View File

@ -54,7 +54,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
m_FriendsModule = fmodule; m_FriendsModule = fmodule;
} }
public override byte[] Handle( protected override byte[] ProcessRequest(
string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); StreamReader sr = new StreamReader(requestData);

View File

@ -252,7 +252,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
{ {
m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID); //m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID);
// First, let's divide the friends on a per-domain basis // First, let's divide the friends on a per-domain basis
Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>(); Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>();

View File

@ -125,9 +125,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
{ {
string uri = "/CAPS/" + UUID.Random(); string uri = "/CAPS/" + UUID.Random();
caps.RegisterHandler("UntrustedSimulatorMessage", caps.RegisterHandler(
new RestStreamHandler("POST", uri, "UntrustedSimulatorMessage",
HandleUntrustedSimulatorMessage)); new RestStreamHandler("POST", uri, HandleUntrustedSimulatorMessage, "UntrustedSimulatorMessage", null));
} }
private string HandleUntrustedSimulatorMessage(string request, private string HandleUntrustedSimulatorMessage(string request,

View File

@ -67,10 +67,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// </summary> /// </summary>
protected bool m_merge; protected bool m_merge;
/// <value> protected IInventoryService m_InventoryService;
/// We only use this to request modules protected IAssetService m_AssetService;
/// </value> protected IUserAccountService m_UserAccountService;
protected Scene m_scene;
/// <value> /// <value>
/// The stream from which the inventory archive will be loaded. /// The stream from which the inventory archive will be loaded.
@ -118,9 +117,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>(); protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>();
public InventoryArchiveReadRequest( public InventoryArchiveReadRequest(
Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge) IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge)
: this( : this(
scene, inv,
assets,
uacc,
userInfo, userInfo,
invPath, invPath,
new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress), new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress),
@ -129,9 +130,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
} }
public InventoryArchiveReadRequest( public InventoryArchiveReadRequest(
Scene scene, UserAccount userInfo, string invPath, Stream loadStream, bool merge) IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, Stream loadStream, bool merge)
{ {
m_scene = scene; m_InventoryService = inv;
m_AssetService = assets;
m_UserAccountService = uacc;
m_merge = merge; m_merge = merge;
m_userInfo = userInfo; m_userInfo = userInfo;
m_invPath = invPath; m_invPath = invPath;
@ -162,7 +165,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
List<InventoryFolderBase> folderCandidates List<InventoryFolderBase> folderCandidates
= InventoryArchiveUtils.FindFoldersByPath( = InventoryArchiveUtils.FindFoldersByPath(
m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath); m_InventoryService, m_userInfo.PrincipalID, m_invPath);
if (folderCandidates.Count == 0) if (folderCandidates.Count == 0)
{ {
@ -297,7 +300,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath); string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath);
List<InventoryFolderBase> folderCandidates List<InventoryFolderBase> folderCandidates
= InventoryArchiveUtils.FindFoldersByPath( = InventoryArchiveUtils.FindFoldersByPath(
m_scene.InventoryService, m_userInfo.PrincipalID, plainPath); m_InventoryService, m_userInfo.PrincipalID, plainPath);
if (folderCandidates.Count != 0) if (folderCandidates.Count != 0)
{ {
@ -380,7 +383,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
= new InventoryFolderBase( = new InventoryFolderBase(
newFolderId, newFolderName, m_userInfo.PrincipalID, newFolderId, newFolderName, m_userInfo.PrincipalID,
(short)AssetType.Unknown, destFolder.ID, 1); (short)AssetType.Unknown, destFolder.ID, 1);
m_scene.InventoryService.AddFolder(destFolder); m_InventoryService.AddFolder(destFolder);
// Record that we have now created this folder // Record that we have now created this folder
iarPathExisting += rawDirsToCreate[i] + "/"; iarPathExisting += rawDirsToCreate[i] + "/";
@ -406,7 +409,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
// Don't use the item ID that's in the file // Don't use the item ID that's in the file
item.ID = UUID.Random(); item.ID = UUID.Random();
UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService); UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_UserAccountService);
if (UUID.Zero != ospResolvedId) // The user exists in this grid if (UUID.Zero != ospResolvedId) // The user exists in this grid
{ {
// m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId); // m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId);
@ -436,7 +439,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
// relying on native tar tools. // relying on native tar tools.
m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid; m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid;
m_scene.AddInventoryItem(item); if (!m_InventoryService.AddItem(item))
m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}", item.Name, item.Folder);
return item; return item;
} }
@ -533,7 +537,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString()); AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString());
asset.Data = data; asset.Data = data;
m_scene.AssetService.Store(asset); m_AssetService.Store(asset);
return true; return true;
} }

View File

@ -294,7 +294,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
try try
{ {
request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge); request = new InventoryArchiveReadRequest(m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadStream, merge);
} }
catch (EntryPointNotFoundException e) catch (EntryPointNotFoundException e)
{ {
@ -342,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
try try
{ {
request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge); request = new InventoryArchiveReadRequest(m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadPath, merge);
} }
catch (EntryPointNotFoundException e) catch (EntryPointNotFoundException e)
{ {

View File

@ -229,7 +229,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{ {
// Test replication of path1 // Test replication of path1
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory( .ReplicateArchivePathToUserInventory(
iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID), iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
foldersCreated, nodesLoaded); foldersCreated, nodesLoaded);
@ -246,7 +246,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{ {
// Test replication of path2 // Test replication of path2
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory( .ReplicateArchivePathToUserInventory(
iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID), iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
foldersCreated, nodesLoaded); foldersCreated, nodesLoaded);
@ -292,7 +292,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory( .ReplicateArchivePathToUserInventory(
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
@ -343,7 +343,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
new InventoryArchiveReadRequest(scene, ua1, folder1ExistingName, (Stream)null, true) new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, folder1ExistingName, (Stream)null, true)
.ReplicateArchivePathToUserInventory( .ReplicateArchivePathToUserInventory(
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());

View File

@ -86,7 +86,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
InventoryArchiveReadRequest iarr InventoryArchiveReadRequest iarr
= new InventoryArchiveReadRequest(null, null, null, (Stream)null, false); = new InventoryArchiveReadRequest(null, null, null, null, null, (Stream)null, false);
iarr.LoadControlFile(filePath, data); iarr.LoadControlFile(filePath, data);
Assert.That(iarr.ControlFileLoaded, Is.True); Assert.That(iarr.ControlFileLoaded, Is.True);

View File

@ -173,7 +173,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
if(obj.PresenceType == PresenceType.Npc) if(obj.PresenceType == PresenceType.Npc)
return; return;
Util.FireAndForget(delegate
{
GetImageAssets(((IScenePresence)obj).UUID); GetImageAssets(((IScenePresence)obj).UUID);
});
} }
/// <summary> /// <summary>
@ -1044,12 +1047,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
{ {
OSDString assetId = (OSDString)asset; OSDString assetId = (OSDString)asset;
Scene.AssetService.Get(string.Format("{0}/{1}",assetServerURI, assetId.AsString()), this, Scene.AssetService.Get(string.Format("{0}/{1}",assetServerURI, assetId.AsString()));
delegate (string assetID, Object s, AssetBase a)
{
// m_log.DebugFormat("[PROFILES]: Getting Image Assets {0}", assetID);
return;
});
} }
return true; return true;
} }

View File

@ -28,6 +28,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using log4net; using log4net;
@ -37,6 +38,7 @@ using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using Caps=OpenSim.Framework.Capabilities.Caps; using Caps=OpenSim.Framework.Capabilities.Caps;
@ -57,8 +59,9 @@ namespace OpenSim.Region.CoreModules.Framework
/// </summary> /// </summary>
protected Dictionary<uint, Caps> m_capsObjects = new Dictionary<uint, Caps>(); protected Dictionary<uint, Caps> m_capsObjects = new Dictionary<uint, Caps>();
protected Dictionary<UUID, string> capsPaths = new Dictionary<UUID, string>(); protected Dictionary<UUID, string> m_capsPaths = new Dictionary<UUID, string>();
protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds
protected Dictionary<UUID, Dictionary<ulong, string>> m_childrenSeeds
= new Dictionary<UUID, Dictionary<ulong, string>>(); = new Dictionary<UUID, Dictionary<ulong, string>>();
public void Initialise(IConfigSource source) public void Initialise(IConfigSource source)
@ -70,9 +73,24 @@ namespace OpenSim.Region.CoreModules.Framework
m_scene = scene; m_scene = scene;
m_scene.RegisterModuleInterface<ICapabilitiesModule>(this); m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
MainConsole.Instance.Commands.AddCommand("Comms", false, "show caps", MainConsole.Instance.Commands.AddCommand(
"show caps", "Comms", false, "show caps list",
"Shows all registered capabilities for users", HandleShowCapsCommand); "show caps list",
"Shows list of registered capabilities for users.", HandleShowCapsListCommand);
MainConsole.Instance.Commands.AddCommand(
"Comms", false, "show caps stats by user",
"show caps stats [<first-name> <last-name>]",
"Shows statistics on capabilities use by user.",
"If a user name is given, then prints a detailed breakdown of caps use ordered by number of requests received.",
HandleShowCapsStatsByUserCommand);
MainConsole.Instance.Commands.AddCommand(
"Comms", false, "show caps stats by cap",
"show caps stats by cap [<cap-name>]",
"Shows statistics on capabilities use by capability.",
"If a capability name is given, then prints a detailed breakdown of use by each user.",
HandleShowCapsStatsByCapCommand);
} }
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)
@ -106,6 +124,7 @@ namespace OpenSim.Region.CoreModules.Framework
if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags)) if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags))
return; return;
Caps caps;
String capsObjectPath = GetCapsPath(agentId); String capsObjectPath = GetCapsPath(agentId);
if (m_capsObjects.ContainsKey(circuitCode)) if (m_capsObjects.ContainsKey(circuitCode))
@ -121,7 +140,7 @@ namespace OpenSim.Region.CoreModules.Framework
//return; //return;
} }
Caps caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName, caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName,
(MainServer.Instance == null) ? 0: MainServer.Instance.Port, (MainServer.Instance == null) ? 0: MainServer.Instance.Port,
capsObjectPath, agentId, m_scene.RegionInfo.RegionName); capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
@ -132,9 +151,12 @@ namespace OpenSim.Region.CoreModules.Framework
public void RemoveCaps(UUID agentId, uint circuitCode) public void RemoveCaps(UUID agentId, uint circuitCode)
{ {
if (childrenSeeds.ContainsKey(agentId)) lock (m_childrenSeeds)
{ {
childrenSeeds.Remove(agentId); if (m_childrenSeeds.ContainsKey(agentId))
{
m_childrenSeeds.Remove(agentId);
}
} }
lock (m_capsObjects) lock (m_capsObjects)
@ -180,16 +202,22 @@ namespace OpenSim.Region.CoreModules.Framework
public void SetAgentCapsSeeds(AgentCircuitData agent) public void SetAgentCapsSeeds(AgentCircuitData agent)
{ {
capsPaths[agent.AgentID] = agent.CapsPath; lock (m_capsPaths)
childrenSeeds[agent.AgentID] m_capsPaths[agent.AgentID] = agent.CapsPath;
lock (m_childrenSeeds)
m_childrenSeeds[agent.AgentID]
= ((agent.ChildrenCapSeeds == null) ? new Dictionary<ulong, string>() : agent.ChildrenCapSeeds); = ((agent.ChildrenCapSeeds == null) ? new Dictionary<ulong, string>() : agent.ChildrenCapSeeds);
} }
public string GetCapsPath(UUID agentId) public string GetCapsPath(UUID agentId)
{ {
if (capsPaths.ContainsKey(agentId)) lock (m_capsPaths)
{ {
return capsPaths[agentId]; if (m_capsPaths.ContainsKey(agentId))
{
return m_capsPaths[agentId];
}
} }
return null; return null;
@ -198,42 +226,59 @@ namespace OpenSim.Region.CoreModules.Framework
public Dictionary<ulong, string> GetChildrenSeeds(UUID agentID) public Dictionary<ulong, string> GetChildrenSeeds(UUID agentID)
{ {
Dictionary<ulong, string> seeds = null; Dictionary<ulong, string> seeds = null;
if (childrenSeeds.TryGetValue(agentID, out seeds))
lock (m_childrenSeeds)
if (m_childrenSeeds.TryGetValue(agentID, out seeds))
return seeds; return seeds;
return new Dictionary<ulong, string>(); return new Dictionary<ulong, string>();
} }
public void DropChildSeed(UUID agentID, ulong handle) public void DropChildSeed(UUID agentID, ulong handle)
{ {
Dictionary<ulong, string> seeds; Dictionary<ulong, string> seeds;
if (childrenSeeds.TryGetValue(agentID, out seeds))
lock (m_childrenSeeds)
{
if (m_childrenSeeds.TryGetValue(agentID, out seeds))
{ {
seeds.Remove(handle); seeds.Remove(handle);
} }
} }
}
public string GetChildSeed(UUID agentID, ulong handle) public string GetChildSeed(UUID agentID, ulong handle)
{ {
Dictionary<ulong, string> seeds; Dictionary<ulong, string> seeds;
string returnval; string returnval;
if (childrenSeeds.TryGetValue(agentID, out seeds))
lock (m_childrenSeeds)
{
if (m_childrenSeeds.TryGetValue(agentID, out seeds))
{ {
if (seeds.TryGetValue(handle, out returnval)) if (seeds.TryGetValue(handle, out returnval))
return returnval; return returnval;
} }
}
return null; return null;
} }
public void SetChildrenSeed(UUID agentID, Dictionary<ulong, string> seeds) public void SetChildrenSeed(UUID agentID, Dictionary<ulong, string> seeds)
{ {
//m_log.DebugFormat(" !!! Setting child seeds in {0} to {1}", m_scene.RegionInfo.RegionName, seeds.Count); //m_log.DebugFormat(" !!! Setting child seeds in {0} to {1}", m_scene.RegionInfo.RegionName, seeds.Count);
childrenSeeds[agentID] = seeds;
lock (m_childrenSeeds)
m_childrenSeeds[agentID] = seeds;
} }
public void DumpChildrenSeeds(UUID agentID) public void DumpChildrenSeeds(UUID agentID)
{ {
m_log.Info("================ ChildrenSeed "+m_scene.RegionInfo.RegionName+" ================"); m_log.Info("================ ChildrenSeed "+m_scene.RegionInfo.RegionName+" ================");
foreach (KeyValuePair<ulong, string> kvp in childrenSeeds[agentID])
lock (m_childrenSeeds)
{
foreach (KeyValuePair<ulong, string> kvp in m_childrenSeeds[agentID])
{ {
uint x, y; uint x, y;
Utils.LongToUInts(kvp.Key, out x, out y); Utils.LongToUInts(kvp.Key, out x, out y);
@ -242,15 +287,21 @@ namespace OpenSim.Region.CoreModules.Framework
m_log.Info(" >> "+x+", "+y+": "+kvp.Value); m_log.Info(" >> "+x+", "+y+": "+kvp.Value);
} }
} }
}
private void HandleShowCapsCommand(string module, string[] cmdparams) private void HandleShowCapsListCommand(string module, string[] cmdParams)
{ {
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
return;
StringBuilder caps = new StringBuilder(); StringBuilder caps = new StringBuilder();
caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
lock (m_capsObjects)
{
foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects) foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects)
{ {
caps.AppendFormat("** Circuit {0}:\n", kvp.Key); caps.AppendFormat("** User {0}:\n", kvp.Key);
for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); ) for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); )
{ {
@ -261,8 +312,222 @@ namespace OpenSim.Region.CoreModules.Framework
foreach (KeyValuePair<string, string> kvp3 in kvp.Value.ExternalCapsHandlers) foreach (KeyValuePair<string, string> kvp3 in kvp.Value.ExternalCapsHandlers)
caps.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value); caps.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value);
} }
}
MainConsole.Instance.Output(caps.ToString()); MainConsole.Instance.Output(caps.ToString());
} }
private void HandleShowCapsStatsByCapCommand(string module, string[] cmdParams)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
return;
if (cmdParams.Length != 5 && cmdParams.Length != 6)
{
MainConsole.Instance.Output("Usage: show caps stats by cap [<cap-name>]");
return;
}
StringBuilder sb = new StringBuilder();
sb.AppendFormat("Region {0}:\n", m_scene.Name);
if (cmdParams.Length == 5)
{
BuildSummaryStatsByCapReport(sb);
}
else if (cmdParams.Length == 6)
{
BuildDetailedStatsByCapReport(sb, cmdParams[5]);
}
MainConsole.Instance.Output(sb.ToString());
}
private void BuildDetailedStatsByCapReport(StringBuilder sb, string capName)
{
/*
sb.AppendFormat("Capability name {0}\n", capName);
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
cdt.AddColumn("User Name", 34);
cdt.AddColumn("Req Received", 12);
cdt.AddColumn("Req Handled", 12);
cdt.Indent = 2;
Dictionary<string, int> receivedStats = new Dictionary<string, int>();
Dictionary<string, int> handledStats = new Dictionary<string, int>();
m_scene.ForEachScenePresence(
sp =>
{
Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
if (caps == null)
return;
Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
IRequestHandler reqHandler;
if (capsHandlers.TryGetValue(capName, out reqHandler))
{
receivedStats[sp.Name] = reqHandler.RequestsReceived;
handledStats[sp.Name] = reqHandler.RequestsHandled;
}
}
);
foreach (KeyValuePair<string, int> kvp in receivedStats.OrderByDescending(kp => kp.Value))
{
cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]);
}
sb.Append(cdt.ToString());
*/
}
private void BuildSummaryStatsByCapReport(StringBuilder sb)
{
/*
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
cdt.AddColumn("Name", 34);
cdt.AddColumn("Req Received", 12);
cdt.AddColumn("Req Handled", 12);
cdt.Indent = 2;
Dictionary<string, int> receivedStats = new Dictionary<string, int>();
Dictionary<string, int> handledStats = new Dictionary<string, int>();
m_scene.ForEachScenePresence(
sp =>
{
Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
if (caps == null)
return;
Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
foreach (IRequestHandler reqHandler in capsHandlers.Values)
{
string reqName = reqHandler.Name ?? "";
if (!receivedStats.ContainsKey(reqName))
{
receivedStats[reqName] = reqHandler.RequestsReceived;
handledStats[reqName] = reqHandler.RequestsHandled;
}
else
{
receivedStats[reqName] += reqHandler.RequestsReceived;
handledStats[reqName] += reqHandler.RequestsHandled;
}
}
}
);
foreach (KeyValuePair<string, int> kvp in receivedStats.OrderByDescending(kp => kp.Value))
cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]);
sb.Append(cdt.ToString());
*/
}
private void HandleShowCapsStatsByUserCommand(string module, string[] cmdParams)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
return;
if (cmdParams.Length != 5 && cmdParams.Length != 7)
{
MainConsole.Instance.Output("Usage: show caps stats by user [<first-name> <last-name>]");
return;
}
StringBuilder sb = new StringBuilder();
sb.AppendFormat("Region {0}:\n", m_scene.Name);
if (cmdParams.Length == 5)
{
BuildSummaryStatsByUserReport(sb);
}
else if (cmdParams.Length == 7)
{
string firstName = cmdParams[5];
string lastName = cmdParams[6];
ScenePresence sp = m_scene.GetScenePresence(firstName, lastName);
if (sp == null)
return;
BuildDetailedStatsByUserReport(sb, sp);
}
MainConsole.Instance.Output(sb.ToString());
}
private void BuildDetailedStatsByUserReport(StringBuilder sb, ScenePresence sp)
{
/*
sb.AppendFormat("Avatar name {0}, type {1}\n", sp.Name, sp.IsChildAgent ? "child" : "root");
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
cdt.AddColumn("Cap Name", 34);
cdt.AddColumn("Req Received", 12);
cdt.AddColumn("Req Handled", 12);
cdt.Indent = 2;
Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
if (caps == null)
return;
Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
foreach (IRequestHandler reqHandler in capsHandlers.Values.OrderByDescending(rh => rh.RequestsReceived))
{
cdt.AddRow(reqHandler.Name, reqHandler.RequestsReceived, reqHandler.RequestsHandled);
}
sb.Append(cdt.ToString());
*/
}
private void BuildSummaryStatsByUserReport(StringBuilder sb)
{
/*
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
cdt.AddColumn("Name", 32);
cdt.AddColumn("Type", 5);
cdt.AddColumn("Req Received", 12);
cdt.AddColumn("Req Handled", 12);
cdt.Indent = 2;
m_scene.ForEachScenePresence(
sp =>
{
Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
if (caps == null)
return;
Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
int totalRequestsReceived = 0;
int totalRequestsHandled = 0;
foreach (IRequestHandler reqHandler in capsHandlers.Values)
{
totalRequestsReceived += reqHandler.RequestsReceived;
totalRequestsHandled += reqHandler.RequestsHandled;
}
cdt.AddRow(sp.Name, sp.IsChildAgent ? "child" : "root", totalRequestsReceived, totalRequestsHandled);
}
);
sb.Append(cdt.ToString());
*/
}
} }
} }

View File

@ -171,11 +171,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (!so.IsAttachment) if (!so.IsAttachment)
return; return;
if (so.Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar)) if (so.AttachedAvatar == UUID.Zero || Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar))
return; return;
// foreign user // foreign user
AgentCircuitData aCircuit = so.Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar); AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar);
if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
{ {
if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
@ -183,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
string url = aCircuit.ServiceURLs["AssetServerURI"].ToString(); string url = aCircuit.ServiceURLs["AssetServerURI"].ToString();
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachement {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachement {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url);
Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>();
HGUuidGatherer uuidGatherer = new HGUuidGatherer(so.Scene.AssetService, url); HGUuidGatherer uuidGatherer = new HGUuidGatherer(Scene.AssetService, url);
uuidGatherer.GatherAssetUuids(so, ids); uuidGatherer.GatherAssetUuids(so, ids);
foreach (KeyValuePair<UUID, AssetType> kvp in ids) foreach (KeyValuePair<UUID, AssetType> kvp in ids)

View File

@ -0,0 +1,163 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Scenes;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Region.CoreModules.Framework
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GridServiceThrottleModule")]
public class GridServiceThrottleModule : ISharedRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private readonly List<Scene> m_scenes = new List<Scene>();
private OpenSim.Framework.BlockingQueue<GridRegionRequest> m_RequestQueue = new OpenSim.Framework.BlockingQueue<GridRegionRequest>();
public void Initialise(IConfigSource config)
{
Watchdog.StartThread(
ProcessQueue,
"GridServiceRequestThread",
ThreadPriority.BelowNormal,
true,
false);
}
public void AddRegion(Scene scene)
{
lock (m_scenes)
{
m_scenes.Add(scene);
scene.EventManager.OnNewClient += OnNewClient;
}
}
public void RegionLoaded(Scene scene)
{
}
public void RemoveRegion(Scene scene)
{
lock (m_scenes)
{
m_scenes.Remove(scene);
scene.EventManager.OnNewClient -= OnNewClient;
}
}
void OnNewClient(IClientAPI client)
{
client.OnRegionHandleRequest += OnRegionHandleRequest;
}
public void PostInitialise()
{
}
public void Close()
{
}
public string Name
{
get { return "GridServiceThrottleModule"; }
}
public Type ReplaceableInterface
{
get { return null; }
}
public void OnRegionHandleRequest(IClientAPI client, UUID regionID)
{
//m_log.DebugFormat("[GRIDSERVICE THROTTLE]: RegionHandleRequest {0}", regionID);
ulong handle = 0;
if (IsLocalRegionHandle(regionID, out handle))
{
client.SendRegionHandle(regionID, handle);
return;
}
GridRegionRequest request = new GridRegionRequest(client, regionID);
m_RequestQueue.Enqueue(request);
}
private bool IsLocalRegionHandle(UUID regionID, out ulong regionHandle)
{
regionHandle = 0;
foreach (Scene s in m_scenes)
if (s.RegionInfo.RegionID == regionID)
{
regionHandle = s.RegionInfo.RegionHandle;
return true;
}
return false;
}
private void ProcessQueue()
{
while (true)
{
Watchdog.UpdateThread();
GridRegionRequest request = m_RequestQueue.Dequeue();
GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, request.regionID);
if (r != null && r.RegionHandle != 0)
request.client.SendRegionHandle(request.regionID, r.RegionHandle);
}
}
}
class GridRegionRequest
{
public IClientAPI client;
public UUID regionID;
public GridRegionRequest(IClientAPI c, UUID r)
{
client = c;
regionID = r;
}
}
}

View File

@ -135,7 +135,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (sp is ScenePresence) if (sp is ScenePresence)
{ {
AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId); AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId);
if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
{ {
if (m_RestrictInventoryAccessAbroad) if (m_RestrictInventoryAccessAbroad)
{ {

View File

@ -176,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName); m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName);
simpleName = GetInventoryPathFromName(simpleName); simpleName = GetInventoryPathFromName(simpleName);
InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName, false); InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, simpleName, iarFileName, false);
try try
{ {
HashSet<InventoryNodeBase> nodes = archread.Execute(); HashSet<InventoryNodeBase> nodes = archread.Execute();
@ -185,7 +185,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
// didn't find the subfolder with the given name; place it on the top // didn't find the subfolder with the given name; place it on the top
m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName); m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName);
archread.Close(); archread.Close();
archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false); archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, "/", iarFileName, false);
archread.Execute(); archread.Execute();
} }

View File

@ -58,7 +58,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
if (umanmod == Name) if (umanmod == Name)
{ {
m_Enabled = true; m_Enabled = true;
RegisterConsoleCmds(); Init();
m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name); m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name);
} }
} }

View File

@ -28,9 +28,11 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Threading;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.ClientStack.LindenUDP; using OpenSim.Region.ClientStack.LindenUDP;
using OpenSim.Region.Framework; using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
@ -57,6 +59,10 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
// The cache // The cache
protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>(); protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>();
// Throttle the name requests
private OpenSim.Framework.BlockingQueue<NameRequest> m_RequestQueue = new OpenSim.Framework.BlockingQueue<NameRequest>();
#region ISharedRegionModule #region ISharedRegionModule
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
@ -65,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
if (umanmod == Name) if (umanmod == Name)
{ {
m_Enabled = true; m_Enabled = true;
RegisterConsoleCmds(); Init();
m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name); m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name);
} }
} }
@ -160,16 +166,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
} }
else else
{ {
string[] names; NameRequest request = new NameRequest(remote_client, uuid);
bool foundRealName = TryGetUserNames(uuid, out names); m_RequestQueue.Enqueue(request);
if (names.Length == 2)
{
if (!foundRealName)
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], uuid, remote_client.Name);
remote_client.SendNameReply(uuid, names[0], names[1]);
}
} }
} }
@ -514,9 +513,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
return; return;
} }
//try update unknown users //try update unknown users, but don't update anyone else
//and creator's home URL's if (oldUser.FirstName == "Unknown" && !creatorData.Contains("Unknown"))
if ((oldUser.FirstName == "Unknown" && !creatorData.Contains("Unknown")) || (oldUser.HomeURL != null && !creatorData.StartsWith(oldUser.HomeURL)))
{ {
lock (m_UserCache) lock (m_UserCache)
m_UserCache.Remove(id); m_UserCache.Remove(id);
@ -597,6 +595,18 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
#endregion IUserManagement #endregion IUserManagement
protected void Init()
{
RegisterConsoleCmds();
Watchdog.StartThread(
ProcessQueue,
"NameRequestThread",
ThreadPriority.BelowNormal,
true,
false);
}
protected void RegisterConsoleCmds() protected void RegisterConsoleCmds()
{ {
MainConsole.Instance.Commands.AddCommand("Users", true, MainConsole.Instance.Commands.AddCommand("Users", true,
@ -663,5 +673,40 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
MainConsole.Instance.Output(cdt.ToString()); MainConsole.Instance.Output(cdt.ToString());
} }
private void ProcessQueue()
{
while (true)
{
Watchdog.UpdateThread();
NameRequest request = m_RequestQueue.Dequeue();
string[] names;
bool foundRealName = TryGetUserNames(request.uuid, out names);
if (names.Length == 2)
{
if (!foundRealName)
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], request.uuid, request.client.Name);
request.client.SendNameReply(request.uuid, names[0], names[1]);
}
} }
} }
}
class NameRequest
{
public IClientAPI client;
public UUID uuid;
public NameRequest(IClientAPI c, UUID n)
{
client = c;
uuid = n;
}
}
}

View File

@ -0,0 +1,198 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text;
using System.Threading;
using log4net.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenMetaverse.Assets;
using OpenSim.Framework;
using OpenSim.Region.CoreModules.Scripting.HttpRequest;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests
{
class TestWebRequestCreate : IWebRequestCreate
{
public TestWebRequest NextRequest { get; set; }
public WebRequest Create(Uri uri)
{
// NextRequest.RequestUri = uri;
return NextRequest;
// return new TestWebRequest(new SerializationInfo(typeof(TestWebRequest), new FormatterConverter()), new StreamingContext());
}
}
class TestWebRequest : WebRequest
{
public override string ContentType { get; set; }
public override string Method { get; set; }
public Func<IAsyncResult, WebResponse> OnEndGetResponse { get; set; }
public TestWebRequest() : base()
{
// Console.WriteLine("created");
}
// public TestWebRequest(SerializationInfo serializationInfo, StreamingContext streamingContext)
// : base(serializationInfo, streamingContext)
// {
// Console.WriteLine("created");
// }
public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state)
{
// Console.WriteLine("bish");
TestAsyncResult tasr = new TestAsyncResult();
callback(tasr);
return tasr;
}
public override WebResponse EndGetResponse(IAsyncResult asyncResult)
{
// Console.WriteLine("bosh");
return OnEndGetResponse(asyncResult);
}
}
class TestHttpWebResponse : HttpWebResponse
{
public string Response { get; set; }
public TestHttpWebResponse(SerializationInfo serializationInfo, StreamingContext streamingContext)
: base(serializationInfo, streamingContext) {}
public override Stream GetResponseStream()
{
return new MemoryStream(Encoding.UTF8.GetBytes(Response));
}
}
class TestAsyncResult : IAsyncResult
{
WaitHandle m_wh = new ManualResetEvent(true);
object IAsyncResult.AsyncState
{
get {
throw new System.NotImplementedException ();
}
}
WaitHandle IAsyncResult.AsyncWaitHandle
{
get { return m_wh; }
}
bool IAsyncResult.CompletedSynchronously
{
get { return false; }
}
bool IAsyncResult.IsCompleted
{
get { return true; }
}
}
/// <summary>
/// Test script http request code.
/// </summary>
/// <remarks>
/// This class uses some very hacky workarounds in order to mock HttpWebResponse which are Mono dependent (though
/// alternative code can be written to make this work for Windows). However, the value of being able to
/// regression test this kind of code is very high.
/// </remarks>
[TestFixture]
public class ScriptsHttpRequestsTests : OpenSimTestCase
{
/// <summary>
/// Test what happens when we get a 404 response from a call.
/// </summary>
[Test]
public void Test404Response()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
if (!Util.IsPlatformMono)
Assert.Ignore("Ignoring test since can only currently run on Mono");
string rawResponse = "boom";
TestWebRequestCreate twrc = new TestWebRequestCreate();
TestWebRequest twr = new TestWebRequest();
//twr.OnEndGetResponse += ar => new TestHttpWebResponse(null, new StreamingContext());
twr.OnEndGetResponse += ar =>
{
SerializationInfo si = new SerializationInfo(typeof(HttpWebResponse), new FormatterConverter());
StreamingContext sc = new StreamingContext();
// WebHeaderCollection headers = new WebHeaderCollection();
// si.AddValue("m_HttpResponseHeaders", headers);
si.AddValue("uri", new Uri("test://arrg"));
// si.AddValue("m_Certificate", null);
si.AddValue("version", HttpVersion.Version11);
si.AddValue("statusCode", HttpStatusCode.NotFound);
si.AddValue("contentLength", 0);
si.AddValue("method", "GET");
si.AddValue("statusDescription", "Not Found");
si.AddValue("contentType", null);
si.AddValue("cookieCollection", new CookieCollection());
TestHttpWebResponse thwr = new TestHttpWebResponse(si, sc);
thwr.Response = rawResponse;
throw new WebException("no message", null, WebExceptionStatus.ProtocolError, thwr);
};
twrc.NextRequest = twr;
WebRequest.RegisterPrefix("test", twrc);
HttpRequestClass hr = new HttpRequestClass();
hr.Url = "test://something";
hr.SendRequest();
Assert.That(hr.Status, Is.EqualTo((int)HttpStatusCode.NotFound));
Assert.That(hr.ResponseBody, Is.EqualTo(rawResponse));
}
}
}

View File

@ -81,6 +81,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
public void OnConnectionClose(IClientAPI client) public void OnConnectionClose(IClientAPI client)
{ {
if (client == null)
return;
if (client.SceneAgent == null)
return;
if (client.SceneAgent.IsChildAgent) if (client.SceneAgent.IsChildAgent)
return; return;

View File

@ -195,19 +195,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
{ {
InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID); InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID);
if (invCol != null && UserManager != null) // Commenting this for now, because it's causing more grief than good
{ //if (invCol != null && UserManager != null)
// Protect ourselves against the caller subsequently modifying the items list //{
List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items); // // Protect ourselves against the caller subsequently modifying the items list
// List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
if (items != null && items.Count > 0) // if (items != null && items.Count > 0)
Util.FireAndForget(delegate // //Util.FireAndForget(delegate
{ // //{
foreach (InventoryItemBase item in items) // foreach (InventoryItemBase item in items)
if (!string.IsNullOrEmpty(item.CreatorData)) // if (!string.IsNullOrEmpty(item.CreatorData))
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); // UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
}); // //});
} //}
return invCol; return invCol;
} }

View File

@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
m_EstateModule = fmodule; m_EstateModule = fmodule;
} }
public override byte[] Handle(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); StreamReader sr = new StreamReader(requestData);

View File

@ -55,7 +55,6 @@ namespace OpenSim.Region.Framework.Scenes
private object m_lockObject = new object(); private object m_lockObject = new object();
private object m_timerLock = new object(); private object m_timerLock = new object();
private const double m_tickDuration = 50.0; private const double m_tickDuration = 50.0;
private Scene m_scene;
public double TickDuration public double TickDuration
{ {
@ -69,8 +68,6 @@ namespace OpenSim.Region.Framework.Scenes
m_timer.AutoReset = true; m_timer.AutoReset = true;
m_timer.Elapsed += OnTimer; m_timer.Elapsed += OnTimer;
m_scene = scene;
m_timer.Start(); m_timer.Start();
} }
@ -94,13 +91,13 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m.OnTimer(TickDuration); m.OnTimer(TickDuration);
} }
catch (Exception inner) catch (Exception)
{ {
// Don't stop processing // Don't stop processing
} }
} }
} }
catch (Exception e) catch (Exception)
{ {
// Keep running no matter what // Keep running no matter what
} }
@ -157,7 +154,7 @@ namespace OpenSim.Region.Framework.Scenes
[Serializable] [Serializable]
public class KeyframeMotion public class KeyframeMotion
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public enum PlayMode : int public enum PlayMode : int
{ {

View File

@ -46,48 +46,34 @@ using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.Framework.Scenes namespace OpenSim.Region.Framework.Scenes
{ {
public class RegionStatsHandler : IStreamedRequestHandler public class RegionStatsHandler : BaseStreamHandler
{ {
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string osRXStatsURI = String.Empty;
private string osXStatsURI = String.Empty; private string osXStatsURI = String.Empty;
//private string osSecret = String.Empty; //private string osSecret = String.Empty;
private OpenSim.Framework.RegionInfo regionInfo; private OpenSim.Framework.RegionInfo regionInfo;
public string localZone = TimeZone.CurrentTimeZone.StandardName; public string localZone = TimeZone.CurrentTimeZone.StandardName;
public TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now); public TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
public string Name { get { return "RegionStats"; } }
public string Description { get { return "Region Statistics"; } }
public RegionStatsHandler(RegionInfo region_info) public RegionStatsHandler(RegionInfo region_info)
: base("GET", "/" + Util.SHA1Hash(region_info.regionSecret), "RegionStats", "Region Statistics")
{ {
regionInfo = region_info; regionInfo = region_info;
osRXStatsURI = Util.SHA1Hash(regionInfo.regionSecret);
osXStatsURI = Util.SHA1Hash(regionInfo.osSecret); osXStatsURI = Util.SHA1Hash(regionInfo.osSecret);
} }
public byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) protected override byte[] ProcessRequest(
string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
return Util.UTF8.GetBytes(Report()); return Util.UTF8.GetBytes(Report());
} }
public string ContentType public override string ContentType
{ {
get { return "text/plain"; } get { return "text/plain"; }
} }
public string HttpMethod
{
get { return "GET"; }
}
public string Path
{
// This is for the region and is the regionSecret hashed
get { return "/" + osRXStatsURI; }
}
private string Report() private string Report()
{ {
OSDMap args = new OSDMap(30); OSDMap args = new OSDMap(30);

View File

@ -3258,7 +3258,6 @@ namespace OpenSim.Region.Framework.Scenes
{ {
//client.OnNameFromUUIDRequest += HandleUUIDNameRequest; //client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
client.OnMoneyTransferRequest += ProcessMoneyTransferRequest; client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
client.OnRegionHandleRequest += RegionHandleRequest;
} }
public virtual void SubscribeToClientNetworkEvents(IClientAPI client) public virtual void SubscribeToClientNetworkEvents(IClientAPI client)
@ -3384,7 +3383,6 @@ namespace OpenSim.Region.Framework.Scenes
{ {
//client.OnNameFromUUIDRequest -= HandleUUIDNameRequest; //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest;
client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest; client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest;
client.OnRegionHandleRequest -= RegionHandleRequest;
} }
public virtual void UnSubscribeToClientNetworkEvents(IClientAPI client) public virtual void UnSubscribeToClientNetworkEvents(IClientAPI client)
@ -3859,7 +3857,10 @@ namespace OpenSim.Region.Framework.Scenes
"[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
sp.Name, sp.UUID, RegionInfo.RegionName); sp.Name, sp.UUID, RegionInfo.RegionName);
if (sp.ControllingClient != null)
sp.ControllingClient.Close(true, true); sp.ControllingClient.Close(true, true);
sp = null; sp = null;
} }
} }
@ -5089,22 +5090,6 @@ namespace OpenSim.Region.Framework.Scenes
#endregion #endregion
public void RegionHandleRequest(IClientAPI client, UUID regionID)
{
m_log.DebugFormat("[SCENE]: RegionHandleRequest {0}", regionID);
ulong handle = 0;
if (regionID == RegionInfo.RegionID)
handle = RegionInfo.RegionHandle;
else
{
GridRegion r = GridService.GetRegionByUUID(UUID.Zero, regionID);
if (r != null)
handle = r.RegionHandle;
}
if (handle != 0)
client.SendRegionHandle(regionID, handle);
}
// Commented pending deletion since this method no longer appears to do anything at all // Commented pending deletion since this method no longer appears to do anything at all
// public bool NeedSceneCacheClear(UUID agentID) // public bool NeedSceneCacheClear(UUID agentID)

View File

@ -67,6 +67,12 @@ namespace OpenSim.Region.Framework.Scenes
{ {
int scriptsStarted = 0; int scriptsStarted = 0;
if (m_scene == null)
{
m_log.DebugFormat("[PRIM INVENTORY]: m_scene is null. Unable to create script instances");
return 0;
}
// Don't start scripts if they're turned off in the region! // Don't start scripts if they're turned off in the region!
if (!m_scene.RegionInfo.RegionSettings.DisableScripts) if (!m_scene.RegionInfo.RegionSettings.DisableScripts)
{ {

View File

@ -390,8 +390,6 @@ namespace OpenSim.Region.Framework.Scenes
private SOPVehicle m_vehicleParams = null; private SOPVehicle m_vehicleParams = null;
private KeyframeMotion m_keyframeMotion = null;
public KeyframeMotion KeyframeMotion public KeyframeMotion KeyframeMotion
{ {
get; set; get; set;
@ -543,7 +541,11 @@ namespace OpenSim.Region.Framework.Scenes
CreatorID = uuid; CreatorID = uuid;
} }
if (parts.Length >= 2) if (parts.Length >= 2)
{
CreatorData = parts[1]; CreatorData = parts[1];
if (!CreatorData.EndsWith("/"))
CreatorData += "/";
}
if (parts.Length >= 3) if (parts.Length >= 3)
name = parts[2]; name = parts[2];
@ -4642,6 +4644,11 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
*/ */
if (pa != null)
{
pa.SetMaterial(Material);
DoPhysicsPropertyUpdate(UsePhysics, true);
}
} }
else // it already has a physical representation else // it already has a physical representation
{ {
@ -4696,6 +4703,46 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); // m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
} }
// Subscribe for physics collision events if needed for scripts and sounds
public void SubscribeForCollisionEvents()
{
if (PhysActor != 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) ||
((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
(CollisionSound != UUID.Zero)
)
{
if (!PhysActor.SubscribedEvents())
{
// If not already subscribed for event, set up for a collision event.
PhysActor.OnCollisionUpdate += PhysicsCollision;
PhysActor.SubscribeEvents(1000);
}
}
else
{
// There is no need to be subscribed to collisions so, if subscribed, remove subscription
if (PhysActor.SubscribedEvents())
{
PhysActor.OnCollisionUpdate -= PhysicsCollision;
PhysActor.UnSubscribeEvents();
}
}
}
}
/// <summary> /// <summary>
/// Adds this part to the physics scene. /// Adds this part to the physics scene.
/// and sets the PhysActor property /// and sets the PhysActor property
@ -5154,31 +5201,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
} }
/*
PhysicsActor 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)
)
{
// subscribe to physics updates.
pa.OnCollisionUpdate += PhysicsCollision;
pa.SubscribeEvents(1000);
}
else
{
pa.UnSubscribeEvents();
pa.OnCollisionUpdate -= PhysicsCollision;
}
}
*/
UpdatePhysicsSubscribedEvents(); UpdatePhysicsSubscribedEvents();
//if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)

View File

@ -696,6 +696,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </param> /// </param>
public void StopScriptInstance(TaskInventoryItem item) public void StopScriptInstance(TaskInventoryItem item)
{ {
if (m_part.ParentGroup.Scene != null)
m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID); m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID);
// At the moment, even stopped scripts are counted as active, which is probably wrong. // At the moment, even stopped scripts are counted as active, which is probably wrong.

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Timers;
using Timer = System.Timers.Timer;
using Nini.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.ClientStack.Linden;
using OpenSim.Region.CoreModules.Framework;
using OpenSim.Region.CoreModules.Framework.EntityTransfer;
using OpenSim.Region.CoreModules.World.Serialiser;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Region.Framework.Scenes.Tests
{
[TestFixture]
public class ScenePresenceCapabilityTests : OpenSimTestCase
{
[Test]
public void TestChildAgentSingleRegionCapabilities()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
UUID spUuid = TestHelpers.ParseTail(0x1);
// XXX: This is not great since the use of statics will mean that this has to be manually cleaned up for
// any subsequent test.
// XXX: May replace with a mock IHttpServer later.
BaseHttpServer httpServer = new BaseHttpServer(99999);
MainServer.AddHttpServer(httpServer);
MainServer.Instance = httpServer;
CapabilitiesModule capsMod = new CapabilitiesModule();
TestScene scene = new SceneHelpers().SetupScene();
SceneHelpers.SetupSceneModules(scene, capsMod);
ScenePresence sp = SceneHelpers.AddChildScenePresence(scene, spUuid);
//Assert.That(capsMod.GetCapsForUser(spUuid), Is.Not.Null);
// TODO: Need to add tests for other ICapabiltiesModule methods.
scene.IncomingCloseAgent(sp.UUID, false);
//Assert.That(capsMod.GetCapsForUser(spUuid), Is.Null);
// TODO: Need to add tests for other ICapabiltiesModule methods.
}
}
}

View File

@ -27,6 +27,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using log4net; using log4net;
@ -51,7 +52,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LindenUDPInfoModule")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LindenUDPInfoModule")]
public class LindenUDPInfoModule : ISharedRegionModule public class LindenUDPInfoModule : ISharedRegionModule
{ {
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); protected Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
@ -130,6 +131,15 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
"Go on/off emergency monitoring mode", "Go on/off emergency monitoring mode",
"Go on/off emergency monitoring mode", "Go on/off emergency monitoring mode",
HandleEmergencyMonitoring); HandleEmergencyMonitoring);
scene.AddCommand(
"Comms", this, "show client stats",
"show client stats [first_name last_name]",
"Show client request stats",
"Without the 'first_name last_name' option, all clients are shown."
+ " With the 'first_name last_name' option only a specific client is shown.",
(mod, cmd) => MainConsole.Instance.Output(HandleClientStatsReport(cmd)));
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
@ -588,5 +598,101 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
return report.ToString(); return report.ToString();
} }
/// <summary>
/// Show client stats data
/// </summary>
/// <param name="showParams"></param>
/// <returns></returns>
protected string HandleClientStatsReport(string[] showParams)
{
// NOTE: This writes to m_log on purpose. We want to store this information
// in case we need to analyze it later.
//
if (showParams.Length <= 4)
{
m_log.InfoFormat("[INFO]: {0,-12} {1,20} {2,6} {3,11} {4, 10}", "Region", "Name", "Root", "Time", "Reqs/min");
foreach (Scene scene in m_scenes.Values)
{
scene.ForEachClient(
delegate(IClientAPI client)
{
if (client is LLClientView)
{
LLClientView llClient = client as LLClientView;
ClientInfo cinfo = llClient.UDPClient.GetClientInfo();
int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum();
avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1);
m_log.InfoFormat("[INFO]: {0,-12} {1,20} {2,4} {3,9}min {4,10}",
scene.RegionInfo.RegionName, llClient.Name,
(llClient.SceneAgent.IsChildAgent ? "N" : "Y"), (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs);
}
});
}
return string.Empty;
}
string fname = "", lname = "";
if (showParams.Length > 3)
fname = showParams[3];
if (showParams.Length > 4)
lname = showParams[4];
foreach (Scene scene in m_scenes.Values)
{
scene.ForEachClient(
delegate(IClientAPI client)
{
if (client is LLClientView)
{
LLClientView llClient = client as LLClientView;
if (llClient.Name == fname + " " + lname)
{
ClientInfo cinfo = llClient.GetClientInfo();
AgentCircuitData aCircuit = scene.AuthenticateHandler.GetAgentCircuitData(llClient.CircuitCode);
if (aCircuit == null) // create a dummy one
aCircuit = new AgentCircuitData();
if (!llClient.SceneAgent.IsChildAgent)
m_log.InfoFormat("[INFO]: {0} # {1} # {2}", llClient.Name, aCircuit.Viewer, aCircuit.Id0);
int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum();
avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1);
m_log.InfoFormat("[INFO]:");
m_log.InfoFormat("[INFO]: {0} # {1} # Time: {2}min # Avg Reqs/min: {3}", scene.RegionInfo.RegionName,
(llClient.SceneAgent.IsChildAgent ? "Child" : "Root"), (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs);
Dictionary<string, int> sortedDict = (from entry in cinfo.AsyncRequests orderby entry.Value descending select entry)
.ToDictionary(pair => pair.Key, pair => pair.Value);
PrintRequests("TOP ASYNC", sortedDict, cinfo.AsyncRequests.Values.Sum());
sortedDict = (from entry in cinfo.SyncRequests orderby entry.Value descending select entry)
.ToDictionary(pair => pair.Key, pair => pair.Value);
PrintRequests("TOP SYNC", sortedDict, cinfo.SyncRequests.Values.Sum());
sortedDict = (from entry in cinfo.GenericRequests orderby entry.Value descending select entry)
.ToDictionary(pair => pair.Key, pair => pair.Value);
PrintRequests("TOP GENERIC", sortedDict, cinfo.GenericRequests.Values.Sum());
}
}
});
}
return string.Empty;
}
private void PrintRequests(string type, Dictionary<string, int> sortedDict, int sum)
{
m_log.InfoFormat("[INFO]:");
m_log.InfoFormat("[INFO]: {0,25}", type);
foreach (KeyValuePair<string, int> kvp in sortedDict.Take(12))
m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value);
m_log.InfoFormat("[INFO]: {0,25}", "...");
m_log.InfoFormat("[INFO]: {0,25} {1,-6}", "Total", sum);
}
} }
} }

View File

@ -139,18 +139,21 @@ namespace OpenSim.Region.OptionalModules.MaterialsDemoModule
{ {
string capsBase = "/CAPS/" + caps.CapsObjectPath; string capsBase = "/CAPS/" + caps.CapsObjectPath;
IRequestHandler renderMaterialsPostHandler = new RestStreamHandler("POST", capsBase + "/", RenderMaterialsPostCap); IRequestHandler renderMaterialsPostHandler
= new RestStreamHandler("POST", capsBase + "/", RenderMaterialsPostCap, "RenderMaterials", null);
caps.RegisterHandler("RenderMaterials", renderMaterialsPostHandler); caps.RegisterHandler("RenderMaterials", renderMaterialsPostHandler);
// OpenSimulator CAPs infrastructure seems to be somewhat hostile towards any CAP that requires both GET // OpenSimulator CAPs infrastructure seems to be somewhat hostile towards any CAP that requires both GET
// and POST handlers, (at least at the time this was originally written), so we first set up a POST // and POST handlers, (at least at the time this was originally written), so we first set up a POST
// handler normally and then add a GET handler via MainServer // handler normally and then add a GET handler via MainServer
IRequestHandler renderMaterialsGetHandler = new RestStreamHandler("GET", capsBase + "/", RenderMaterialsGetCap); IRequestHandler renderMaterialsGetHandler
= new RestStreamHandler("GET", capsBase + "/", RenderMaterialsGetCap, "RenderMaterials", null);
MainServer.Instance.AddStreamHandler(renderMaterialsGetHandler); MainServer.Instance.AddStreamHandler(renderMaterialsGetHandler);
// materials viewer seems to use either POST or PUT, so assign POST handler for PUT as well // materials viewer seems to use either POST or PUT, so assign POST handler for PUT as well
IRequestHandler renderMaterialsPutHandler = new RestStreamHandler("PUT", capsBase + "/", RenderMaterialsPostCap); IRequestHandler renderMaterialsPutHandler
= new RestStreamHandler("PUT", capsBase + "/", RenderMaterialsPostCap, "RenderMaterials", null);
MainServer.Instance.AddStreamHandler(renderMaterialsPutHandler); MainServer.Instance.AddStreamHandler(renderMaterialsPutHandler);
} }
@ -394,7 +397,6 @@ namespace OpenSim.Region.OptionalModules.MaterialsDemoModule
m_log.Debug("[MaterialsDemoModule]: null SOP for localId: " + matLocalID.ToString()); m_log.Debug("[MaterialsDemoModule]: null SOP for localId: " + matLocalID.ToString());
else else
{ {
//var te = sop.Shape.Textures;
var te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length); var te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length);
if (te == null) if (te == null)
@ -413,15 +415,8 @@ namespace OpenSim.Region.OptionalModules.MaterialsDemoModule
if (te.DefaultTexture == null) if (te.DefaultTexture == null)
m_log.Debug("[MaterialsDemoModule]: te.DefaultTexture is null"); m_log.Debug("[MaterialsDemoModule]: te.DefaultTexture is null");
else else
{
if (te.DefaultTexture.MaterialID == null)
m_log.Debug("[MaterialsDemoModule]: te.DefaultTexture.MaterialID is null");
else
{
te.DefaultTexture.MaterialID = id; te.DefaultTexture.MaterialID = id;
} }
}
}
else else
{ {
if (te.FaceTextures.Length >= face - 1) if (te.FaceTextures.Length >= face - 1)

View File

@ -263,7 +263,7 @@ namespace OpenSim.Region.OptionalModules.ViewerSupport
m_module = module; m_module = module;
} }
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader reader = new StreamReader(request); StreamReader reader = new StreamReader(request);
string requestBody = reader.ReadToEnd(); string requestBody = reader.ReadToEnd();

View File

@ -55,7 +55,7 @@ namespace OpenSim.Region.OptionalModules.World.WorldView
m_WorldViewModule = fmodule; m_WorldViewModule = fmodule;
} }
public override byte[] Handle(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
httpResponse.ContentType = "image/jpeg"; httpResponse.ContentType = "image/jpeg";

View File

@ -43,12 +43,10 @@ public sealed class BSCharacter : BSPhysObject
private OMV.Vector3 _size; private OMV.Vector3 _size;
private bool _grabbed; private bool _grabbed;
private bool _selected; private bool _selected;
private OMV.Vector3 _position;
private float _mass; private float _mass;
private float _avatarVolume; private float _avatarVolume;
private float _collisionScore; private float _collisionScore;
private OMV.Vector3 _acceleration; private OMV.Vector3 _acceleration;
private OMV.Quaternion _orientation;
private int _physicsActorType; private int _physicsActorType;
private bool _isPhysical; private bool _isPhysical;
private bool _flying; private bool _flying;
@ -70,10 +68,10 @@ public sealed class BSCharacter : BSPhysObject
: base(parent_scene, localID, avName, "BSCharacter") : base(parent_scene, localID, avName, "BSCharacter")
{ {
_physicsActorType = (int)ActorTypes.Agent; _physicsActorType = (int)ActorTypes.Agent;
_position = pos; RawPosition = pos;
_flying = isFlying; _flying = isFlying;
_orientation = OMV.Quaternion.Identity; RawOrientation = OMV.Quaternion.Identity;
RawVelocity = OMV.Vector3.Zero; RawVelocity = OMV.Vector3.Zero;
_buoyancy = ComputeBuoyancyFromFlying(isFlying); _buoyancy = ComputeBuoyancyFromFlying(isFlying);
Friction = BSParam.AvatarStandingFriction; Friction = BSParam.AvatarStandingFriction;
@ -133,7 +131,7 @@ public sealed class BSCharacter : BSPhysObject
PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody); PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody);
ZeroMotion(true); ZeroMotion(true);
ForcePosition = _position; ForcePosition = RawPosition;
// Set the velocity // Set the velocity
if (m_moveActor != null) if (m_moveActor != null)
@ -272,38 +270,33 @@ public sealed class BSCharacter : BSPhysObject
public override void LockAngularMotion(OMV.Vector3 axis) { return; } public override void LockAngularMotion(OMV.Vector3 axis) { return; }
public override OMV.Vector3 RawPosition
{
get { return _position; }
set { _position = value; }
}
public override OMV.Vector3 Position { public override OMV.Vector3 Position {
get { get {
// Don't refetch the position because this function is called a zillion times // Don't refetch the position because this function is called a zillion times
// _position = PhysicsScene.PE.GetObjectPosition(Scene.World, LocalID); // RawPosition = PhysicsScene.PE.GetObjectPosition(Scene.World, LocalID);
return _position; return RawPosition;
} }
set { set {
_position = value; RawPosition = value;
PhysScene.TaintedObject("BSCharacter.setPosition", delegate() PhysScene.TaintedObject("BSCharacter.setPosition", delegate()
{ {
DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
PositionSanityCheck(); PositionSanityCheck();
ForcePosition = _position; ForcePosition = RawPosition;
}); });
} }
} }
public override OMV.Vector3 ForcePosition { public override OMV.Vector3 ForcePosition {
get { get {
_position = PhysScene.PE.GetPosition(PhysBody); RawPosition = PhysScene.PE.GetPosition(PhysBody);
return _position; return RawPosition;
} }
set { set {
_position = value; RawPosition = value;
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
PhysScene.PE.SetTranslation(PhysBody, _position, _orientation); PhysScene.PE.SetTranslation(PhysBody, RawPosition, RawOrientation);
} }
} }
} }
@ -331,16 +324,16 @@ public sealed class BSCharacter : BSPhysObject
float terrainHeight = PhysScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition); float terrainHeight = PhysScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
if (Position.Z < terrainHeight) if (Position.Z < terrainHeight)
{ {
DetailLog("{0},BSCharacter.PositionSanityCheck,adjustForUnderGround,pos={1},terrain={2}", LocalID, _position, terrainHeight); DetailLog("{0},BSCharacter.PositionSanityCheck,adjustForUnderGround,pos={1},terrain={2}", LocalID, RawPosition, terrainHeight);
_position.Z = terrainHeight + BSParam.AvatarBelowGroundUpCorrectionMeters; RawPosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, terrainHeight + BSParam.AvatarBelowGroundUpCorrectionMeters);
ret = true; ret = true;
} }
if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
{ {
float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(_position); float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(RawPosition);
if (Position.Z < waterHeight) if (Position.Z < waterHeight)
{ {
_position.Z = waterHeight; RawPosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, waterHeight);
ret = true; ret = true;
} }
} }
@ -360,8 +353,8 @@ public sealed class BSCharacter : BSPhysObject
// just assign to "Position" because of potential call loops. // just assign to "Position" because of potential call loops.
PhysScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate() PhysScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate()
{ {
DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
ForcePosition = _position; ForcePosition = RawPosition;
}); });
ret = true; ret = true;
} }
@ -466,19 +459,14 @@ public sealed class BSCharacter : BSPhysObject
get { return _acceleration; } get { return _acceleration; }
set { _acceleration = value; } set { _acceleration = value; }
} }
public override OMV.Quaternion RawOrientation
{
get { return _orientation; }
set { _orientation = value; }
}
public override OMV.Quaternion Orientation { public override OMV.Quaternion Orientation {
get { return _orientation; } get { return RawOrientation; }
set { set {
// Orientation is set zillions of times when an avatar is walking. It's like // Orientation is set zillions of times when an avatar is walking. It's like
// the viewer doesn't trust us. // the viewer doesn't trust us.
if (_orientation != value) if (RawOrientation != value)
{ {
_orientation = value; RawOrientation = value;
PhysScene.TaintedObject("BSCharacter.setOrientation", delegate() PhysScene.TaintedObject("BSCharacter.setOrientation", delegate()
{ {
// Bullet assumes we know what we are doing when forcing orientation // Bullet assumes we know what we are doing when forcing orientation
@ -486,10 +474,10 @@ public sealed class BSCharacter : BSPhysObject
// This forces rotation to be only around the Z axis and doesn't change any of the other axis. // This forces rotation to be only around the Z axis and doesn't change any of the other axis.
// This keeps us from flipping the capsule over which the veiwer does not understand. // This keeps us from flipping the capsule over which the veiwer does not understand.
float oRoll, oPitch, oYaw; float oRoll, oPitch, oYaw;
_orientation.GetEulerAngles(out oRoll, out oPitch, out oYaw); RawOrientation.GetEulerAngles(out oRoll, out oPitch, out oYaw);
OMV.Quaternion trimmedOrientation = OMV.Quaternion.CreateFromEulers(0f, 0f, oYaw); OMV.Quaternion trimmedOrientation = OMV.Quaternion.CreateFromEulers(0f, 0f, oYaw);
// DetailLog("{0},BSCharacter.setOrientation,taint,val={1},valDir={2},conv={3},convDir={4}", // DetailLog("{0},BSCharacter.setOrientation,taint,val={1},valDir={2},conv={3},convDir={4}",
// LocalID, _orientation, OMV.Vector3.UnitX * _orientation, // LocalID, RawOrientation, OMV.Vector3.UnitX * RawOrientation,
// trimmedOrientation, OMV.Vector3.UnitX * trimmedOrientation); // trimmedOrientation, OMV.Vector3.UnitX * trimmedOrientation);
ForceOrientation = trimmedOrientation; ForceOrientation = trimmedOrientation;
}); });
@ -501,16 +489,16 @@ public sealed class BSCharacter : BSPhysObject
{ {
get get
{ {
_orientation = PhysScene.PE.GetOrientation(PhysBody); RawOrientation = PhysScene.PE.GetOrientation(PhysBody);
return _orientation; return RawOrientation;
} }
set set
{ {
_orientation = value; RawOrientation = value;
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
// _position = PhysicsScene.PE.GetPosition(BSBody); // RawPosition = PhysicsScene.PE.GetPosition(BSBody);
PhysScene.PE.SetTranslation(PhysBody, _position, _orientation); PhysScene.PE.SetTranslation(PhysBody, RawPosition, RawOrientation);
} }
} }
} }
@ -723,9 +711,9 @@ public sealed class BSCharacter : BSPhysObject
{ {
// Don't change position if standing on a stationary object. // Don't change position if standing on a stationary object.
if (!IsStationary) if (!IsStationary)
_position = entprop.Position; RawPosition = entprop.Position;
_orientation = entprop.Rotation; RawOrientation = entprop.Rotation;
// Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar // Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar
// and will send agent updates to the clients if velocity changes by more than // and will send agent updates to the clients if velocity changes by more than
@ -740,8 +728,8 @@ public sealed class BSCharacter : BSPhysObject
// Do some sanity checking for the avatar. Make sure it's above ground and inbounds. // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
if (PositionSanityCheck(true)) if (PositionSanityCheck(true))
{ {
DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position); DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, RawPosition);
entprop.Position = _position; entprop.Position = RawPosition;
} }
// remember the current and last set values // remember the current and last set values
@ -755,7 +743,7 @@ public sealed class BSCharacter : BSPhysObject
// base.RequestPhysicsterseUpdate(); // base.RequestPhysicsterseUpdate();
DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
LocalID, _position, _orientation, RawVelocity, _acceleration, _rotationalVelocity); LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, _rotationalVelocity);
} }
} }
} }

View File

@ -125,33 +125,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
static readonly float PIOverFour = ((float)Math.PI) / 4f; static readonly float PIOverFour = ((float)Math.PI) / 4f;
static readonly float PIOverTwo = ((float)Math.PI) / 2f; static readonly float PIOverTwo = ((float)Math.PI) / 2f;
// For debugging, flags to turn on and off individual corrections.
public bool enableAngularVerticalAttraction;
public bool enableAngularDeflection;
public bool enableAngularBanking;
public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName) public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName)
: base(myScene, myPrim, actorName) : base(myScene, myPrim, actorName)
{ {
ControllingPrim = myPrim; ControllingPrim = myPrim;
Type = Vehicle.TYPE_NONE; Type = Vehicle.TYPE_NONE;
m_haveRegisteredForSceneEvents = false; m_haveRegisteredForSceneEvents = false;
SetupVehicleDebugging();
}
// Stopgap debugging enablement. Allows source level debugging but still checking
// in changes by making enablement of debugging flags from INI file.
public void SetupVehicleDebugging()
{
enableAngularVerticalAttraction = true;
enableAngularDeflection = false;
enableAngularBanking = true;
if (BSParam.VehicleDebuggingEnable)
{
enableAngularVerticalAttraction = true;
enableAngularDeflection = false;
enableAngularBanking = false;
}
} }
// Return 'true' if this vehicle is doing vehicle things // Return 'true' if this vehicle is doing vehicle things
@ -173,7 +152,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
switch (pParam) switch (pParam)
{ {
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
m_angularDeflectionEfficiency = Math.Max(pValue, 0.01f); m_angularDeflectionEfficiency = ClampInRange(0f, pValue, 1f);
break; break;
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); m_angularDeflectionTimescale = Math.Max(pValue, 0.01f);
@ -556,10 +535,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
} }
m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, m_linearMotorDecayTimescale, 1f); m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, m_linearMotorDecayTimescale, 1f);
m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging) // m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, m_angularMotorDecayTimescale, 1f); m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, m_angularMotorDecayTimescale, 1f);
m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging) // m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
/* Not implemented /* Not implemented
m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale,
@ -774,7 +753,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Since the computation of terrain height can be a little involved, this routine // Since the computation of terrain height can be a little involved, this routine
// is used to fetch the height only once for each vehicle simulation step. // is used to fetch the height only once for each vehicle simulation step.
Vector3 lastRememberedHeightPos; Vector3 lastRememberedHeightPos = new Vector3(-1, -1, -1);
private float GetTerrainHeight(Vector3 pos) private float GetTerrainHeight(Vector3 pos)
{ {
if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos) if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos)
@ -788,14 +767,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Since the computation of water level can be a little involved, this routine // Since the computation of water level can be a little involved, this routine
// is used ot fetch the level only once for each vehicle simulation step. // is used ot fetch the level only once for each vehicle simulation step.
Vector3 lastRememberedWaterHeightPos = new Vector3(-1, -1, -1);
private float GetWaterLevel(Vector3 pos) private float GetWaterLevel(Vector3 pos)
{ {
if ((m_knownHas & m_knownChangedWaterLevel) == 0) if ((m_knownHas & m_knownChangedWaterLevel) == 0 || pos != lastRememberedWaterHeightPos)
{ {
lastRememberedWaterHeightPos = pos;
m_knownWaterLevel = ControllingPrim.PhysScene.TerrainManager.GetWaterLevelAtXYZ(pos); m_knownWaterLevel = ControllingPrim.PhysScene.TerrainManager.GetWaterLevelAtXYZ(pos);
m_knownHas |= m_knownChangedWaterLevel; m_knownHas |= m_knownChangedWaterLevel;
} }
return (float)m_knownWaterLevel; return m_knownWaterLevel;
} }
private Vector3 VehiclePosition private Vector3 VehiclePosition
@ -924,6 +905,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
return VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation)); return VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation));
} }
} }
private float VehicleForwardSpeed private float VehicleForwardSpeed
{ {
get get
@ -991,11 +973,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{ {
Vector3 vel = VehicleVelocity; Vector3 vel = VehicleVelocity;
if ((m_flags & (VehicleFlag.NO_X)) != 0) if ((m_flags & (VehicleFlag.NO_X)) != 0)
{
vel.X = 0; vel.X = 0;
}
if ((m_flags & (VehicleFlag.NO_Y)) != 0) if ((m_flags & (VehicleFlag.NO_Y)) != 0)
{
vel.Y = 0; vel.Y = 0;
}
if ((m_flags & (VehicleFlag.NO_Z)) != 0) if ((m_flags & (VehicleFlag.NO_Z)) != 0)
{
vel.Z = 0; vel.Z = 0;
}
VehicleVelocity = vel; VehicleVelocity = vel;
} }
@ -1053,6 +1041,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
Vector3 linearDeflectionV = Vector3.Zero; Vector3 linearDeflectionV = Vector3.Zero;
Vector3 velocityV = VehicleForwardVelocity; Vector3 velocityV = VehicleForwardVelocity;
if (BSParam.VehicleEnableLinearDeflection)
{
// Velocity in Y and Z dimensions is movement to the side or turning. // Velocity in Y and Z dimensions is movement to the side or turning.
// Compute deflection factor from the to the side and rotational velocity // Compute deflection factor from the to the side and rotational velocity
linearDeflectionV.Y = SortedClampInRange(0, (velocityV.Y * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Y); linearDeflectionV.Y = SortedClampInRange(0, (velocityV.Y * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Y);
@ -1068,12 +1058,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Subtract the sideways and rotational velocity deflection factors while adding the correction forward // Subtract the sideways and rotational velocity deflection factors while adding the correction forward
linearDeflectionV *= new Vector3(1, -1, -1); linearDeflectionV *= new Vector3(1, -1, -1);
// Correciont is vehicle relative. Convert to world coordinates and add to the velocity // Correction is vehicle relative. Convert to world coordinates.
VehicleVelocity += linearDeflectionV * VehicleOrientation; Vector3 linearDeflectionW = linearDeflectionV * VehicleOrientation;
// Optionally, if not colliding, don't effect world downward velocity. Let falling things fall.
if (BSParam.VehicleLinearDeflectionNotCollidingNoZ && !m_controllingPrim.IsColliding)
{
linearDeflectionW.Z = 0f;
}
VehicleVelocity += linearDeflectionW;
VDetailLog("{0}, MoveLinear,LinearDeflection,linDefEff={1},linDefTS={2},linDeflectionV={3}", VDetailLog("{0}, MoveLinear,LinearDeflection,linDefEff={1},linDefTS={2},linDeflectionV={3}",
ControllingPrim.LocalID, m_linearDeflectionEfficiency, m_linearDeflectionTimescale, linearDeflectionV); ControllingPrim.LocalID, m_linearDeflectionEfficiency, m_linearDeflectionTimescale, linearDeflectionV);
} }
}
public void ComputeLinearTerrainHeightCorrection(float pTimestep) public void ComputeLinearTerrainHeightCorrection(float pTimestep)
{ {
@ -1385,20 +1384,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{ {
// If vertical attaction timescale is reasonable // If vertical attaction timescale is reasonable
if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) if (BSParam.VehicleEnableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
{
Vector3 vehicleUpAxis = Vector3.UnitZ * VehicleOrientation;
switch (BSParam.VehicleAngularVerticalAttractionAlgorithm)
{
case 0:
{ {
//Another formula to try got from : //Another formula to try got from :
//http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html //http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html
Vector3 VehicleUpAxis = Vector3.UnitZ * VehicleOrientation;
// Flipping what was originally a timescale into a speed variable and then multiplying it by 2 // Flipping what was originally a timescale into a speed variable and then multiplying it by 2
// since only computing half the distance between the angles. // since only computing half the distance between the angles.
float VerticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f; float VerticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f;
// Make a prediction of where the up axis will be when this is applied rather then where it is now as // Make a prediction of where the up axis will be when this is applied rather then where it is now as
// this makes for a smoother adjustment and less fighting between the various forces. // this makes for a smoother adjustment and less fighting between the various forces.
Vector3 predictedUp = VehicleUpAxis * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f); Vector3 predictedUp = vehicleUpAxis * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f);
// This is only half the distance to the target so it will take 2 seconds to complete the turn. // This is only half the distance to the target so it will take 2 seconds to complete the turn.
Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ); Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ);
@ -1408,14 +1410,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
VehicleRotationalVelocity += vertContributionV; VehicleRotationalVelocity += vertContributionV;
VDetailLog("{0}, MoveAngular,verticalAttraction,UpAxis={1},PredictedUp={2},torqueVector={3},contrib={4}", VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},PredictedUp={2},torqueVector={3},contrib={4}",
ControllingPrim.LocalID, ControllingPrim.LocalID,
VehicleUpAxis, vehicleUpAxis,
predictedUp, predictedUp,
torqueVector, torqueVector,
vertContributionV); vertContributionV);
//===================================================================== break;
/* }
case 1:
{
// Possible solution derived from a discussion at: // Possible solution derived from a discussion at:
// http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no // http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no
@ -1444,16 +1448,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin
VehicleRotationalVelocity += vertContributionV; VehicleRotationalVelocity += vertContributionV;
VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}", VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},diffAxis={2},diffAng={3},corrRot={4},contrib={5}",
ControllingPrim.LocalID, ControllingPrim.LocalID,
vehicleUpAxis,
differenceAxis, differenceAxis,
differenceAngle, differenceAngle,
correctionRotation, correctionRotation,
vertContributionV); vertContributionV);
*/ break;
}
// =================================================================== case 2:
/* {
Vector3 vertContributionV = Vector3.Zero; Vector3 vertContributionV = Vector3.Zero;
Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG
@ -1491,10 +1496,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Rotate the vehicle rotation to the world coordinates. // Rotate the vehicle rotation to the world coordinates.
VehicleRotationalVelocity += (vertContributionV * VehicleOrientation); VehicleRotationalVelocity += (vertContributionV * VehicleOrientation);
VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}", VDetailLog("{0}, MoveAngular,verticalAttraction,,upAxis={1},origRotVW={2},vertError={3},unscaledV={4},eff={5},ts={6},vertContribV={7}",
Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV, ControllingPrim.LocalID,
m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV); vehicleUpAxis,
*/ origRotVelW,
verticalError,
unscaledContribVerticalErrorV,
m_verticalAttractionEfficiency,
m_verticalAttractionTimescale,
vertContributionV);
break;
}
default:
{
break;
}
}
} }
} }
@ -1505,12 +1522,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// TODO: implement reference frame. // TODO: implement reference frame.
public void ComputeAngularDeflection() public void ComputeAngularDeflection()
{ {
// Since angularMotorUp and angularDeflection are computed independently, they will calculate
// approximately the same X or Y correction. When added together (when contributions are combined)
// this creates an over-correction and then wabbling as the target is overshot.
// TODO: rethink how the different correction computations inter-relate.
if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) if (BSParam.VehicleEnableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2)
{ {
Vector3 deflectContributionV = Vector3.Zero; Vector3 deflectContributionV = Vector3.Zero;
@ -1523,10 +1536,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// The direction the vehicle is pointing // The direction the vehicle is pointing
Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation;
pointingDirection.Normalize(); //Predict where the Vehicle will be pointing after AngularVelocity change is applied. This will keep
// from overshooting and allow this correction to merge with the Vertical Attraction peacefully.
Vector3 predictedPointingDirection = pointingDirection * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f);
predictedPointingDirection.Normalize();
// The difference between what is and what should be. // The difference between what is and what should be.
Vector3 deflectionError = movingDirection - pointingDirection; // Vector3 deflectionError = movingDirection - predictedPointingDirection;
Vector3 deflectionError = Vector3.Cross(movingDirection, predictedPointingDirection);
// Don't try to correct very large errors (not our job) // Don't try to correct very large errors (not our job)
// if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = PIOverTwo * Math.Sign(deflectionError.X); // if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = PIOverTwo * Math.Sign(deflectionError.X);
@ -1539,15 +1556,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// ret = m_angularDeflectionCorrectionMotor(1f, deflectionError); // ret = m_angularDeflectionCorrectionMotor(1f, deflectionError);
// Scale the correction by recovery timescale and efficiency // Scale the correction by recovery timescale and efficiency
deflectContributionV = (-deflectionError) * m_angularDeflectionEfficiency; // Not modeling a spring so clamp the scale to no more then the arc
deflectContributionV /= m_angularDeflectionTimescale; deflectContributionV = (-deflectionError) * ClampInRange(0, m_angularDeflectionEfficiency/m_angularDeflectionTimescale,1f);
//deflectContributionV /= m_angularDeflectionTimescale;
VehicleRotationalVelocity += deflectContributionV * VehicleOrientation;
// VehicleRotationalVelocity += deflectContributionV * VehicleOrientation;
VehicleRotationalVelocity += deflectContributionV;
VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}",
ControllingPrim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV); ControllingPrim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV);
VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}", VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3},PredictedPointingDir={4}",
ControllingPrim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale); ControllingPrim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale, predictedPointingDirection);
} }
} }
@ -1584,7 +1602,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// make a sluggish vehicle by giving it a timescale of several seconds. // make a sluggish vehicle by giving it a timescale of several seconds.
public void ComputeAngularBanking() public void ComputeAngularBanking()
{ {
if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) if (BSParam.VehicleEnableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
{ {
Vector3 bankingContributionV = Vector3.Zero; Vector3 bankingContributionV = Vector3.Zero;

View File

@ -35,62 +35,6 @@ using OMV = OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin namespace OpenSim.Region.Physics.BulletSPlugin
{ {
/*
// When a child is linked, the relationship position of the child to the parent
// is remembered so the child's world position can be recomputed when it is
// removed from the linkset.
sealed class BSLinksetCompoundInfo : BSLinksetInfo
{
public int Index;
public OMV.Vector3 OffsetFromRoot;
public OMV.Vector3 OffsetFromCenterOfMass;
public OMV.Quaternion OffsetRot;
public BSLinksetCompoundInfo(int indx, OMV.Vector3 p, OMV.Quaternion r)
{
Index = indx;
OffsetFromRoot = p;
OffsetFromCenterOfMass = p;
OffsetRot = r;
}
// 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape)
public BSLinksetCompoundInfo(int indx, BSPrimLinkable root, BSPrimLinkable child, OMV.Vector3 centerDisplacement)
{
// Each child position and rotation is given relative to the center-of-mass.
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation);
OMV.Vector3 displacementFromRoot = (child.RawPosition - root.RawPosition) * invRootOrientation;
OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement;
OMV.Quaternion displacementRot = child.RawOrientation * invRootOrientation;
// Save relative position for recomputing child's world position after moving linkset.
Index = indx;
OffsetFromRoot = displacementFromRoot;
OffsetFromCenterOfMass = displacementFromCOM;
OffsetRot = displacementRot;
}
public override void Clear()
{
Index = 0;
OffsetFromRoot = OMV.Vector3.Zero;
OffsetFromCenterOfMass = OMV.Vector3.Zero;
OffsetRot = OMV.Quaternion.Identity;
}
public override string ToString()
{
StringBuilder buff = new StringBuilder();
buff.Append("<i=");
buff.Append(Index.ToString());
buff.Append(",p=");
buff.Append(OffsetFromRoot.ToString());
buff.Append(",m=");
buff.Append(OffsetFromCenterOfMass.ToString());
buff.Append(",r=");
buff.Append(OffsetRot.ToString());
buff.Append(">");
return buff.ToString();
}
};
*/
public sealed class BSLinksetCompound : BSLinkset public sealed class BSLinksetCompound : BSLinkset
{ {
private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]";
@ -151,7 +95,9 @@ public sealed class BSLinksetCompound : BSLinkset
public override bool MakeStatic(BSPrimLinkable child) public override bool MakeStatic(BSPrimLinkable child)
{ {
bool ret = false; bool ret = false;
DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child));
child.ClearDisplacement();
if (IsRoot(child)) if (IsRoot(child))
{ {
// Schedule a rebuild to verify that the root shape is set to the real shape. // Schedule a rebuild to verify that the root shape is set to the real shape.
@ -315,7 +261,6 @@ public sealed class BSLinksetCompound : BSLinkset
// Note that this works for rebuilding just the root after a linkset is taken apart. // Note that this works for rebuilding just the root after a linkset is taken apart.
// Called at taint time!! // Called at taint time!!
private bool UseBulletSimRootOffsetHack = false; // Attempt to have Bullet track the coords of root compound shape private bool UseBulletSimRootOffsetHack = false; // Attempt to have Bullet track the coords of root compound shape
private bool disableCOM = true; // For basic linkset debugging, turn off the center-of-mass setting
private void RecomputeLinksetCompound() private void RecomputeLinksetCompound()
{ {
try try
@ -326,55 +271,70 @@ public sealed class BSLinksetCompound : BSLinkset
// to what they should be as if the root was not in a linkset. // to what they should be as if the root was not in a linkset.
// Not that bad since we only get into this routine if there are children in the linkset and // Not that bad since we only get into this routine if there are children in the linkset and
// something has been updated/changed. // something has been updated/changed.
// Have to do the rebuild before checking for physical because this might be a linkset
// being destructed and going non-physical.
LinksetRoot.ForceBodyShapeRebuild(true); LinksetRoot.ForceBodyShapeRebuild(true);
// There is no reason to build all this physical stuff for a non-physical linkset. // There is no reason to build all this physical stuff for a non-physical linkset.
if (!LinksetRoot.IsPhysicallyActive) if (!LinksetRoot.IsPhysicallyActive)
{ {
// Clean up any old linkset shape and make sure the root shape is set to the root object.
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID); DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID);
return; // Note the 'finally' clause at the botton which will get executed. return; // Note the 'finally' clause at the botton which will get executed.
} }
// Get a new compound shape to build the linkset shape in. // Get a new compound shape to build the linkset shape in.
BSShape linksetShape = BSShapeCompound.GetReference(m_physicsScene); BSShape linksetShape = BSShapeCompound.GetReference(m_physicsScene);
// The center of mass for the linkset is the geometric center of the group.
// Compute a displacement for each component so it is relative to the center-of-mass. // Compute a displacement for each component so it is relative to the center-of-mass.
// Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass
OMV.Vector3 centerOfMassW = ComputeLinksetCenterOfMass(); OMV.Vector3 centerOfMassW = ComputeLinksetCenterOfMass();
OMV.Quaternion invRootOrientation = OMV.Quaternion.Normalize(OMV.Quaternion.Inverse(LinksetRoot.RawOrientation)); OMV.Quaternion invRootOrientation = OMV.Quaternion.Normalize(OMV.Quaternion.Inverse(LinksetRoot.RawOrientation));
OMV.Vector3 origRootPosition = LinksetRoot.RawPosition;
// 'centerDisplacement' is the value to subtract from children to give physical offset position // 'centerDisplacementV' is the vehicle relative distance from the simulator root position to the center-of-mass
OMV.Vector3 centerDisplacementV = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation; OMV.Vector3 centerDisplacementV = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation;
if (UseBulletSimRootOffsetHack || disableCOM) if (UseBulletSimRootOffsetHack || !BSParam.LinksetOffsetCenterOfMass)
{ {
// Zero everything if center-of-mass displacement is not being done.
centerDisplacementV = OMV.Vector3.Zero; centerDisplacementV = OMV.Vector3.Zero;
LinksetRoot.ClearDisplacement(); LinksetRoot.ClearDisplacement();
} }
else else
{ {
LinksetRoot.SetEffectiveCenterOfMassDisplacement(centerDisplacementV); // The actual center-of-mass could have been set by the user.
centerDisplacementV = LinksetRoot.SetEffectiveCenterOfMassDisplacement(centerDisplacementV);
} }
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,rootPos={1},com={2},comDisp={3}", DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,rootPos={1},com={2},comDisp={3}",
LinksetRoot.LocalID, LinksetRoot.RawPosition, centerOfMassW, centerDisplacementV); LinksetRoot.LocalID, origRootPosition, centerOfMassW, centerDisplacementV);
// Add the shapes of all the components of the linkset // Add the shapes of all the components of the linkset
int memberIndex = 1; int memberIndex = 1;
ForEachMember(delegate(BSPrimLinkable cPrim) ForEachMember(delegate(BSPrimLinkable cPrim)
{
if (IsRoot(cPrim))
{ {
// Root shape is always index zero. // Root shape is always index zero.
cPrim.LinksetChildIndex = IsRoot(cPrim) ? 0 : memberIndex; cPrim.LinksetChildIndex = 0;
}
else
{
cPrim.LinksetChildIndex = memberIndex;
memberIndex++;
}
// Get a reference to the shape of the child and add that shape to the linkset compound shape // Get a reference to the shape of the child for adding of that shape to the linkset compound shape
BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim); BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim);
OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacementV;
// Offset the child shape from the center-of-mass and rotate it to vehicle relative.
OMV.Vector3 offsetPos = (cPrim.RawPosition - origRootPosition) * invRootOrientation - centerDisplacementV;
OMV.Quaternion offsetRot = OMV.Quaternion.Normalize(cPrim.RawOrientation) * invRootOrientation; OMV.Quaternion offsetRot = OMV.Quaternion.Normalize(cPrim.RawOrientation) * invRootOrientation;
// Add the child shape to the compound shape being built
m_physicsScene.PE.AddChildShapeToCompoundShape(linksetShape.physShapeInfo, childShape.physShapeInfo, offsetPos, offsetRot); m_physicsScene.PE.AddChildShapeToCompoundShape(linksetShape.physShapeInfo, childShape.physShapeInfo, offsetPos, offsetRot);
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChild,indx={1},cShape={2},offPos={3},offRot={4}", DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChild,indx={1},cShape={2},offPos={3},offRot={4}",
LinksetRoot.LocalID, memberIndex, childShape, offsetPos, offsetRot); LinksetRoot.LocalID, cPrim.LinksetChildIndex, childShape, offsetPos, offsetRot);
// Since we are borrowing the shape of the child, disable the origional child body // Since we are borrowing the shape of the child, disable the origional child body
if (!IsRoot(cPrim)) if (!IsRoot(cPrim))
@ -386,8 +346,6 @@ public sealed class BSLinksetCompound : BSLinkset
cPrim.PhysBody.collisionType = CollisionType.LinksetChild; cPrim.PhysBody.collisionType = CollisionType.LinksetChild;
} }
memberIndex++;
return false; // 'false' says to move onto the next child in the list return false; // 'false' says to move onto the next child in the list
}); });
@ -409,8 +367,9 @@ public sealed class BSLinksetCompound : BSLinkset
{ {
// Enable the physical position updator to return the position and rotation of the root shape. // Enable the physical position updator to return the position and rotation of the root shape.
// This enables a feature in the C++ code to return the world coordinates of the first shape in the // This enables a feature in the C++ code to return the world coordinates of the first shape in the
// compound shape. This eleviates the need to offset the returned physical position by the // compound shape. This aleviates the need to offset the returned physical position by the
// center-of-mass offset. // center-of-mass offset.
// TODO: either debug this feature or remove it.
m_physicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE); m_physicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE);
} }
} }

View File

@ -188,6 +188,8 @@ public class BSVMotor : BSMotor
CurrentValue = current; CurrentValue = current;
return Step(timeStep); return Step(timeStep);
} }
// Given and error, computer a correction for this step.
// Simple scaling of the error by the timestep.
public virtual Vector3 StepError(float timeStep, Vector3 error) public virtual Vector3 StepError(float timeStep, Vector3 error)
{ {
if (!Enabled) return Vector3.Zero; if (!Enabled) return Vector3.Zero;
@ -221,7 +223,7 @@ public class BSVMotor : BSMotor
CurrentValue, TargetValue); CurrentValue, TargetValue);
LastError = BSMotor.InfiniteVector; LastError = BSMotor.InfiniteVector;
while (maxOutput-- > 0 && !LastError.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) while (maxOutput-- > 0 && !ErrorIsZero())
{ {
Vector3 lastStep = Step(timeStep); Vector3 lastStep = Step(timeStep);
MDetailLog("{0},BSVMotor.Test,{1},cur={2},tgt={3},lastError={4},lastStep={5}", MDetailLog("{0},BSVMotor.Test,{1},cur={2},tgt={3},lastError={4},lastStep={5}",
@ -375,7 +377,6 @@ public class BSPIDVMotor : BSVMotor
// The factors are vectors for the three dimensions. This is the proportional of each // The factors are vectors for the three dimensions. This is the proportional of each
// that is applied. This could be multiplied through the actual factors but it // that is applied. This could be multiplied through the actual factors but it
// is sometimes easier to manipulate the factors and their mix separately. // is sometimes easier to manipulate the factors and their mix separately.
// to
public Vector3 FactorMix; public Vector3 FactorMix;
// Arbritrary factor range. // Arbritrary factor range.
@ -413,8 +414,8 @@ public class BSPIDVMotor : BSVMotor
// If efficiency is high (1f), use a factor value that moves the error value to zero with little overshoot. // If efficiency is high (1f), use a factor value that moves the error value to zero with little overshoot.
// If efficiency is low (0f), use a factor value that overcorrects. // If efficiency is low (0f), use a factor value that overcorrects.
// TODO: might want to vary contribution of different factor depending on efficiency. // TODO: might want to vary contribution of different factor depending on efficiency.
float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f; // float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f;
// float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow; float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow;
proportionFactor = new Vector3(factor, factor, factor); proportionFactor = new Vector3(factor, factor, factor);
integralFactor = new Vector3(factor, factor, factor); integralFactor = new Vector3(factor, factor, factor);
@ -441,8 +442,8 @@ public class BSPIDVMotor : BSVMotor
+ derivitive / TimeScale * derivFactor * FactorMix.Z + derivitive / TimeScale * derivFactor * FactorMix.Z
; ;
MDetailLog("{0}, BSPIDVMotor.step,ts={1},err={2},runnInt={3},deriv={4},ret={5}", MDetailLog("{0}, BSPIDVMotor.step,ts={1},err={2},lerr={3},runnInt={4},deriv={5},ret={6}",
BSScene.DetailLogZero, timeStep, error, RunningIntegration, derivitive, ret); BSScene.DetailLogZero, timeStep, error, LastError, RunningIntegration, derivitive, ret);
return ret; return ret;
} }

View File

@ -155,7 +155,12 @@ public static class BSParam
public static Vector3 VehicleInertiaFactor { get; private set; } public static Vector3 VehicleInertiaFactor { get; private set; }
public static float VehicleGroundGravityFudge { get; private set; } public static float VehicleGroundGravityFudge { get; private set; }
public static float VehicleAngularBankingTimescaleFudge { get; private set; } public static float VehicleAngularBankingTimescaleFudge { get; private set; }
public static bool VehicleDebuggingEnable { get; private set; } public static bool VehicleEnableLinearDeflection { get; private set; }
public static bool VehicleLinearDeflectionNotCollidingNoZ { get; private set; }
public static bool VehicleEnableAngularVerticalAttraction { get; private set; }
public static int VehicleAngularVerticalAttractionAlgorithm { get; private set; }
public static bool VehicleEnableAngularDeflection { get; private set; }
public static bool VehicleEnableAngularBanking { get; private set; }
// Convex Hulls // Convex Hulls
public static int CSHullMaxDepthSplit { get; private set; } public static int CSHullMaxDepthSplit { get; private set; }
@ -176,6 +181,7 @@ public static class BSParam
// Linkset implementation parameters // Linkset implementation parameters
public static float LinksetImplementation { get; private set; } public static float LinksetImplementation { get; private set; }
public static bool LinksetOffsetCenterOfMass { get; private set; }
public static bool LinkConstraintUseFrameOffset { get; private set; } public static bool LinkConstraintUseFrameOffset { get; private set; }
public static bool LinkConstraintEnableTransMotor { get; private set; } public static bool LinkConstraintEnableTransMotor { get; private set; }
public static float LinkConstraintTransMotorMaxVel { get; private set; } public static float LinkConstraintTransMotorMaxVel { get; private set; }
@ -605,8 +611,18 @@ public static class BSParam
0.2f ), 0.2f ),
new ParameterDefn<float>("VehicleAngularBankingTimescaleFudge", "Factor to multiple angular banking timescale. Tune to increase realism.", new ParameterDefn<float>("VehicleAngularBankingTimescaleFudge", "Factor to multiple angular banking timescale. Tune to increase realism.",
60.0f ), 60.0f ),
new ParameterDefn<bool>("VehicleDebuggingEnable", "Turn on/off vehicle debugging", new ParameterDefn<bool>("VehicleEnableLinearDeflection", "Turn on/off vehicle linear deflection effect",
false ), true ),
new ParameterDefn<bool>("VehicleLinearDeflectionNotCollidingNoZ", "Turn on/off linear deflection Z effect on non-colliding vehicles",
true ),
new ParameterDefn<bool>("VehicleEnableAngularVerticalAttraction", "Turn on/off vehicle angular vertical attraction effect",
true ),
new ParameterDefn<int>("VehicleAngularVerticalAttractionAlgorithm", "Select vertical attraction algo. You need to look at the source.",
0 ),
new ParameterDefn<bool>("VehicleEnableAngularDeflection", "Turn on/off vehicle angular deflection effect",
true ),
new ParameterDefn<bool>("VehicleEnableAngularBanking", "Turn on/off vehicle angular banking effect",
true ),
new ParameterDefn<float>("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", new ParameterDefn<float>("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
0f, 0f,
@ -684,6 +700,8 @@ public static class BSParam
new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
(float)BSLinkset.LinksetImplementation.Compound ), (float)BSLinkset.LinksetImplementation.Compound ),
new ParameterDefn<bool>("LinksetOffsetCenterOfMass", "If 'true', compute linkset center-of-mass and offset linkset position to account for same",
false ),
new ParameterDefn<bool>("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", new ParameterDefn<bool>("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.",
false ), false ),
new ParameterDefn<bool>("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", new ParameterDefn<bool>("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints",

View File

@ -90,6 +90,8 @@ public abstract class BSPhysObject : PhysicsActor
PhysBody = new BulletBody(localID); PhysBody = new BulletBody(localID);
PhysShape = new BSShapeNull(); PhysShape = new BSShapeNull();
UserSetCenterOfMassDisplacement = null;
PrimAssetState = PrimAssetCondition.Unknown; PrimAssetState = PrimAssetCondition.Unknown;
// Default material type. Also sets Friction, Restitution and Density. // Default material type. Also sets Friction, Restitution and Density.
@ -180,6 +182,7 @@ public abstract class BSPhysObject : PhysicsActor
Material = (MaterialAttributes.Material)material; Material = (MaterialAttributes.Material)material;
// Setting the material sets the material attributes also. // Setting the material sets the material attributes also.
// TODO: decide if this is necessary -- the simulator does this.
MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
Friction = matAttrib.friction; Friction = matAttrib.friction;
Restitution = matAttrib.restitution; Restitution = matAttrib.restitution;
@ -194,10 +197,10 @@ public abstract class BSPhysObject : PhysicsActor
// Update the physical location and motion of the object. Called with data from Bullet. // Update the physical location and motion of the object. Called with data from Bullet.
public abstract void UpdateProperties(EntityProperties entprop); public abstract void UpdateProperties(EntityProperties entprop);
public abstract OMV.Vector3 RawPosition { get; set; } public virtual OMV.Vector3 RawPosition { get; set; }
public abstract OMV.Vector3 ForcePosition { get; set; } public abstract OMV.Vector3 ForcePosition { get; set; }
public abstract OMV.Quaternion RawOrientation { get; set; } public virtual OMV.Quaternion RawOrientation { get; set; }
public abstract OMV.Quaternion ForceOrientation { get; set; } public abstract OMV.Quaternion ForceOrientation { get; set; }
public OMV.Vector3 RawVelocity { get; set; } public OMV.Vector3 RawVelocity { get; set; }

View File

@ -51,12 +51,8 @@ public class BSPrim : BSPhysObject
private bool _isSelected; private bool _isSelected;
private bool _isVolumeDetect; private bool _isVolumeDetect;
// _position is what the simulator thinks the positions of the prim is.
private OMV.Vector3 _position;
private float _mass; // the mass of this object private float _mass; // the mass of this object
private OMV.Vector3 _acceleration; private OMV.Vector3 _acceleration;
private OMV.Quaternion _orientation;
private int _physicsActorType; private int _physicsActorType;
private bool _isPhysical; private bool _isPhysical;
private bool _flying; private bool _flying;
@ -88,10 +84,10 @@ public class BSPrim : BSPhysObject
{ {
// m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
_physicsActorType = (int)ActorTypes.Prim; _physicsActorType = (int)ActorTypes.Prim;
_position = pos; RawPosition = pos;
_size = size; _size = size;
Scale = size; // prims are the size the user wants them to be (different for BSCharactes). Scale = size; // prims are the size the user wants them to be (different for BSCharactes).
_orientation = rotation; RawOrientation = rotation;
_buoyancy = 0f; _buoyancy = 0f;
RawVelocity = OMV.Vector3.Zero; RawVelocity = OMV.Vector3.Zero;
_rotationalVelocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero;
@ -270,46 +266,42 @@ public class BSPrim : BSPhysObject
return; return;
} }
public override OMV.Vector3 RawPosition
{
get { return _position; }
set { _position = value; }
}
public override OMV.Vector3 Position { public override OMV.Vector3 Position {
get { get {
// don't do the GetObjectPosition for root elements because this function is called a zillion times. // don't do the GetObjectPosition for root elements because this function is called a zillion times.
// _position = ForcePosition; // RawPosition = ForcePosition;
return _position; return RawPosition;
} }
set { set {
// If the position must be forced into the physics engine, use ForcePosition. // If the position must be forced into the physics engine, use ForcePosition.
// All positions are given in world positions. // All positions are given in world positions.
if (_position == value) if (RawPosition == value)
{ {
DetailLog("{0},BSPrim.setPosition,call,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation); DetailLog("{0},BSPrim.setPosition,call,positionNotChanging,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
return; return;
} }
_position = value; RawPosition = value;
PositionSanityCheck(false); PositionSanityCheck(false);
PhysScene.TaintedObject("BSPrim.setPosition", delegate() PhysScene.TaintedObject("BSPrim.setPosition", delegate()
{ {
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
ForcePosition = _position; ForcePosition = RawPosition;
}); });
} }
} }
// NOTE: overloaded by BSPrimDisplaced to handle offset for center-of-gravity.
public override OMV.Vector3 ForcePosition { public override OMV.Vector3 ForcePosition {
get { get {
_position = PhysScene.PE.GetPosition(PhysBody); RawPosition = PhysScene.PE.GetPosition(PhysBody);
return _position; return RawPosition;
} }
set { set {
_position = value; RawPosition = value;
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
PhysScene.PE.SetTranslation(PhysBody, _position, _orientation); PhysScene.PE.SetTranslation(PhysBody, RawPosition, RawOrientation);
ActivateIfPhysical(false); ActivateIfPhysical(false);
} }
} }
@ -343,10 +335,10 @@ public class BSPrim : BSPhysObject
float targetHeight = terrainHeight + (Size.Z / 2f); float targetHeight = terrainHeight + (Size.Z / 2f);
// If the object is below ground it just has to be moved up because pushing will // If the object is below ground it just has to be moved up because pushing will
// not get it through the terrain // not get it through the terrain
_position.Z = targetHeight; RawPosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, targetHeight);
if (inTaintTime) if (inTaintTime)
{ {
ForcePosition = _position; ForcePosition = RawPosition;
} }
// If we are throwing the object around, zero its other forces // If we are throwing the object around, zero its other forces
ZeroMotion(inTaintTime); ZeroMotion(inTaintTime);
@ -355,7 +347,7 @@ public class BSPrim : BSPhysObject
if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
{ {
float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(_position); float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(RawPosition);
// TODO: a floating motor so object will bob in the water // TODO: a floating motor so object will bob in the water
if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f) if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f)
{ {
@ -364,7 +356,7 @@ public class BSPrim : BSPhysObject
// Apply upforce and overcome gravity. // Apply upforce and overcome gravity.
OMV.Vector3 correctionForce = upForce - PhysScene.DefaultGravity; OMV.Vector3 correctionForce = upForce - PhysScene.DefaultGravity;
DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, RawPosition, upForce, correctionForce);
AddForce(correctionForce, false, inTaintTime); AddForce(correctionForce, false, inTaintTime);
ret = true; ret = true;
} }
@ -383,11 +375,11 @@ public class BSPrim : BSPhysObject
uint wayOutThere = Constants.RegionSize * Constants.RegionSize; uint wayOutThere = Constants.RegionSize * Constants.RegionSize;
// There have been instances of objects getting thrown way out of bounds and crashing // There have been instances of objects getting thrown way out of bounds and crashing
// the border crossing code. // the border crossing code.
if ( _position.X < -Constants.RegionSize || _position.X > wayOutThere if ( RawPosition.X < -Constants.RegionSize || RawPosition.X > wayOutThere
|| _position.Y < -Constants.RegionSize || _position.Y > wayOutThere || RawPosition.Y < -Constants.RegionSize || RawPosition.Y > wayOutThere
|| _position.Z < -Constants.RegionSize || _position.Z > wayOutThere) || RawPosition.Z < -Constants.RegionSize || RawPosition.Z > wayOutThere)
{ {
_position = new OMV.Vector3(10, 10, 50); RawPosition = new OMV.Vector3(10, 10, 50);
ZeroMotion(inTaintTime); ZeroMotion(inTaintTime);
ret = true; ret = true;
} }
@ -713,23 +705,19 @@ public class BSPrim : BSPhysObject
get { return _acceleration; } get { return _acceleration; }
set { _acceleration = value; } set { _acceleration = value; }
} }
public override OMV.Quaternion RawOrientation
{
get { return _orientation; }
set { _orientation = value; }
}
public override OMV.Quaternion Orientation { public override OMV.Quaternion Orientation {
get { get {
return _orientation; return RawOrientation;
} }
set { set {
if (_orientation == value) if (RawOrientation == value)
return; return;
_orientation = value; RawOrientation = value;
PhysScene.TaintedObject("BSPrim.setOrientation", delegate() PhysScene.TaintedObject("BSPrim.setOrientation", delegate()
{ {
ForceOrientation = _orientation; ForceOrientation = RawOrientation;
}); });
} }
} }
@ -738,14 +726,14 @@ public class BSPrim : BSPhysObject
{ {
get get
{ {
_orientation = PhysScene.PE.GetOrientation(PhysBody); RawOrientation = PhysScene.PE.GetOrientation(PhysBody);
return _orientation; return RawOrientation;
} }
set set
{ {
_orientation = value; RawOrientation = value;
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
PhysScene.PE.SetTranslation(PhysBody, _position, _orientation); PhysScene.PE.SetTranslation(PhysBody, RawPosition, RawOrientation);
} }
} }
public override int PhysicsActorType { public override int PhysicsActorType {
@ -802,6 +790,7 @@ public class BSPrim : BSPhysObject
// isSolid: other objects bounce off of this object // isSolid: other objects bounce off of this object
// isVolumeDetect: other objects pass through but can generate collisions // isVolumeDetect: other objects pass through but can generate collisions
// collisionEvents: whether this object returns collision events // collisionEvents: whether this object returns collision events
// NOTE: overloaded by BSPrimLinkable to also update linkset physical parameters.
public virtual void UpdatePhysicalParameters() public virtual void UpdatePhysicalParameters()
{ {
if (!PhysBody.HasPhysicalBody) if (!PhysBody.HasPhysicalBody)
@ -888,7 +877,7 @@ public class BSPrim : BSPhysObject
// PhysicsScene.PE.ClearAllForces(BSBody); // PhysicsScene.PE.ClearAllForces(BSBody);
// For good measure, make sure the transform is set through to the motion state // For good measure, make sure the transform is set through to the motion state
ForcePosition = _position; ForcePosition = RawPosition;
ForceVelocity = RawVelocity; ForceVelocity = RawVelocity;
ForceRotationalVelocity = _rotationalVelocity; ForceRotationalVelocity = _rotationalVelocity;
@ -1125,7 +1114,9 @@ public class BSPrim : BSPhysObject
OMV.Vector3 addForce = force; OMV.Vector3 addForce = force;
PhysScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() PhysScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate()
{ {
// Bullet adds this central force to the total force for this tick // Bullet adds this central force to the total force for this tick.
// Deep down in Bullet:
// linearVelocity += totalForce / mass * timeStep;
DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce);
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
@ -1493,6 +1484,8 @@ public class BSPrim : BSPhysObject
returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass); returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass);
// DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3}", LocalID, Density, volume, returnMass); // DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3}", LocalID, Density, volume, returnMass);
DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3},pathB={4},pathE={5},profB={6},profE={7},siz={8}",
LocalID, Density, volume, returnMass, pathBegin, pathEnd, profileBegin, profileEnd, _size);
return returnMass; return returnMass;
}// end CalculateMass }// end CalculateMass
@ -1528,6 +1521,8 @@ public class BSPrim : BSPhysObject
// The physics engine says that properties have updated. Update same and inform // The physics engine says that properties have updated. Update same and inform
// the world that things have changed. // the world that things have changed.
// NOTE: BSPrim.UpdateProperties is overloaded by BSPrimLinkable which modifies updates from root and children prims.
// NOTE: BSPrim.UpdateProperties is overloaded by BSPrimDisplaced which handles mapping physical position to simulator position.
public override void UpdateProperties(EntityProperties entprop) public override void UpdateProperties(EntityProperties entprop)
{ {
// Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator. // Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator.
@ -1536,8 +1531,8 @@ public class BSPrim : BSPhysObject
// DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
// Assign directly to the local variables so the normal set actions do not happen // Assign directly to the local variables so the normal set actions do not happen
_position = entprop.Position; RawPosition = entprop.Position;
_orientation = entprop.Rotation; RawOrientation = entprop.Rotation;
// DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be
// very sensitive to velocity changes. // very sensitive to velocity changes.
if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold)) if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold))
@ -1550,21 +1545,19 @@ public class BSPrim : BSPhysObject
// The sanity check can change the velocity and/or position. // The sanity check can change the velocity and/or position.
if (PositionSanityCheck(true /* inTaintTime */ )) if (PositionSanityCheck(true /* inTaintTime */ ))
{ {
entprop.Position = _position; entprop.Position = RawPosition;
entprop.Velocity = RawVelocity; entprop.Velocity = RawVelocity;
entprop.RotationalVelocity = _rotationalVelocity; entprop.RotationalVelocity = _rotationalVelocity;
entprop.Acceleration = _acceleration; entprop.Acceleration = _acceleration;
} }
OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG OMV.Vector3 direction = OMV.Vector3.UnitX * RawOrientation; // DEBUG DEBUG DEBUG
DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction); DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction);
// remember the current and last set values // remember the current and last set values
LastEntityProperties = CurrentEntityProperties; LastEntityProperties = CurrentEntityProperties;
CurrentEntityProperties = entprop; CurrentEntityProperties = entprop;
// Note that BSPrim can be overloaded by BSPrimLinkable which controls updates from root and children prims.
PhysScene.PostUpdate(this); PhysScene.PostUpdate(this);
} }
} }

View File

@ -23,11 +23,6 @@
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The quotations from http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial
* are Copyright (c) 2009 Linden Research, Inc and are used under their license
* of Creative Commons Attribution-Share Alike 3.0
* (http://creativecommons.org/licenses/by-sa/3.0/).
*/ */
using System; using System;
@ -44,14 +39,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{ {
public class BSPrimDisplaced : BSPrim public class BSPrimDisplaced : BSPrim
{ {
// The purpose of this module is to do any mapping between what the simulator thinks // The purpose of this subclass is to do any mapping between what the simulator thinks
// the prim position and orientation is and what the physical position/orientation. // the prim position and orientation is and what the physical position/orientation.
// This difference happens because Bullet assumes the center-of-mass is the <0,0,0> // This difference happens because Bullet assumes the center-of-mass is the <0,0,0>
// of the prim/linkset. The simulator tracks the location of the prim/linkset by // of the prim/linkset. The simulator, on the other hand, tracks the location of
// the location of the root prim. So, if center-of-mass is anywhere but the origin // the prim/linkset by the location of the root prim. So, if center-of-mass is anywhere
// of the root prim, the physical origin is displaced from the simulator origin. // but the origin of the root prim, the physical origin is displaced from the simulator origin.
// //
// This routine works by capturing the Force* setting of position/orientation/... and // This routine works by capturing ForcePosition and
// adjusting the simulator values (being set) into the physical values. // adjusting the simulator values (being set) into the physical values.
// The conversion is also done in the opposite direction (physical origin -> simulator origin). // The conversion is also done in the opposite direction (physical origin -> simulator origin).
// //
@ -59,8 +54,8 @@ public class BSPrimDisplaced : BSPrim
// are converted into simulator origin values before being passed to the base // are converted into simulator origin values before being passed to the base
// class. // class.
// PositionDisplacement is the vehicle relative distance from the root prim position to the center-of-mass.
public virtual OMV.Vector3 PositionDisplacement { get; set; } public virtual OMV.Vector3 PositionDisplacement { get; set; }
public virtual OMV.Quaternion OrientationDisplacement { get; set; }
public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
@ -69,50 +64,82 @@ public class BSPrimDisplaced : BSPrim
ClearDisplacement(); ClearDisplacement();
} }
// Clears any center-of-mass displacement introduced by linksets, etc.
// Does not clear the displacement set by the user.
public void ClearDisplacement() public void ClearDisplacement()
{ {
if (UserSetCenterOfMassDisplacement.HasValue)
PositionDisplacement = (OMV.Vector3)UserSetCenterOfMassDisplacement;
else
PositionDisplacement = OMV.Vector3.Zero; PositionDisplacement = OMV.Vector3.Zero;
OrientationDisplacement = OMV.Quaternion.Identity;
} }
// Set this sets and computes the displacement from the passed prim to the center-of-mass. // Set this sets and computes the displacement from the passed prim to the center-of-mass.
// A user set value for center-of-mass overrides whatever might be passed in here. // A user set value for center-of-mass overrides whatever might be passed in here.
// The displacement is in local coordinates (relative to root prim in linkset oriented coordinates). // The displacement is in local coordinates (relative to root prim in linkset oriented coordinates).
public virtual void SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement) // Returns the relative offset from the root position to the center-of-mass.
// Called at taint time.
public virtual Vector3 SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement)
{ {
PhysScene.AssertInTaintTime("BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement");
Vector3 comDisp; Vector3 comDisp;
if (UserSetCenterOfMassDisplacement.HasValue) if (UserSetCenterOfMassDisplacement.HasValue)
comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement; comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement;
else else
comDisp = centerOfMassDisplacement; comDisp = centerOfMassDisplacement;
// Eliminate any jitter caused be very slight differences in masses and positions
if (comDisp.ApproxEquals(Vector3.Zero, 0.01f) )
comDisp = Vector3.Zero;
DetailLog("{0},BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement,userSet={1},comDisp={2}", DetailLog("{0},BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement,userSet={1},comDisp={2}",
LocalID, UserSetCenterOfMassDisplacement.HasValue, comDisp); LocalID, UserSetCenterOfMassDisplacement.HasValue, comDisp);
if (comDisp == Vector3.Zero) if ( !comDisp.ApproxEquals(PositionDisplacement, 0.01f) )
{ {
// If there is no diplacement. Things get reset. // Displacement setting is changing.
PositionDisplacement = OMV.Vector3.Zero; // The relationship between the physical object and simulated object must be aligned.
OrientationDisplacement = OMV.Quaternion.Identity;
}
else
{
// Remember the displacement from root as well as the origional rotation of the
// new center-of-mass.
PositionDisplacement = comDisp; PositionDisplacement = comDisp;
OrientationDisplacement = OMV.Quaternion.Identity; this.ForcePosition = RawPosition;
}
} }
return PositionDisplacement;
}
// 'ForcePosition' is the one way to set the physical position of the body in the physics engine.
// Displace the simulator idea of position (center of root prim) to the physical position.
public override Vector3 ForcePosition public override Vector3 ForcePosition
{ {
get { return base.ForcePosition; } get {
OMV.Vector3 physPosition = PhysScene.PE.GetPosition(PhysBody);
if (PositionDisplacement != OMV.Vector3.Zero)
{
// If there is some displacement, return the physical position (center-of-mass)
// location minus the displacement to give the center of the root prim.
OMV.Vector3 displacement = PositionDisplacement * ForceOrientation;
DetailLog("{0},BSPrimDisplaced.ForcePosition,get,physPos={1},disp={2},simPos={3}",
LocalID, physPosition, displacement, physPosition - displacement);
physPosition -= displacement;
}
RawPosition = physPosition;
return physPosition;
}
set set
{ {
if (PositionDisplacement != OMV.Vector3.Zero) if (PositionDisplacement != OMV.Vector3.Zero)
{ {
OMV.Vector3 displacedPos = value - (PositionDisplacement * RawOrientation); // This value is the simulator's idea of where the prim is: the center of the root prim
DetailLog("{0},BSPrimDisplaced.ForcePosition,val={1},disp={2},newPos={3}", LocalID, value, PositionDisplacement, displacedPos); RawPosition = value;
base.ForcePosition = displacedPos;
// Move the passed root prim postion to the center-of-mass position and set in the physics engine.
OMV.Vector3 displacement = PositionDisplacement * RawOrientation;
OMV.Vector3 displacedPos = RawPosition + displacement;
DetailLog("{0},BSPrimDisplaced.ForcePosition,set,simPos={1},disp={2},physPos={3}",
LocalID, RawPosition, displacement, displacedPos);
if (PhysBody.HasPhysicalBody)
{
PhysScene.PE.SetTranslation(PhysBody, displacedPos, RawOrientation);
ActivateIfPhysical(false);
}
} }
else else
{ {
@ -121,25 +148,12 @@ public class BSPrimDisplaced : BSPrim
} }
} }
public override Quaternion ForceOrientation // These are also overridden by BSPrimLinkable if the prim can be part of a linkset
{
get { return base.ForceOrientation; }
set
{
// TODO:
base.ForceOrientation = value;
}
}
// TODO: decide if this is the right place for these variables.
// Somehow incorporate the optional settability by the user.
// Is this used?
public override OMV.Vector3 CenterOfMass public override OMV.Vector3 CenterOfMass
{ {
get { return RawPosition; } get { return RawPosition; }
} }
// Is this used?
public override OMV.Vector3 GeometricCenter public override OMV.Vector3 GeometricCenter
{ {
get { return RawPosition; } get { return RawPosition; }
@ -148,15 +162,18 @@ public class BSPrimDisplaced : BSPrim
public override void UpdateProperties(EntityProperties entprop) public override void UpdateProperties(EntityProperties entprop)
{ {
// Undo any center-of-mass displacement that might have been done. // Undo any center-of-mass displacement that might have been done.
if (PositionDisplacement != OMV.Vector3.Zero || OrientationDisplacement != OMV.Quaternion.Identity) if (PositionDisplacement != OMV.Vector3.Zero)
{ {
// Correct for any rotation around the center-of-mass // The origional shape was offset from 'zero' by PositionDisplacement.
// TODO!!! // These physical location must be back converted to be centered around the displaced
// root shape.
OMV.Vector3 displacedPos = entprop.Position + (PositionDisplacement * entprop.Rotation); // Move the returned center-of-mass location to the root prim location.
DetailLog("{0},BSPrimDisplaced.ForcePosition,physPos={1},disp={2},newPos={3}", LocalID, entprop.Position, PositionDisplacement, displacedPos); OMV.Vector3 displacement = PositionDisplacement * entprop.Rotation;
OMV.Vector3 displacedPos = entprop.Position - displacement;
DetailLog("{0},BSPrimDisplaced.UpdateProperties,physPos={1},disp={2},simPos={3}",
LocalID, entprop.Position, displacement, displacedPos);
entprop.Position = displacedPos; entprop.Position = displacedPos;
// entprop.Rotation = something;
} }
base.UpdateProperties(entprop); base.UpdateProperties(entprop);

View File

@ -37,6 +37,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{ {
public class BSPrimLinkable : BSPrimDisplaced public class BSPrimLinkable : BSPrimDisplaced
{ {
// The purpose of this subclass is to add linkset functionality to the prim. This overrides
// operations necessary for keeping the linkset created and, additionally, this
// calls the linkset implementation for its creation and management.
// This adds the overrides for link() and delink() so the prim is linkable.
public BSLinkset Linkset { get; set; } public BSLinkset Linkset { get; set; }
// The index of this child prim. // The index of this child prim.
public int LinksetChildIndex { get; set; } public int LinksetChildIndex { get; set; }
@ -69,8 +75,8 @@ public class BSPrimLinkable : BSPrimDisplaced
BSPrimLinkable parent = obj as BSPrimLinkable; BSPrimLinkable parent = obj as BSPrimLinkable;
if (parent != null) if (parent != null)
{ {
BSPhysObject parentBefore = Linkset.LinksetRoot; BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG
int childrenBefore = Linkset.NumberOfChildren; int childrenBefore = Linkset.NumberOfChildren; // DEBUG
Linkset = parent.Linkset.AddMeToLinkset(this); Linkset = parent.Linkset.AddMeToLinkset(this);
@ -85,8 +91,8 @@ public class BSPrimLinkable : BSPrimDisplaced
// TODO: decide if this parent checking needs to happen at taint time // TODO: decide if this parent checking needs to happen at taint time
// Race condition here: if link() and delink() in same simulation tick, the delink will not happen // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
BSPhysObject parentBefore = Linkset.LinksetRoot; BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG
int childrenBefore = Linkset.NumberOfChildren; int childrenBefore = Linkset.NumberOfChildren; // DEBUG
Linkset = Linkset.RemoveMeFromLinkset(this); Linkset = Linkset.RemoveMeFromLinkset(this);
@ -128,6 +134,17 @@ public class BSPrimLinkable : BSPrimDisplaced
get { return Linkset.LinksetMass; } get { return Linkset.LinksetMass; }
} }
public override OMV.Vector3 CenterOfMass
{
get { return Linkset.CenterOfMass; }
}
public override OMV.Vector3 GeometricCenter
{
get { return Linkset.GeometricCenter; }
}
// Refresh the linkset structure and parameters when the prim's physical parameters are changed.
public override void UpdatePhysicalParameters() public override void UpdatePhysicalParameters()
{ {
base.UpdatePhysicalParameters(); base.UpdatePhysicalParameters();
@ -139,14 +156,18 @@ public class BSPrimLinkable : BSPrimDisplaced
Linkset.Refresh(this); Linkset.Refresh(this);
} }
// When the prim is made dynamic or static, the linkset needs to change.
protected override void MakeDynamic(bool makeStatic) protected override void MakeDynamic(bool makeStatic)
{ {
base.MakeDynamic(makeStatic); base.MakeDynamic(makeStatic);
if (Linkset != null) // null can happen during initialization
{
if (makeStatic) if (makeStatic)
Linkset.MakeStatic(this); Linkset.MakeStatic(this);
else else
Linkset.MakeDynamic(this); Linkset.MakeDynamic(this);
} }
}
// Body is being taken apart. Remove physical dependencies and schedule a rebuild. // Body is being taken apart. Remove physical dependencies and schedule a rebuild.
protected override void RemoveDependencies() protected override void RemoveDependencies()
@ -155,6 +176,8 @@ public class BSPrimLinkable : BSPrimDisplaced
base.RemoveDependencies(); base.RemoveDependencies();
} }
// Called after a simulation step for the changes in physical object properties.
// Do any filtering/modification needed for linksets.
public override void UpdateProperties(EntityProperties entprop) public override void UpdateProperties(EntityProperties entprop)
{ {
if (Linkset.IsRoot(this)) if (Linkset.IsRoot(this))
@ -176,6 +199,7 @@ public class BSPrimLinkable : BSPrimDisplaced
Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
} }
// Called after a simulation step to post a collision with this object.
public override bool Collide(uint collidingWith, BSPhysObject collidee, public override bool Collide(uint collidingWith, BSPhysObject collidee,
OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
{ {

View File

@ -1,4 +1,4 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
@ -648,7 +648,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
simTime = Util.EnvironmentTickCountSubtract(beforeTime); simTime = Util.EnvironmentTickCountSubtract(beforeTime);
if (PhysicsLogging.Enabled) if (PhysicsLogging.Enabled)
{ {
DetailLog("{0},DoPhysicsStep,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}", DetailLog("{0},DoPhysicsStep,complete,frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}",
DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps,
updatedEntityCount, collidersCount, ObjectsWithCollisions.Count); updatedEntityCount, collidersCount, ObjectsWithCollisions.Count);
} }
@ -785,7 +785,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
{ {
// The simulation of the time interval took less than realtime. // The simulation of the time interval took less than realtime.
// Do a sleep for the rest of realtime. // Do a sleep for the rest of realtime.
DetailLog("{0},BulletSPluginPhysicsThread,sleeping={1}", BSScene.DetailLogZero, simulationTimeVsRealtimeDifferenceMS);
Thread.Sleep(simulationTimeVsRealtimeDifferenceMS); Thread.Sleep(simulationTimeVsRealtimeDifferenceMS);
} }
else else

View File

@ -3,25 +3,21 @@ CURRENT PROBLEMS TO FIX AND/OR LOOK AT
Vehicle buoyancy. Computed correctly? Possibly creating very large effective mass. Vehicle buoyancy. Computed correctly? Possibly creating very large effective mass.
Interaction of llSetBuoyancy and vehicle buoyancy. Should be additive? Interaction of llSetBuoyancy and vehicle buoyancy. Should be additive?
Negative buoyancy computed correctly Negative buoyancy computed correctly
Center-of-gravity
Computation of mesh mass. How done? How should it be done? Computation of mesh mass. How done? How should it be done?
Script changing rotation of child prim while vehicle moving (eg turning wheel) causes
the wheel to appear to jump back. Looks like sending position from previous update.
Enable vehicle border crossings (at least as poorly as ODE) Enable vehicle border crossings (at least as poorly as ODE)
Terrain skirts Terrain skirts
Avatar created in previous region and not new region when crossing border Avatar created in previous region and not new region when crossing border
Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) Vehicle recreated in new sim at small Z value (offset from root value?) (DONE)
User settable terrain mesh
Allow specifying as convex or concave and use different getHeight functions depending
Boats, when turning nose down into the water
Acts like rotation around Z is also effecting rotation around X and Y
Deleting a linkset while standing on the root will leave the physical shape of the root behind. Deleting a linkset while standing on the root will leave the physical shape of the root behind.
Not sure if it is because standing on it. Done with large prim linksets. Not sure if it is because standing on it. Done with large prim linksets.
Linkset child rotations. Linkset child rotations.
Nebadon spiral tube has middle sections which are rotated wrong. Nebadon spiral tube has middle sections which are rotated wrong.
Select linked spiral tube. Delink and note where the middle section ends up. Select linked spiral tube. Delink and note where the middle section ends up.
Refarb compound linkset creation to create a pseudo-root for center-of-mass
Let children change their shape to physical indendently and just add shapes to compound
Vehicle angular vertical attraction
vehicle angular banking
Center-of-gravity
Vehicle angular deflection
Preferred orientation angular correction fix
Teravus llMoveToTarget script debug Teravus llMoveToTarget script debug
Mixing of hover, buoyancy/gravity, moveToTarget, into one force Mixing of hover, buoyancy/gravity, moveToTarget, into one force
Setting hover height to zero disables hover even if hover flags are on (from SL wiki) Setting hover height to zero disables hover even if hover flags are on (from SL wiki)
@ -33,10 +29,16 @@ Vehicle script tuning/debugging
Avanti speed script Avanti speed script
Weapon shooter script Weapon shooter script
Move material definitions (friction, ...) into simulator. Move material definitions (friction, ...) into simulator.
osGetPhysicsEngineVerion() and create a version code for the C++ DLL
One sided meshes? Should terrain be built into a closed shape? One sided meshes? Should terrain be built into a closed shape?
When meshes get partially wedged into the terrain, they cannot push themselves out. When meshes get partially wedged into the terrain, they cannot push themselves out.
It is possible that Bullet processes collisions whether entering or leaving a mesh. It is possible that Bullet processes collisions whether entering or leaving a mesh.
Ref: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4869 Ref: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4869
Small physical objects do not interact correctly
Create chain of .5x.5x.1 torui and make all but top physical so to hang.
The chain will fall apart and pairs will dance around on ground
Chains of 1x1x.2 will stay connected but will dance.
Chains above 2x2x.4 are more stable and get stablier as torui get larger.
VEHICLES TODO LIST: VEHICLES TODO LIST:
================================================= =================================================
@ -45,14 +47,12 @@ LINEAR_MOTOR_DIRECTION values should be clamped to reasonable numbers.
Same for other velocity settings. Same for other velocity settings.
UBit improvements to remove rubber-banding of avatars sitting on vehicle child prims: UBit improvements to remove rubber-banding of avatars sitting on vehicle child prims:
https://github.com/UbitUmarov/Ubit-opensim https://github.com/UbitUmarov/Ubit-opensim
Vehicles (Move smoothly)
Some vehicles should not be able to turn if no speed or off ground. Some vehicles should not be able to turn if no speed or off ground.
Cannot edit/move a vehicle being ridden: it jumps back to the origional position. Cannot edit/move a vehicle being ridden: it jumps back to the origional position.
Neb car jiggling left and right Neb car jiggling left and right
Happens on terrain and any other mesh object. Flat cubes are much smoother. Happens on terrain and any other mesh object. Flat cubes are much smoother.
This has been reduced but not eliminated. This has been reduced but not eliminated.
Implement referenceFrame for all the motion routines. Implement referenceFrame for all the motion routines.
For limitMotorUp, use raycast down to find if vehicle is in the air.
Verify llGetVel() is returning a smooth and good value for vehicle movement. Verify llGetVel() is returning a smooth and good value for vehicle movement.
llGetVel() should return the root's velocity if requested in a child prim. llGetVel() should return the root's velocity if requested in a child prim.
Implement function efficiency for lineaar and angular motion. Implement function efficiency for lineaar and angular motion.
@ -93,29 +93,15 @@ Revisit CollisionMargin. Builders notice the 0.04 spacing between prims.
Duplicating a physical prim causes old prim to jump away Duplicating a physical prim causes old prim to jump away
Dup a phys prim and the original become unselected and thus interacts w/ selected prim. Dup a phys prim and the original become unselected and thus interacts w/ selected prim.
Scenes with hundred of thousands of static objects take a lot of physics CPU time. Scenes with hundred of thousands of static objects take a lot of physics CPU time.
BSPrim.Force should set a continious force on the prim. The force should be
applied each tick. Some limits?
Gun sending shooter flying. Gun sending shooter flying.
Collision margin (gap between physical objects lying on each other) Collision margin (gap between physical objects lying on each other)
Boundry checking (crashes related to crossing boundry) Boundry checking (crashes related to crossing boundry)
Add check for border edge position for avatars and objects. Add check for border edge position for avatars and objects.
Verify the events are created for border crossings. Verify the events are created for border crossings.
Avatar rotation (check out changes to ScenePresence for physical rotation)
Avatar running (what does phys engine need to do?)
Small physical objects do not interact correctly
Create chain of .5x.5x.1 torui and make all but top physical so to hang.
The chain will fall apart and pairs will dance around on ground
Chains of 1x1x.2 will stay connected but will dance.
Chains above 2x2x.4 are more stable and get stablier as torui get larger.
Add PID motor for avatar movement (slow to stop, ...)
setForce should set a constant force. Different than AddImpulse.
Implement raycast.
Implement ShapeCollection.Dispose() Implement ShapeCollection.Dispose()
Implement water as a plain so raycasting and collisions can happen with same. Implement water as a plain or mesh so raycasting and collisions can happen with same.
Add collision penetration return Add collision penetration return
Add field passed back by BulletSim.dll and fill with info in ManifoldConstact.GetDistance() Add field passed back by BulletSim.dll and fill with info in ManifoldConstact.GetDistance()
Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE
Also osGetPhysicsEngineVerion() maybe.
Linkset.Position and Linkset.Orientation requre rewrite to properly return Linkset.Position and Linkset.Orientation requre rewrite to properly return
child position. LinksetConstraint acts like it's at taint time!! child position. LinksetConstraint acts like it's at taint time!!
Implement LockAngularMotion -- implements llSetStatus(ROTATE_AXIS_*, T/F) Implement LockAngularMotion -- implements llSetStatus(ROTATE_AXIS_*, T/F)
@ -127,9 +113,6 @@ Selecting and deselecting physical objects causes CPU processing time to jump
Re-implement buoyancy as a separate force on the object rather than diddling gravity. Re-implement buoyancy as a separate force on the object rather than diddling gravity.
Register a pre-step event to add the force. Register a pre-step event to add the force.
More efficient memory usage when passing hull information from BSPrim to BulletSim More efficient memory usage when passing hull information from BSPrim to BulletSim
Avatar movement motor check for zero or small movement. Somehow suppress small movements
when avatar has stopped and is just standing. Simple test for near zero has
the problem of preventing starting up (increase from zero) especially when falling.
Physical and phantom will drop through the terrain Physical and phantom will drop through the terrain
@ -172,7 +155,6 @@ Do we need to do convex hulls all the time? Can complex meshes be left meshes?
There is some problem with meshes and collisions There is some problem with meshes and collisions
Hulls are not as detailed as meshes. Hulled vehicles insides are different shape. Hulls are not as detailed as meshes. Hulled vehicles insides are different shape.
Debounce avatar contact so legs don't keep folding up when standing. Debounce avatar contact so legs don't keep folding up when standing.
Implement LSL physics controls. Like STATUS_ROTATE_X.
Add border extensions to terrain to help region crossings and objects leaving region. Add border extensions to terrain to help region crossings and objects leaving region.
Use a different capsule shape for avatar when sitting Use a different capsule shape for avatar when sitting
LL uses a pyrimidal shape scaled by the avatar's bounding box LL uses a pyrimidal shape scaled by the avatar's bounding box
@ -205,8 +187,6 @@ Keep avatar scaling correct. http://pennycow.blogspot.fr/2011/07/matter-of-scale
INTERNAL IMPROVEMENT/CLEANUP INTERNAL IMPROVEMENT/CLEANUP
================================================= =================================================
Can the 'inTaintTime' flag be cleaned up and used? For instance, a call to
BSScene.TaintedObject() could immediately execute the callback if already in taint time.
Create the physical wrapper classes (BulletBody, BulletShape) by methods on Create the physical wrapper classes (BulletBody, BulletShape) by methods on
BSAPITemplate and make their actual implementation Bullet engine specific. BSAPITemplate and make their actual implementation Bullet engine specific.
For the short term, just call the existing functions in ShapeCollection. For the short term, just call the existing functions in ShapeCollection.
@ -365,4 +345,35 @@ After getting off a vehicle, the root prim is phantom (can be walked through)
Explore btGImpactMeshShape as alternative to convex hulls for simplified physical objects. Explore btGImpactMeshShape as alternative to convex hulls for simplified physical objects.
Regular triangle meshes don't do physical collisions. Regular triangle meshes don't do physical collisions.
(DONE: discovered GImpact is VERY CPU intensive) (DONE: discovered GImpact is VERY CPU intensive)
Script changing rotation of child prim while vehicle moving (eg turning wheel) causes
the wheel to appear to jump back. Looks like sending position from previous update.
(DONE: redo of compound linksets fixed problem)
Refarb compound linkset creation to create a pseudo-root for center-of-mass
Let children change their shape to physical indendently and just add shapes to compound
(DONE: redo of compound linkset fixed problem)
Vehicle angular vertical attraction (DONE: vegaslon code)
vehicle angular banking (DONE: vegaslon code)
Vehicle angular deflection (DONE: vegaslon code)
Preferred orientation angular correction fix
Vehicles (Move smoothly)
For limitMotorUp, use raycast down to find if vehicle is in the air.
(WILL NOT BE DONE: gravity does the job well enough)
BSPrim.Force should set a continious force on the prim. The force should be
applied each tick. Some limits?
(DONE: added physical actors. Implemented SetForce, SetTorque, ...)
Implement LSL physics controls. Like STATUS_ROTATE_X. (DONE)
Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE
Avatar rotation (check out changes to ScenePresence for physical rotation) (DONE)
Avatar running (what does phys engine need to do?) (DONE: multiplies run factor by walking force)
setForce should set a constant force. Different than AddImpulse. (DONE)
Add PID motor for avatar movement (slow to stop, ...) (WNBD: current works ok)
Avatar movement motor check for zero or small movement. Somehow suppress small movements
when avatar has stopped and is just standing. Simple test for near zero has
the problem of preventing starting up (increase from zero) especially when falling.
(DONE: avatar movement actor knows if standing on stationary object and zeros motion)
Can the 'inTaintTime' flag be cleaned up and used? For instance, a call to
BSScene.TaintedObject() could immediately execute the callback if already in taint time.
(DONE)

View File

@ -57,6 +57,8 @@ public class BasicVehicles : OpenSimTestCase
public void Init() public void Init()
{ {
Dictionary<string, string> engineParams = new Dictionary<string, string>(); Dictionary<string, string> engineParams = new Dictionary<string, string>();
engineParams.Add("VehicleEnableAngularVerticalAttraction", "true");
engineParams.Add("VehicleAngularVerticalAttractionAlgorithm", "1");
PhysicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams); PhysicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams);
PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere(); PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere();
@ -119,7 +121,7 @@ public class BasicVehicles : OpenSimTestCase
{ {
vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency); vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency);
vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, timeScale); vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, timeScale);
vehicleActor.enableAngularVerticalAttraction = true; // vehicleActor.enableAngularVerticalAttraction = true;
TestVehicle.IsPhysical = true; TestVehicle.IsPhysical = true;
PhysicsScene.ProcessTaints(); PhysicsScene.ProcessTaints();

View File

@ -108,7 +108,6 @@ namespace OpenSim.Region.Physics.OdePlugin
private Vector3 m_taintAngularLock = Vector3.One; private Vector3 m_taintAngularLock = Vector3.One;
private IntPtr Amotor = IntPtr.Zero; private IntPtr Amotor = IntPtr.Zero;
private object m_assetsLock = new object();
private bool m_assetFailed = false; private bool m_assetFailed = false;
private Vector3 m_PIDTarget; private Vector3 m_PIDTarget;

View File

@ -46,7 +46,7 @@ namespace OpenSim.Region.Physics.OdePlugin
/// </summary> /// </summary>
public class OdePlugin : IPhysicsPlugin public class OdePlugin : IPhysicsPlugin
{ {
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); // private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private OdeScene m_scene; private OdeScene m_scene;

View File

@ -355,6 +355,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
fromRegionPos = avatar.AbsolutePosition; fromRegionPos = avatar.AbsolutePosition;
q = avatar.Rotation; q = avatar.Rotation;
// Don't proceed if the avatar for this attachment has since been removed from the scene.
if (avatar == null)
return sensedEntities;
} }
LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);

View File

@ -332,7 +332,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void llSensorRemove(); void llSensorRemove();
void llSensorRepeat(string name, string id, int type, double range, double arc, double rate); void llSensorRepeat(string name, string id, int type, double range, double arc, double rate);
void llSetAlpha(double alpha, int face); void llSetAlpha(double alpha, int face);
void llSetAngularVelocity(LSL_Vector angvelocity, int local);
void llSetBuoyancy(double buoyancy); void llSetBuoyancy(double buoyancy);
void llSetCameraAtOffset(LSL_Vector offset); void llSetCameraAtOffset(LSL_Vector offset);
void llSetCameraEyeOffset(LSL_Vector offset); void llSetCameraEyeOffset(LSL_Vector offset);
@ -344,6 +343,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void llSetDamage(double damage); void llSetDamage(double damage);
void llSetForce(LSL_Vector force, int local); void llSetForce(LSL_Vector force, int local);
void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local); void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local);
void llSetVelocity(LSL_Vector velocity, int local);
void llSetAngularVelocity(LSL_Vector angularVelocity, int local);
void llSetHoverHeight(double height, int water, double tau); void llSetHoverHeight(double height, int water, double tau);
void llSetInventoryPermMask(string item, int mask, int value); void llSetInventoryPermMask(string item, int mask, int value);
void llSetLinkAlpha(int linknumber, double alpha, int face); void llSetLinkAlpha(int linknumber, double alpha, int face);
@ -384,7 +385,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void llSetVehicleRotationParam(int param, LSL_Rotation rot); void llSetVehicleRotationParam(int param, LSL_Rotation rot);
void llSetVehicleType(int type); void llSetVehicleType(int type);
void llSetVehicleVectorParam(int param, LSL_Vector vec); void llSetVehicleVectorParam(int param, LSL_Vector vec);
void llSetVelocity(LSL_Vector velocity, int local);
void llShout(int channelID, string text); void llShout(int channelID, string text);
LSL_Float llSin(double f); LSL_Float llSin(double f);
void llSitTarget(LSL_Vector offset, LSL_Rotation rot); void llSitTarget(LSL_Vector offset, LSL_Rotation rot);

View File

@ -1495,11 +1495,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
m_LSL_Functions.llSetAlpha(alpha, face); 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) public void llSetBuoyancy(double buoyancy)
{ {
m_LSL_Functions.llSetBuoyancy(buoyancy); m_LSL_Functions.llSetBuoyancy(buoyancy);
@ -1555,6 +1550,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
m_LSL_Functions.llSetForceAndTorque(force, torque, local); m_LSL_Functions.llSetForceAndTorque(force, torque, local);
} }
public void llSetVelocity(LSL_Vector force, int local)
{
m_LSL_Functions.llSetVelocity(force, local);
}
public void llSetAngularVelocity(LSL_Vector force, int local)
{
m_LSL_Functions.llSetAngularVelocity(force, local);
}
public void llSetHoverHeight(double height, int water, double tau) public void llSetHoverHeight(double height, int water, double tau)
{ {
m_LSL_Functions.llSetHoverHeight(height, water, tau); m_LSL_Functions.llSetHoverHeight(height, water, tau);
@ -1745,11 +1750,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
m_LSL_Functions.llSetVehicleVectorParam(param, vec); 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) public void llShout(int channelID, string text)
{ {
m_LSL_Functions.llShout(channelID, text); m_LSL_Functions.llShout(channelID, text);

View File

@ -70,7 +70,7 @@ namespace OpenSim.Server.Handlers.Asset
m_allowedTypes = allowedTypes; m_allowedTypes = allowedTypes;
} }
public override byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
bool result = false; bool result = false;

View File

@ -54,7 +54,7 @@ namespace OpenSim.Server.Handlers.Asset
m_AssetService = service; m_AssetService = service;
} }
public override byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
byte[] result = new byte[0]; byte[] result = new byte[0];

View File

@ -54,7 +54,7 @@ namespace OpenSim.Server.Handlers.Asset
m_AssetService = service; m_AssetService = service;
} }
public override byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
AssetBase asset; AssetBase asset;

View File

@ -70,7 +70,7 @@ namespace OpenSim.Server.Handlers.Authentication
} }
} }
public override byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
string[] p = SplitParams(path); string[] p = SplitParams(path);

View File

@ -147,7 +147,7 @@ namespace OpenSim.Server.Handlers.Authentication
#endregion #endregion
} }
public class OpenIdStreamHandler : IStreamHandler public class OpenIdStreamHandler : BaseOutputStreamHandler
{ {
#region HTML #region HTML
@ -191,42 +191,34 @@ For more information, see <a href='http://openid.net/'>http://openid.net/</a>.
#endregion HTML #endregion HTML
public string Name { get { return "OpenId"; } }
public string Description { get { return null; } }
public string ContentType { get { return m_contentType; } }
public string HttpMethod { get { return m_httpMethod; } }
public string Path { get { return m_path; } }
string m_contentType;
string m_httpMethod;
string m_path;
IAuthenticationService m_authenticationService; IAuthenticationService m_authenticationService;
IUserAccountService m_userAccountService; IUserAccountService m_userAccountService;
ProviderMemoryStore m_openidStore = new ProviderMemoryStore(); ProviderMemoryStore m_openidStore = new ProviderMemoryStore();
public override string ContentType { get { return "text/html"; } }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public OpenIdStreamHandler(string httpMethod, string path, IUserAccountService userService, IAuthenticationService authService) public OpenIdStreamHandler(
string httpMethod, string path, IUserAccountService userService, IAuthenticationService authService)
: base(httpMethod, path, "OpenId", "OpenID stream handler")
{ {
m_authenticationService = authService; m_authenticationService = authService;
m_userAccountService = userService; m_userAccountService = userService;
m_httpMethod = httpMethod;
m_path = path;
m_contentType = "text/html";
} }
/// <summary> /// <summary>
/// Handles all GET and POST requests for OpenID identifier pages and endpoint /// Handles all GET and POST requests for OpenID identifier pages and endpoint
/// server communication /// server communication
/// </summary> /// </summary>
public void Handle(string path, Stream request, Stream response, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) protected override void ProcessRequest(
string path, Stream request, Stream response, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
Uri providerEndpoint = new Uri(String.Format("{0}://{1}{2}", httpRequest.Url.Scheme, httpRequest.Url.Authority, httpRequest.Url.AbsolutePath)); Uri providerEndpoint = new Uri(String.Format("{0}://{1}{2}", httpRequest.Url.Scheme, httpRequest.Url.Authority, httpRequest.Url.AbsolutePath));
// Defult to returning HTML content // Defult to returning HTML content
m_contentType = "text/html"; httpResponse.ContentType = ContentType;
try try
{ {
@ -276,7 +268,7 @@ For more information, see <a href='http://openid.net/'>http://openid.net/</a>.
string[] contentTypeValues = provider.Request.Response.Headers.GetValues("Content-Type"); string[] contentTypeValues = provider.Request.Response.Headers.GetValues("Content-Type");
if (contentTypeValues != null && contentTypeValues.Length == 1) if (contentTypeValues != null && contentTypeValues.Length == 1)
m_contentType = contentTypeValues[0]; httpResponse.ContentType = contentTypeValues[0];
// Set the response code and document body based on the OpenID result // Set the response code and document body based on the OpenID result
httpResponse.StatusCode = (int)provider.Request.Response.Code; httpResponse.StatusCode = (int)provider.Request.Response.Code;

View File

@ -54,7 +54,7 @@ namespace OpenSim.Server.Handlers.Authorization
m_AuthorizationService = service; m_AuthorizationService = service;
} }
public override byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
XmlSerializer xs = new XmlSerializer(typeof (AuthorizationRequest)); XmlSerializer xs = new XmlSerializer(typeof (AuthorizationRequest));

View File

@ -56,7 +56,7 @@ namespace OpenSim.Server.Handlers.Avatar
m_AvatarService = service; m_AvatarService = service;
} }
public override byte[] Handle(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); StreamReader sr = new StreamReader(requestData);

View File

@ -57,7 +57,7 @@ namespace OpenSim.Server.Handlers.Friends
m_FriendsService = service; m_FriendsService = service;
} }
public override byte[] Handle(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); StreamReader sr = new StreamReader(requestData);

View File

@ -57,7 +57,7 @@ namespace OpenSim.Server.Handlers.Grid
m_GridService = service; m_GridService = service;
} }
public override byte[] Handle(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); StreamReader sr = new StreamReader(requestData);

View File

@ -56,7 +56,7 @@ namespace OpenSim.Server.Handlers.GridUser
m_GridUserService = service; m_GridUserService = service;
} }
public override byte[] Handle(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); StreamReader sr = new StreamReader(requestData);

View File

@ -68,7 +68,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
m_log.ErrorFormat("[HGFRIENDS HANDLER]: TheService is null!"); m_log.ErrorFormat("[HGFRIENDS HANDLER]: TheService is null!");
} }
public override byte[] Handle(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); StreamReader sr = new StreamReader(requestData);

View File

@ -91,7 +91,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
m_HandlersType = handlersType; m_HandlersType = handlersType;
} }
public override byte[] Handle(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
return OKResponse(httpResponse); return OKResponse(httpResponse);

View File

@ -68,6 +68,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
{ {
return new ExtendedAgentDestinationData(); return new ExtendedAgentDestinationData();
} }
protected override void UnpackData(OSDMap args, AgentDestinationData d, Hashtable request) protected override void UnpackData(OSDMap args, AgentDestinationData d, Hashtable request)
{ {
base.UnpackData(args, d, request); base.UnpackData(args, d, request);

View File

@ -56,7 +56,7 @@ namespace OpenSim.Server.Handlers.Inventory
m_InventoryService = service; m_InventoryService = service;
} }
public override byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
XmlSerializer xs = new XmlSerializer(typeof (List<InventoryItemBase>)); XmlSerializer xs = new XmlSerializer(typeof (List<InventoryItemBase>));

View File

@ -87,7 +87,7 @@ namespace OpenSim.Server.Handlers.Asset
m_InventoryService = service; m_InventoryService = service;
} }
public override byte[] Handle(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); StreamReader sr = new StreamReader(requestData);

View File

@ -99,7 +99,7 @@ namespace OpenSim.Server.Handlers.MapImage
m_Proxy = proxy; m_Proxy = proxy;
} }
public override byte[] Handle(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
// m_log.DebugFormat("[MAP SERVICE IMAGE HANDLER]: Received {0}", path); // m_log.DebugFormat("[MAP SERVICE IMAGE HANDLER]: Received {0}", path);
StreamReader sr = new StreamReader(requestData); StreamReader sr = new StreamReader(requestData);

View File

@ -83,7 +83,7 @@ namespace OpenSim.Server.Handlers.MapImage
m_MapService = service; m_MapService = service;
} }
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
ev.WaitOne(); ev.WaitOne();
lock (ev) lock (ev)

View File

@ -58,7 +58,7 @@ namespace OpenSim.Server.Handlers.Neighbour
// TODO: unused: m_AuthenticationService = authentication; // TODO: unused: m_AuthenticationService = authentication;
} }
public override byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
// Not implemented yet // Not implemented yet
@ -83,7 +83,7 @@ namespace OpenSim.Server.Handlers.Neighbour
// TODO: unused: m_AllowForeignGuests = foreignGuests; // TODO: unused: m_AllowForeignGuests = foreignGuests;
} }
public override byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
byte[] result = new byte[0]; byte[] result = new byte[0];
@ -176,7 +176,7 @@ namespace OpenSim.Server.Handlers.Neighbour
// TODO: unused: m_AuthenticationService = authentication; // TODO: unused: m_AuthenticationService = authentication;
} }
public override byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
// Not implemented yet // Not implemented yet
@ -197,7 +197,7 @@ namespace OpenSim.Server.Handlers.Neighbour
// TODO: unused: m_AuthenticationService = authentication; // TODO: unused: m_AuthenticationService = authentication;
} }
public override byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
// Not implemented yet // Not implemented yet

View File

@ -56,7 +56,7 @@ namespace OpenSim.Server.Handlers.Presence
m_PresenceService = service; m_PresenceService = service;
} }
public override byte[] Handle(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); StreamReader sr = new StreamReader(requestData);

View File

@ -112,7 +112,7 @@ namespace OpenSim.Server.Handlers.Simulation
} }
else else
{ {
m_log.InfoFormat("[AGENT HANDLER]: method {0} not supported in agent message", method); m_log.InfoFormat("[AGENT HANDLER]: method {0} not supported in agent message (caller is {1})", method, Util.GetCallerIP(request));
responsedata["int_response_code"] = HttpStatusCode.MethodNotAllowed; responsedata["int_response_code"] = HttpStatusCode.MethodNotAllowed;
responsedata["str_response_string"] = "Method not allowed"; responsedata["str_response_string"] = "Method not allowed";
@ -274,7 +274,7 @@ namespace OpenSim.Server.Handlers.Simulation
m_SimulationService = null; m_SimulationService = null;
} }
public override byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
// m_log.DebugFormat("[SIMULATION]: Stream handler called"); // m_log.DebugFormat("[SIMULATION]: Stream handler called");
@ -488,7 +488,7 @@ namespace OpenSim.Server.Handlers.Simulation
m_SimulationService = null; m_SimulationService = null;
} }
public override byte[] Handle(string path, Stream request, protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
// m_log.DebugFormat("[SIMULATION]: Stream handler called"); // m_log.DebugFormat("[SIMULATION]: Stream handler called");

View File

@ -68,7 +68,7 @@ namespace OpenSim.Server.Handlers.UserAccounts
} }
} }
public override byte[] Handle(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); StreamReader sr = new StreamReader(requestData);

View File

@ -66,6 +66,12 @@ namespace OpenSim.Services.Connectors
private Thread[] m_fetchThreads; private Thread[] m_fetchThreads;
public int MaxAssetRequestConcurrency
{
get { return m_maxAssetRequestConcurrency; }
set { m_maxAssetRequestConcurrency = value; }
}
public AssetServicesConnector() public AssetServicesConnector()
{ {
} }

Some files were not shown because too many files have changed in this diff Show More