Merge branch 'master' into careminster
Conflicts: OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs OpenSim/Region/Framework/Scenes/Scene.cs OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs OpenSim/Region/Framework/Scenes/SceneObjectPart.cs OpenSim/Region/Framework/Scenes/ScenePresence.cs OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs OpenSim/Server/Handlers/Simulation/AgentHandlers.cs OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs OpenSim/Services/HypergridService/UserAgentService.csavinationmerge
commit
7830cc9954
|
@ -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);
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CapsHandlers
|
public class CapsHandlers
|
||||||
{
|
{
|
||||||
private Dictionary <string, IRequestHandler> m_capsHandlers = new Dictionary<string, IRequestHandler>();
|
private Dictionary<string, IRequestHandler> m_capsHandlers = new Dictionary<string, IRequestHandler>();
|
||||||
private IHttpServer m_httpListener;
|
private IHttpServer m_httpListener;
|
||||||
private string m_httpListenerHostName;
|
private string m_httpListenerHostName;
|
||||||
private uint m_httpListenerPort;
|
private uint m_httpListenerPort;
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* 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 Nini.Config;
|
||||||
|
using OpenSim.Server.Base;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Server.Handlers.Base;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Capabilities.Handlers
|
||||||
|
{
|
||||||
|
public class UploadBakedTextureServerConnector : ServiceConnector
|
||||||
|
{
|
||||||
|
private IAssetService m_AssetService;
|
||||||
|
private string m_ConfigName = "CapsService";
|
||||||
|
|
||||||
|
public UploadBakedTextureServerConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||||
|
base(config, server, configName)
|
||||||
|
{
|
||||||
|
if (configName != String.Empty)
|
||||||
|
m_ConfigName = configName;
|
||||||
|
|
||||||
|
IConfig serverConfig = config.Configs[m_ConfigName];
|
||||||
|
if (serverConfig == null)
|
||||||
|
throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
|
||||||
|
|
||||||
|
string assetService = serverConfig.GetString("AssetService", String.Empty);
|
||||||
|
|
||||||
|
if (assetService == String.Empty)
|
||||||
|
throw new Exception("No AssetService in config file");
|
||||||
|
|
||||||
|
Object[] args = new Object[] { config };
|
||||||
|
m_AssetService =
|
||||||
|
ServerUtils.LoadPlugin<IAssetService>(assetService, args);
|
||||||
|
|
||||||
|
if (m_AssetService == null)
|
||||||
|
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
||||||
|
|
||||||
|
// NEED TO FIX THIS
|
||||||
|
OpenSim.Framework.Capabilities.Caps caps = new OpenSim.Framework.Capabilities.Caps(server, "", server.Port, "", UUID.Zero, "");
|
||||||
|
server.AddStreamHandler(new RestStreamHandler(
|
||||||
|
"POST",
|
||||||
|
"/CAPS/UploadBakedTexture/",
|
||||||
|
new UploadBakedTextureHandler(caps, m_AssetService, true).UploadBakedTexture,
|
||||||
|
"UploadBakedTexture",
|
||||||
|
"Upload Baked Texture Capability"));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
|
||||||
|
namespace OpenSim.Data
|
||||||
|
{
|
||||||
|
// This MUST be a ref type!
|
||||||
|
public class HGTravelingData
|
||||||
|
{
|
||||||
|
public UUID SessionID;
|
||||||
|
public UUID UserID;
|
||||||
|
public Dictionary<string, string> Data;
|
||||||
|
|
||||||
|
public HGTravelingData()
|
||||||
|
{
|
||||||
|
Data = new Dictionary<string, string>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An interface for connecting to the user grid datastore
|
||||||
|
/// </summary>
|
||||||
|
public interface IHGTravelingData
|
||||||
|
{
|
||||||
|
HGTravelingData Get(UUID sessionID);
|
||||||
|
HGTravelingData[] GetSessions(UUID userID);
|
||||||
|
bool Store(HGTravelingData data);
|
||||||
|
bool Delete(UUID sessionID);
|
||||||
|
void DeleteOld();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* 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.Data;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
|
using log4net;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using MySql.Data.MySqlClient;
|
||||||
|
|
||||||
|
namespace OpenSim.Data.MySQL
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A MySQL Interface for user grid data
|
||||||
|
/// </summary>
|
||||||
|
public class MySQLHGTravelData : MySQLGenericTableHandler<HGTravelingData>, IHGTravelingData
|
||||||
|
{
|
||||||
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
public MySQLHGTravelData(string connectionString, string realm) : base(connectionString, realm, "HGTravelStore") { }
|
||||||
|
|
||||||
|
public HGTravelingData Get(UUID sessionID)
|
||||||
|
{
|
||||||
|
HGTravelingData[] ret = Get("SessionID", sessionID.ToString());
|
||||||
|
|
||||||
|
if (ret.Length == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return ret[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public HGTravelingData[] GetSessions(UUID userID)
|
||||||
|
{
|
||||||
|
return base.Get("UserID", userID.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Delete(UUID sessionID)
|
||||||
|
{
|
||||||
|
return Delete("SessionID", sessionID.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteOld()
|
||||||
|
{
|
||||||
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
|
{
|
||||||
|
cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 DAY", m_Realm);
|
||||||
|
|
||||||
|
ExecuteNonQuery(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
:VERSION 1 # --------------------------
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
CREATE TABLE `hg_traveling_data` (
|
||||||
|
`SessionID` VARCHAR(36) NOT NULL,
|
||||||
|
`UserID` VARCHAR(36) NOT NULL,
|
||||||
|
`GridExternalName` VARCHAR(255) NOT NULL DEFAULT '',
|
||||||
|
`ServiceToken` VARCHAR(255) NOT NULL DEFAULT '',
|
||||||
|
`ClientIPAddress` VARCHAR(16) NOT NULL DEFAULT '',
|
||||||
|
`MyIPAddress` VARCHAR(16) NOT NULL DEFAULT '',
|
||||||
|
`TMStamp` timestamp NOT NULL,
|
||||||
|
PRIMARY KEY (`SessionID`),
|
||||||
|
KEY (`UserID`)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
|
@ -42,6 +42,22 @@ namespace OpenSim.Data.Null
|
||||||
|
|
||||||
// private string m_connectionString;
|
// private string m_connectionString;
|
||||||
|
|
||||||
|
private Dictionary<uint, EstateSettings> m_knownEstates = new Dictionary<uint, EstateSettings>();
|
||||||
|
private EstateSettings m_estate = null;
|
||||||
|
|
||||||
|
private EstateSettings GetEstate()
|
||||||
|
{
|
||||||
|
if (m_estate == null)
|
||||||
|
{
|
||||||
|
// This fools the initialization caller into thinking an estate was fetched (a check in OpenSimBase).
|
||||||
|
// The estate info is pretty empty so don't try banning anyone.
|
||||||
|
m_estate = new EstateSettings();
|
||||||
|
m_estate.EstateID = 1;
|
||||||
|
m_estate.OnSave += StoreEstateSettings;
|
||||||
|
}
|
||||||
|
return m_estate;
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual Assembly Assembly
|
protected virtual Assembly Assembly
|
||||||
{
|
{
|
||||||
get { return GetType().Assembly; }
|
get { return GetType().Assembly; }
|
||||||
|
@ -68,21 +84,18 @@ namespace OpenSim.Data.Null
|
||||||
|
|
||||||
public EstateSettings LoadEstateSettings(UUID regionID, bool create)
|
public EstateSettings LoadEstateSettings(UUID regionID, bool create)
|
||||||
{
|
{
|
||||||
// This fools the initialization caller into thinking an estate was fetched (a check in OpenSimBase).
|
return GetEstate();
|
||||||
// The estate info is pretty empty so don't try banning anyone.
|
|
||||||
EstateSettings oneEstate = new EstateSettings();
|
|
||||||
oneEstate.EstateID = 1;
|
|
||||||
return oneEstate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StoreEstateSettings(EstateSettings es)
|
public void StoreEstateSettings(EstateSettings es)
|
||||||
{
|
{
|
||||||
|
m_estate = es;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EstateSettings LoadEstateSettings(int estateID)
|
public EstateSettings LoadEstateSettings(int estateID)
|
||||||
{
|
{
|
||||||
return new EstateSettings();
|
return GetEstate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public EstateSettings CreateNewEstate()
|
public EstateSettings CreateNewEstate()
|
||||||
|
@ -93,13 +106,14 @@ namespace OpenSim.Data.Null
|
||||||
public List<EstateSettings> LoadEstateSettingsAll()
|
public List<EstateSettings> LoadEstateSettingsAll()
|
||||||
{
|
{
|
||||||
List<EstateSettings> allEstateSettings = new List<EstateSettings>();
|
List<EstateSettings> allEstateSettings = new List<EstateSettings>();
|
||||||
allEstateSettings.Add(new EstateSettings());
|
allEstateSettings.Add(GetEstate());
|
||||||
return allEstateSettings;
|
return allEstateSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<int> GetEstatesAll()
|
public List<int> GetEstatesAll()
|
||||||
{
|
{
|
||||||
List<int> result = new List<int>();
|
List<int> result = new List<int>();
|
||||||
|
result.Add((int)GetEstate().EstateID);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
:VERSION 1 # --------------------------
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
CREATE TABLE hg_traveling_data (
|
||||||
|
SessionID VARCHAR(36) NOT NULL,
|
||||||
|
UserID VARCHAR(36) NOT NULL,
|
||||||
|
GridExternalName VARCHAR(255) NOT NULL DEFAULT '',
|
||||||
|
ServiceToken VARCHAR(255) NOT NULL DEFAULT '',
|
||||||
|
ClientIPAddress VARCHAR(16) NOT NULL DEFAULT '',
|
||||||
|
MyIPAddress VARCHAR(16) NOT NULL DEFAULT '',
|
||||||
|
TMStamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY (`SessionID`),
|
||||||
|
KEY (`UserID`)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* 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.Data;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
|
using log4net;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using Mono.Data.Sqlite;
|
||||||
|
|
||||||
|
namespace OpenSim.Data.SQLite
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A SQL Interface for user grid data
|
||||||
|
/// </summary>
|
||||||
|
public class SQLiteHGTravelData : SQLiteGenericTableHandler<HGTravelingData>, IHGTravelingData
|
||||||
|
{
|
||||||
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
public SQLiteHGTravelData(string connectionString, string realm)
|
||||||
|
: base(connectionString, realm, "HGTravelStore") {}
|
||||||
|
|
||||||
|
public HGTravelingData Get(UUID sessionID)
|
||||||
|
{
|
||||||
|
HGTravelingData[] ret = Get("SessionID", sessionID.ToString());
|
||||||
|
|
||||||
|
if (ret.Length == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return ret[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public HGTravelingData[] GetSessions(UUID userID)
|
||||||
|
{
|
||||||
|
return base.Get("UserID", userID.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Delete(UUID sessionID)
|
||||||
|
{
|
||||||
|
return Delete("SessionID", sessionID.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteOld()
|
||||||
|
{
|
||||||
|
using (SqliteCommand cmd = new SqliteCommand())
|
||||||
|
{
|
||||||
|
cmd.CommandText = String.Format("delete from {0} where TMStamp < datetime('now', '-2 day') ", m_Realm);
|
||||||
|
|
||||||
|
DoQuery(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -171,9 +171,10 @@ namespace OpenSim.Framework
|
||||||
/// Soon to be decommissioned
|
/// Soon to be decommissioned
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cAgent"></param>
|
/// <param name="cAgent"></param>
|
||||||
public void CopyFrom(ChildAgentDataUpdate cAgent)
|
public void CopyFrom(ChildAgentDataUpdate cAgent, UUID sid)
|
||||||
{
|
{
|
||||||
AgentID = new UUID(cAgent.AgentID);
|
AgentID = new UUID(cAgent.AgentID);
|
||||||
|
SessionID = sid;
|
||||||
|
|
||||||
// next: ???
|
// next: ???
|
||||||
Size = new Vector3();
|
Size = new Vector3();
|
||||||
|
|
|
@ -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>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -224,5 +224,26 @@ public class CounterStat : Stat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CounterStat is a basic stat plus histograms
|
||||||
|
public override OSDMap ToOSDMap()
|
||||||
|
{
|
||||||
|
// Get the foundational instance
|
||||||
|
OSDMap map = base.ToOSDMap();
|
||||||
|
|
||||||
|
map["StatType"] = "CounterStat";
|
||||||
|
|
||||||
|
// If there are any histograms, add a new field that is an array of histograms as OSDMaps
|
||||||
|
if (m_histograms.Count > 0)
|
||||||
|
{
|
||||||
|
OSDArray histos = new OSDArray();
|
||||||
|
foreach (EventHistogram histo in m_histograms.Values)
|
||||||
|
{
|
||||||
|
histos.Add(histo.GetHistogramAsOSDMap());
|
||||||
|
}
|
||||||
|
map.Add("Histograms", histos);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,6 +242,7 @@ namespace OpenSim.Framework.Monitoring
|
||||||
ret.Add("Description", OSD.FromString(Description));
|
ret.Add("Description", OSD.FromString(Description));
|
||||||
ret.Add("UnitName", OSD.FromString(UnitName));
|
ret.Add("UnitName", OSD.FromString(UnitName));
|
||||||
ret.Add("Value", OSD.FromReal(Value));
|
ret.Add("Value", OSD.FromReal(Value));
|
||||||
|
ret.Add("StatType", "Stat"); // used by overloading classes to denote type of stat
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,8 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
using OpenMetaverse.StructuredData;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Monitoring
|
namespace OpenSim.Framework.Monitoring
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -168,6 +170,70 @@ namespace OpenSim.Framework.Monitoring
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creates an OSDMap of the format:
|
||||||
|
// { categoryName: {
|
||||||
|
// containerName: {
|
||||||
|
// statName: {
|
||||||
|
// "Name": name,
|
||||||
|
// "ShortName": shortName,
|
||||||
|
// ...
|
||||||
|
// },
|
||||||
|
// statName: {
|
||||||
|
// "Name": name,
|
||||||
|
// "ShortName": shortName,
|
||||||
|
// ...
|
||||||
|
// },
|
||||||
|
// ...
|
||||||
|
// },
|
||||||
|
// containerName: {
|
||||||
|
// ...
|
||||||
|
// },
|
||||||
|
// ...
|
||||||
|
// },
|
||||||
|
// categoryName: {
|
||||||
|
// ...
|
||||||
|
// },
|
||||||
|
// ...
|
||||||
|
// }
|
||||||
|
// The passed in parameters will filter the categories, containers and stats returned. If any of the
|
||||||
|
// parameters are either EmptyOrNull or the AllSubCommand value, all of that type will be returned.
|
||||||
|
// Case matters.
|
||||||
|
public static OSDMap GetStatsAsOSDMap(string pCategoryName, string pContainerName, string pStatName)
|
||||||
|
{
|
||||||
|
OSDMap map = new OSDMap();
|
||||||
|
|
||||||
|
foreach (string catName in RegisteredStats.Keys)
|
||||||
|
{
|
||||||
|
// Do this category if null spec, "all" subcommand or category name matches passed parameter.
|
||||||
|
// Skip category if none of the above.
|
||||||
|
if (!(String.IsNullOrEmpty(pCategoryName) || pCategoryName == AllSubCommand || pCategoryName == catName))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
OSDMap contMap = new OSDMap();
|
||||||
|
foreach (string contName in RegisteredStats[catName].Keys)
|
||||||
|
{
|
||||||
|
if (!(string.IsNullOrEmpty(pContainerName) || pContainerName == AllSubCommand || pContainerName == contName))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
OSDMap statMap = new OSDMap();
|
||||||
|
|
||||||
|
SortedDictionary<string, Stat> theStats = RegisteredStats[catName][contName];
|
||||||
|
foreach (string statName in theStats.Keys)
|
||||||
|
{
|
||||||
|
if (!(String.IsNullOrEmpty(pStatName) || pStatName == AllSubCommand || pStatName == statName))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
statMap.Add(statName, theStats[statName].ToOSDMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
contMap.Add(contName, statMap);
|
||||||
|
}
|
||||||
|
map.Add(catName, contMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
// /// <summary>
|
// /// <summary>
|
||||||
// /// Start collecting statistics related to assets.
|
// /// Start collecting statistics related to assets.
|
||||||
// /// Should only be called once.
|
// /// Should only be called once.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"; }
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -292,6 +292,5 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
serializer.Serialize(xmlWriter, response);
|
serializer.Serialize(xmlWriter, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
|
@ -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);
|
||||||
|
|
|
@ -100,7 +100,7 @@ namespace OpenSim.Framework.Tests
|
||||||
cadu.AVHeight = Size1.Z;
|
cadu.AVHeight = Size1.Z;
|
||||||
|
|
||||||
AgentPosition position2 = new AgentPosition();
|
AgentPosition position2 = new AgentPosition();
|
||||||
position2.CopyFrom(cadu);
|
position2.CopyFrom(cadu, position1.SessionID);
|
||||||
|
|
||||||
Assert.IsTrue(
|
Assert.IsTrue(
|
||||||
position2.AgentID == position1.AgentID
|
position2.AgentID == position1.AgentID
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -64,11 +64,18 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
private Scene m_scene;
|
private Scene m_scene;
|
||||||
private bool m_persistBakedTextures;
|
private bool m_persistBakedTextures;
|
||||||
|
private string m_URL;
|
||||||
|
|
||||||
private IBakedTextureModule m_BakedTextureModule;
|
private IBakedTextureModule m_BakedTextureModule;
|
||||||
|
|
||||||
public void Initialise(IConfigSource source)
|
public void Initialise(IConfigSource source)
|
||||||
{
|
{
|
||||||
|
IConfig config = source.Configs["ClientStack.LindenCaps"];
|
||||||
|
if (config == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_URL = config.GetString("Cap_UploadBakedTexture", string.Empty);
|
||||||
|
|
||||||
IConfig appearanceConfig = source.Configs["Appearance"];
|
IConfig appearanceConfig = source.Configs["Appearance"];
|
||||||
if (appearanceConfig != null)
|
if (appearanceConfig != null)
|
||||||
m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
|
m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
|
||||||
|
@ -283,20 +290,26 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler(
|
UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler(
|
||||||
caps, m_scene.AssetService, m_persistBakedTextures);
|
caps, m_scene.AssetService, m_persistBakedTextures);
|
||||||
|
|
||||||
|
UUID capID = UUID.Random();
|
||||||
|
|
||||||
caps.RegisterHandler(
|
|
||||||
"UploadBakedTexture",
|
|
||||||
new RestStreamHandler(
|
|
||||||
"POST",
|
|
||||||
"/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
|
|
||||||
avatarhandler.UploadBakedTexture,
|
|
||||||
"UploadBakedTexture",
|
|
||||||
agentID.ToString()));
|
|
||||||
|
|
||||||
|
//caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
|
||||||
|
if (m_URL == "localhost")
|
||||||
|
{
|
||||||
|
caps.RegisterHandler(
|
||||||
|
"UploadBakedTexture",
|
||||||
|
new RestStreamHandler(
|
||||||
|
"POST",
|
||||||
|
"/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
|
||||||
|
avatarhandler.UploadBakedTexture,
|
||||||
|
"UploadBakedTexture",
|
||||||
|
agentID.ToString()));
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
caps.RegisterHandler("UploadBakedTexture", m_URL);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,129 +7883,145 @@ 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);
|
|
||||||
UUID itemID = new UUID(transfer.TransferInfo.Params, 64);
|
|
||||||
UUID requestID = new UUID(transfer.TransferInfo.Params, 80);
|
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
|
|
||||||
// requestID, itemID, taskID, Name);
|
|
||||||
|
|
||||||
if (!(((Scene)m_scene).Permissions.BypassPermissions()))
|
if (!(((Scene)m_scene).Permissions.BypassPermissions()))
|
||||||
{
|
{
|
||||||
if (taskID != UUID.Zero) // Prim
|
// We're spawning a thread because the permissions check can block this thread
|
||||||
|
Util.FireAndForget(delegate
|
||||||
{
|
{
|
||||||
SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID);
|
// This requests the asset if needed
|
||||||
|
HandleSimInventoryTransferRequestWithPermsCheck(sender, transfer);
|
||||||
if (part == null)
|
});
|
||||||
{
|
return true;
|
||||||
m_log.WarnFormat(
|
|
||||||
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist",
|
|
||||||
Name, requestID, itemID, taskID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID);
|
|
||||||
if (tii == null)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat(
|
|
||||||
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist",
|
|
||||||
Name, requestID, itemID, taskID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tii.Type == (int)AssetType.LSLText)
|
|
||||||
{
|
|
||||||
if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (tii.Type == (int)AssetType.Notecard)
|
|
||||||
{
|
|
||||||
if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO: Change this code to allow items other than notecards and scripts to be successfully
|
|
||||||
// shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule
|
|
||||||
if (part.OwnerID != AgentId)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat(
|
|
||||||
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}",
|
|
||||||
Name, requestID, itemID, taskID, part.OwnerID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat(
|
|
||||||
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set",
|
|
||||||
Name, requestID, itemID, taskID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tii.OwnerID != AgentId)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat(
|
|
||||||
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}",
|
|
||||||
Name, requestID, itemID, taskID, tii.OwnerID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((
|
|
||||||
tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
|
|
||||||
!= ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
|
|
||||||
{
|
|
||||||
m_log.WarnFormat(
|
|
||||||
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer",
|
|
||||||
Name, requestID, itemID, taskID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tii.AssetID != requestID)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat(
|
|
||||||
"[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);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // Agent
|
|
||||||
{
|
|
||||||
IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
|
|
||||||
if (invAccess != null)
|
|
||||||
{
|
|
||||||
if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
|
||||||
if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
|
{
|
||||||
{
|
//TransferRequestPacket does not include covenant uuid?
|
||||||
//TransferRequestPacket does not include covenant uuid?
|
//get scene covenant uuid
|
||||||
//get scene covenant uuid
|
taskID = m_scene.RegionInfo.RegionSettings.Covenant;
|
||||||
taskID = m_scene.RegionInfo.RegionSettings.Covenant;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// This is non-blocking
|
||||||
MakeAssetRequest(transfer, taskID);
|
MakeAssetRequest(transfer, taskID);
|
||||||
|
|
||||||
return true;
|
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 requestID = new UUID(transfer.TransferInfo.Params, 80);
|
||||||
|
|
||||||
|
//m_log.DebugFormat(
|
||||||
|
// "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
|
||||||
|
// requestID, itemID, taskID, Name);
|
||||||
|
|
||||||
|
//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
|
||||||
|
{
|
||||||
|
SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID);
|
||||||
|
|
||||||
|
if (part == null)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist",
|
||||||
|
Name, requestID, itemID, taskID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID);
|
||||||
|
if (tii == null)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist",
|
||||||
|
Name, requestID, itemID, taskID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tii.Type == (int)AssetType.LSLText)
|
||||||
|
{
|
||||||
|
if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (tii.Type == (int)AssetType.Notecard)
|
||||||
|
{
|
||||||
|
if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Change this code to allow items other than notecards and scripts to be successfully
|
||||||
|
// shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule
|
||||||
|
if (part.OwnerID != AgentId)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}",
|
||||||
|
Name, requestID, itemID, taskID, part.OwnerID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set",
|
||||||
|
Name, requestID, itemID, taskID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tii.OwnerID != AgentId)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}",
|
||||||
|
Name, requestID, itemID, taskID, tii.OwnerID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((
|
||||||
|
tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
|
||||||
|
!= ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer",
|
||||||
|
Name, requestID, itemID, taskID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tii.AssetID != requestID)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[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);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Agent
|
||||||
|
{
|
||||||
|
IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
|
||||||
|
if (invAccess != null)
|
||||||
|
{
|
||||||
|
if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permissions out of the way, let's request the asset
|
||||||
|
MakeAssetRequest(transfer, taskID);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack)
|
private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack)
|
||||||
{
|
{
|
||||||
AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
|
AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
|
||||||
|
@ -12378,7 +12409,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
ClientInfo info = m_udpClient.GetClientInfo();
|
ClientInfo info = m_udpClient.GetClientInfo();
|
||||||
|
|
||||||
info.proxyEP = null;
|
info.proxyEP = null;
|
||||||
info.agentcircuit = RequestClientInfo();
|
if (info.agentcircuit == null)
|
||||||
|
info.agentcircuit = RequestClientInfo();
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -1512,6 +1512,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
|
AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
|
||||||
bool tp = (aCircuit.teleportFlags > 0);
|
bool tp = (aCircuit.teleportFlags > 0);
|
||||||
|
// Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from
|
||||||
if (!tp)
|
if (!tp)
|
||||||
client.SceneAgent.SendInitialDataToMe();
|
client.SceneAgent.SendInitialDataToMe();
|
||||||
}
|
}
|
||||||
|
@ -1686,6 +1687,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 +1695,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))
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,7 +73,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp()
|
public override void SetUp()
|
||||||
{
|
{
|
||||||
base.SetUp();
|
base.SetUp();
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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>>();
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -291,8 +291,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||||
string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
|
string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
|
||||||
|
|
||||||
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>());
|
||||||
|
@ -342,8 +342,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||||
string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
|
string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
|
||||||
|
|
||||||
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>());
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -173,7 +173,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
||||||
if(obj.PresenceType == PresenceType.Npc)
|
if(obj.PresenceType == PresenceType.Npc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GetImageAssets(((IScenePresence)obj).UUID);
|
Util.FireAndForget(delegate
|
||||||
|
{
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,35 +124,42 @@ 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))
|
lock (m_capsObjects)
|
||||||
{
|
{
|
||||||
Caps oldCaps = m_capsObjects[circuitCode];
|
if (m_capsObjects.ContainsKey(circuitCode))
|
||||||
|
{
|
||||||
m_log.DebugFormat(
|
Caps oldCaps = m_capsObjects[circuitCode];
|
||||||
"[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ",
|
|
||||||
agentId, oldCaps.CapsObjectPath, capsObjectPath);
|
m_log.DebugFormat(
|
||||||
// This should not happen. The caller code is confused. We need to fix that.
|
"[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ",
|
||||||
// CAPs can never be reregistered, or the client will be confused.
|
agentId, oldCaps.CapsObjectPath, capsObjectPath);
|
||||||
// Hence this return here.
|
// This should not happen. The caller code is confused. We need to fix that.
|
||||||
//return;
|
// CAPs can never be reregistered, or the client will be confused.
|
||||||
|
// Hence this return here.
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
|
||||||
|
caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName,
|
||||||
|
(MainServer.Instance == null) ? 0: MainServer.Instance.Port,
|
||||||
|
capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
|
m_capsObjects[circuitCode] = caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
Caps caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName,
|
|
||||||
(MainServer.Instance == null) ? 0: MainServer.Instance.Port,
|
|
||||||
capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
|
|
||||||
|
|
||||||
m_capsObjects[circuitCode] = caps;
|
|
||||||
|
|
||||||
m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
|
m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 +205,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;
|
||||||
= ((agent.ChildrenCapSeeds == null) ? new Dictionary<ulong, string>() : agent.ChildrenCapSeeds);
|
|
||||||
|
lock (m_childrenSeeds)
|
||||||
|
m_childrenSeeds[agent.AgentID]
|
||||||
|
= ((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,17 +229,24 @@ 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))
|
|
||||||
return seeds;
|
lock (m_childrenSeeds)
|
||||||
|
if (m_childrenSeeds.TryGetValue(agentID, out 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)
|
||||||
{
|
{
|
||||||
seeds.Remove(handle);
|
if (m_childrenSeeds.TryGetValue(agentID, out seeds))
|
||||||
|
{
|
||||||
|
seeds.Remove(handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,53 +254,285 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
{
|
{
|
||||||
Dictionary<ulong, string> seeds;
|
Dictionary<ulong, string> seeds;
|
||||||
string returnval;
|
string returnval;
|
||||||
if (childrenSeeds.TryGetValue(agentID, out seeds))
|
|
||||||
|
lock (m_childrenSeeds)
|
||||||
{
|
{
|
||||||
if (seeds.TryGetValue(handle, out returnval))
|
if (m_childrenSeeds.TryGetValue(agentID, out seeds))
|
||||||
return returnval;
|
{
|
||||||
|
if (seeds.TryGetValue(handle, out 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)
|
||||||
{
|
{
|
||||||
uint x, y;
|
foreach (KeyValuePair<ulong, string> kvp in m_childrenSeeds[agentID])
|
||||||
Utils.LongToUInts(kvp.Key, out x, out y);
|
{
|
||||||
x = x / Constants.RegionSize;
|
uint x, y;
|
||||||
y = y / Constants.RegionSize;
|
Utils.LongToUInts(kvp.Key, out x, out y);
|
||||||
m_log.Info(" >> "+x+", "+y+": "+kvp.Value);
|
x = x / Constants.RegionSize;
|
||||||
|
y = y / Constants.RegionSize;
|
||||||
|
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);
|
||||||
|
|
||||||
foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects)
|
lock (m_capsObjects)
|
||||||
{
|
{
|
||||||
caps.AppendFormat("** Circuit {0}:\n", kvp.Key);
|
foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects)
|
||||||
|
|
||||||
for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); )
|
|
||||||
{
|
{
|
||||||
Uri uri = new Uri(kvp2.Value.ToString());
|
caps.AppendFormat("** Circuit {0}:\n", kvp.Key);
|
||||||
caps.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (KeyValuePair<string, string> kvp3 in kvp.Value.ExternalCapsHandlers)
|
for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); )
|
||||||
caps.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value);
|
{
|
||||||
|
Uri uri = new Uri(kvp2.Value.ToString());
|
||||||
|
caps.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, string> kvp3 in kvp.Value.ExternalCapsHandlers)
|
||||||
|
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());
|
||||||
|
*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -822,7 +822,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
"[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.",
|
"[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.",
|
||||||
sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
|
sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
Fail(sp, finalDestination, logout, "Connection between viewer and destination region could not be established.");
|
Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,7 +834,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
"[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
|
"[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
|
||||||
sp.Name, finalDestination.RegionName, sp.Scene.Name);
|
sp.Name, finalDestination.RegionName, sp.Scene.Name);
|
||||||
|
|
||||||
CleanupFailedInterRegionTeleport(sp, finalDestination);
|
CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -878,7 +878,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
"[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.",
|
"[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.",
|
||||||
sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
|
sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion.");
|
Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion.");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -932,7 +932,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// <param name='sp'> </param>
|
/// <param name='sp'> </param>
|
||||||
/// <param name='finalDestination'></param>
|
/// <param name='finalDestination'></param>
|
||||||
protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination)
|
protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, string auth_token, GridRegion finalDestination)
|
||||||
{
|
{
|
||||||
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
|
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
|
||||||
|
|
||||||
|
@ -943,7 +943,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
// Finally, kill the agent we just created at the destination.
|
// Finally, kill the agent we just created at the destination.
|
||||||
// XXX: Possibly this should be done asynchronously.
|
// XXX: Possibly this should be done asynchronously.
|
||||||
Scene.SimulationService.CloseAgent(finalDestination, sp.UUID);
|
Scene.SimulationService.CloseAgent(finalDestination, sp.UUID, auth_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -953,9 +953,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
/// <param name='finalDestination'></param>
|
/// <param name='finalDestination'></param>
|
||||||
/// <param name='logout'></param>
|
/// <param name='logout'></param>
|
||||||
/// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param>
|
/// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param>
|
||||||
protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason)
|
protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string auth_code, string reason)
|
||||||
{
|
{
|
||||||
CleanupFailedInterRegionTeleport(sp, finalDestination);
|
CleanupFailedInterRegionTeleport(sp, auth_code, finalDestination);
|
||||||
|
|
||||||
m_interRegionTeleportFailures.Value++;
|
m_interRegionTeleportFailures.Value++;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -207,6 +207,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
{
|
{
|
||||||
m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService);
|
m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService);
|
||||||
m_UAS = scene.RequestModuleInterface<IUserAgentService>();
|
m_UAS = scene.RequestModuleInterface<IUserAgentService>();
|
||||||
|
if (m_UAS == null)
|
||||||
|
m_UAS = new UserAgentServiceConnector(m_ThisHomeURI);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,12 +574,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
if (uMan != null && uMan.IsLocalGridUser(obj.AgentId))
|
if (uMan != null && uMan.IsLocalGridUser(obj.AgentId))
|
||||||
{
|
{
|
||||||
// local grid user
|
// local grid user
|
||||||
|
m_UAS.LogoutAgent(obj.AgentId, obj.SessionId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode);
|
AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode);
|
||||||
|
if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("HomeURI"))
|
||||||
if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
|
|
||||||
{
|
{
|
||||||
string url = aCircuit.ServiceURLs["HomeURI"].ToString();
|
string url = aCircuit.ServiceURLs["HomeURI"].ToString();
|
||||||
IUserAgentService security = new UserAgentServiceConnector(url);
|
IUserAgentService security = new UserAgentServiceConnector(url);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,26 +250,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent)
|
|
||||||
{
|
|
||||||
agent = null;
|
|
||||||
|
|
||||||
if (destination == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_scenes.ContainsKey(destination.RegionID))
|
|
||||||
{
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
|
|
||||||
// s.RegionInfo.RegionName, destination.RegionHandle);
|
|
||||||
|
|
||||||
return m_scenes[destination.RegionID].IncomingRetrieveRootAgent(id, out agent);
|
|
||||||
}
|
|
||||||
|
|
||||||
//m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
|
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
|
||||||
{
|
{
|
||||||
reason = "Communications failure";
|
reason = "Communications failure";
|
||||||
|
@ -306,12 +286,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CloseChildAgent(GridRegion destination, UUID id)
|
public bool CloseAgent(GridRegion destination, UUID id, string auth_token)
|
||||||
{
|
|
||||||
return CloseAgent(destination, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CloseAgent(GridRegion destination, UUID id)
|
|
||||||
{
|
{
|
||||||
if (destination == null)
|
if (destination == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -322,7 +297,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||||
// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
|
// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
|
||||||
// s.RegionInfo.RegionName, destination.RegionHandle);
|
// s.RegionInfo.RegionName, destination.RegionHandle);
|
||||||
|
|
||||||
m_scenes[destination.RegionID].IncomingCloseAgent(id, false);
|
m_scenes[destination.RegionID].IncomingCloseAgent(id, false, auth_token);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
|
//m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
|
||||||
|
|
|
@ -212,24 +212,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||||
return m_remoteConnector.UpdateAgent(destination, cAgentData);
|
return m_remoteConnector.UpdateAgent(destination, cAgentData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent)
|
|
||||||
{
|
|
||||||
agent = null;
|
|
||||||
|
|
||||||
if (destination == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Try local first
|
|
||||||
if (m_localBackend.RetrieveAgent(destination, id, out agent))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// else do the remote thing
|
|
||||||
if (!m_localBackend.IsLocalRegion(destination.RegionID))
|
|
||||||
return m_remoteConnector.RetrieveAgent(destination, id, out agent);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
|
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
|
||||||
{
|
{
|
||||||
reason = "Communications failure";
|
reason = "Communications failure";
|
||||||
|
@ -262,34 +244,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CloseChildAgent(GridRegion destination, UUID id)
|
public bool CloseAgent(GridRegion destination, UUID id, string auth_token)
|
||||||
{
|
{
|
||||||
if (destination == null)
|
if (destination == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Try local first
|
// Try local first
|
||||||
if (m_localBackend.CloseChildAgent(destination, id))
|
if (m_localBackend.CloseAgent(destination, id, auth_token))
|
||||||
return true;
|
|
||||||
|
|
||||||
// else do the remote thing
|
|
||||||
if (!m_localBackend.IsLocalRegion(destination.RegionHandle))
|
|
||||||
return m_remoteConnector.CloseChildAgent(destination, id);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CloseAgent(GridRegion destination, UUID id)
|
|
||||||
{
|
|
||||||
if (destination == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Try local first
|
|
||||||
if (m_localBackend.CloseAgent(destination, id))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// else do the remote thing
|
// else do the remote thing
|
||||||
if (!m_localBackend.IsLocalRegion(destination.RegionID))
|
if (!m_localBackend.IsLocalRegion(destination.RegionID))
|
||||||
return m_remoteConnector.CloseAgent(destination, id);
|
return m_remoteConnector.CloseAgent(destination, id, auth_token);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,47 +46,33 @@ 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 RegionStatsHandler(RegionInfo region_info)
|
||||||
public string Description { get { return "Region Statistics"; } }
|
: base("GET", "/" + Util.SHA1Hash(region_info.regionSecret), "RegionStats", "Region Statistics")
|
||||||
|
|
||||||
public RegionStatsHandler(RegionInfo region_info)
|
|
||||||
{
|
{
|
||||||
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()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -3611,7 +3609,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
regions.Remove(RegionInfo.RegionHandle);
|
regions.Remove(RegionInfo.RegionHandle);
|
||||||
|
|
||||||
// This ends up being done asynchronously so that a logout isn't held up where there are many present but unresponsive neighbours.
|
// This ends up being done asynchronously so that a logout isn't held up where there are many present but unresponsive neighbours.
|
||||||
m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
|
m_sceneGridService.SendCloseChildAgentConnections(agentID, acd.SessionID.ToString(), regions);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_eventManager.TriggerClientClosed(agentID, this);
|
m_eventManager.TriggerClientClosed(agentID, this);
|
||||||
|
@ -3858,8 +3856,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_log.WarnFormat(
|
m_log.WarnFormat(
|
||||||
"[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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4394,10 +4394,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (childAgentUpdate != null)
|
if (childAgentUpdate != null)
|
||||||
{
|
{
|
||||||
|
if (cAgentData.SessionID != childAgentUpdate.ControllingClient.SessionId)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).", childAgentUpdate.UUID, cAgentData.SessionID);
|
||||||
|
Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}",
|
||||||
|
childAgentUpdate.UUID, childAgentUpdate.ControllingClient.SessionId, cAgentData.SessionID));
|
||||||
|
}
|
||||||
|
|
||||||
childAgentUpdate.ChildAgentDataUpdate(cAgentData);
|
childAgentUpdate.ChildAgentDataUpdate(cAgentData);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4413,20 +4419,24 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
|
ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
|
||||||
if (childAgentUpdate != null)
|
if (childAgentUpdate != null)
|
||||||
{
|
{
|
||||||
// I can't imagine *yet* why we would get an update if the agent is a root agent..
|
if (childAgentUpdate.ControllingClient.SessionId == cAgentData.SessionID)
|
||||||
// however to avoid a race condition crossing borders..
|
|
||||||
if (childAgentUpdate.IsChildAgent)
|
|
||||||
{
|
{
|
||||||
uint rRegionX = (uint)(cAgentData.RegionHandle >> 40);
|
// I can't imagine *yet* why we would get an update if the agent is a root agent..
|
||||||
uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8);
|
// however to avoid a race condition crossing borders..
|
||||||
uint tRegionX = RegionInfo.RegionLocX;
|
if (childAgentUpdate.IsChildAgent)
|
||||||
uint tRegionY = RegionInfo.RegionLocY;
|
{
|
||||||
//Send Data to ScenePresence
|
uint rRegionX = (uint)(cAgentData.RegionHandle >> 40);
|
||||||
childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY);
|
uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8);
|
||||||
// Not Implemented:
|
uint tRegionX = RegionInfo.RegionLocX;
|
||||||
//TODO: Do we need to pass the message on to one of our neighbors?
|
uint tRegionY = RegionInfo.RegionLocY;
|
||||||
|
//Send Data to ScenePresence
|
||||||
|
childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY);
|
||||||
|
// Not Implemented:
|
||||||
|
//TODO: Do we need to pass the message on to one of our neighbors?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}", childAgentUpdate.UUID, cAgentData.SessionID);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4469,6 +4479,25 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Authenticated close (via network)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="agentID"></param>
|
||||||
|
/// <param name="force"></param>
|
||||||
|
/// <param name="auth_token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IncomingCloseAgent(UUID agentID, bool force, string auth_token)
|
||||||
|
{
|
||||||
|
//m_log.DebugFormat("[SCENE]: Processing incoming close agent {0} in region {1} with auth_token {2}", agentID, RegionInfo.RegionName, auth_token);
|
||||||
|
|
||||||
|
// Check that the auth_token is valid
|
||||||
|
AgentCircuitData acd = AuthenticateHandler.GetAgentCircuitData(agentID);
|
||||||
|
if (acd != null && acd.SessionID.ToString() == auth_token)
|
||||||
|
return IncomingCloseAgent(agentID, force);
|
||||||
|
else
|
||||||
|
m_log.ErrorFormat("[SCENE]: Request to close agent {0} with invalid authorization token {1}", agentID, auth_token);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public bool IncomingCloseAgent(UUID agentID)
|
public bool IncomingCloseAgent(UUID agentID)
|
||||||
{
|
{
|
||||||
|
@ -4491,7 +4520,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public bool IncomingCloseAgent(UUID agentID, bool force)
|
public bool IncomingCloseAgent(UUID agentID, bool force)
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
|
//m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
|
||||||
|
|
||||||
ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
|
ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
|
||||||
if (presence != null)
|
if (presence != null)
|
||||||
{
|
{
|
||||||
|
@ -4499,7 +4527,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Agent not here
|
// Agent not here
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5089,22 +5117,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)
|
||||||
|
|
|
@ -200,7 +200,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// This Closes child agents on neighboring regions
|
/// This Closes child agents on neighboring regions
|
||||||
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
|
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected void SendCloseChildAgentAsync(UUID agentID, ulong regionHandle)
|
protected void SendCloseChildAgent(UUID agentID, ulong regionHandle, string auth_token)
|
||||||
{
|
{
|
||||||
// let's do our best, but there's not much we can do if the neighbour doesn't accept.
|
// let's do our best, but there's not much we can do if the neighbour doesn't accept.
|
||||||
|
|
||||||
|
@ -209,24 +209,25 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Utils.LongToUInts(regionHandle, out x, out y);
|
Utils.LongToUInts(regionHandle, out x, out y);
|
||||||
|
|
||||||
GridRegion destination = m_scene.GridService.GetRegionByPosition(m_regionInfo.ScopeID, (int)x, (int)y);
|
GridRegion destination = m_scene.GridService.GetRegionByPosition(m_regionInfo.ScopeID, (int)x, (int)y);
|
||||||
m_scene.SimulationService.CloseChildAgent(destination, agentID);
|
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} to {1}", agentID, destination.RegionName);
|
||||||
|
|
||||||
|
m_scene.SimulationService.CloseAgent(destination, agentID, auth_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendCloseChildAgentCompleted(IAsyncResult iar)
|
/// <summary>
|
||||||
{
|
/// Closes a child agents in a collection of regions. Does so asynchronously
|
||||||
SendCloseChildAgentDelegate icon = (SendCloseChildAgentDelegate)iar.AsyncState;
|
/// so that the caller doesn't wait.
|
||||||
icon.EndInvoke(iar);
|
/// </summary>
|
||||||
}
|
/// <param name="agentID"></param>
|
||||||
|
/// <param name="regionslst"></param>
|
||||||
public void SendCloseChildAgentConnections(UUID agentID, List<ulong> regionslst)
|
public void SendCloseChildAgentConnections(UUID agentID, string auth_code, List<ulong> regionslst)
|
||||||
{
|
{
|
||||||
foreach (ulong handle in regionslst)
|
foreach (ulong handle in regionslst)
|
||||||
{
|
{
|
||||||
ulong handleCopy = handle;
|
ulong handleCopy = handle;
|
||||||
SendCloseChildAgentDelegate d = SendCloseChildAgentAsync;
|
Util.FireAndForget((o) => { SendCloseChildAgent(agentID, handleCopy, auth_code); });
|
||||||
d.BeginInvoke(agentID, handleCopy,
|
|
||||||
SendCloseChildAgentCompleted,
|
|
||||||
d);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -543,7 +543,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];
|
||||||
|
|
||||||
|
|
|
@ -696,7 +696,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </param>
|
/// </param>
|
||||||
public void StopScriptInstance(TaskInventoryItem item)
|
public void StopScriptInstance(TaskInventoryItem item)
|
||||||
{
|
{
|
||||||
m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID);
|
if (m_part.ParentGroup.Scene != null)
|
||||||
|
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.
|
||||||
// m_part.ParentGroup.AddActiveScriptCount(-1);
|
// m_part.ParentGroup.AddActiveScriptCount(-1);
|
||||||
|
|
|
@ -1151,9 +1151,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
MovementFlag = 0;
|
MovementFlag = 0;
|
||||||
|
|
||||||
m_scene.EventManager.TriggerOnMakeRootAgent(this);
|
// DIVA NOTE: I moved TriggerOnMakeRootAgent out of here and into the end of
|
||||||
|
// CompleteMovement. We don't want modules doing heavy computation before CompleteMovement
|
||||||
m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd;
|
// is over.
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetStateSource()
|
public int GetStateSource()
|
||||||
|
@ -1519,10 +1519,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
|
bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
|
||||||
MakeRootAgent(AbsolutePosition, flying);
|
MakeRootAgent(AbsolutePosition, flying);
|
||||||
ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
|
ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
|
||||||
|
// Remember in HandleUseCircuitCode, we delayed this to here
|
||||||
|
// This will also send the initial data to clients when TP to a neighboring region.
|
||||||
|
// Not ideal, but until we know we're TP-ing from a neighboring region, there's not much we can do
|
||||||
|
if (m_teleportFlags > 0)
|
||||||
|
SendInitialDataToMe();
|
||||||
|
|
||||||
// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
|
// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
|
||||||
|
|
||||||
if ((m_callbackURI != null) && !m_callbackURI.Equals(""))
|
if (!string.IsNullOrEmpty(m_callbackURI))
|
||||||
{
|
{
|
||||||
// We cannot sleep here since this would hold up the inbound packet processing thread, as
|
// We cannot sleep here since this would hold up the inbound packet processing thread, as
|
||||||
// CompleteMovement() is executed synchronously. However, it might be better to delay the release
|
// CompleteMovement() is executed synchronously. However, it might be better to delay the release
|
||||||
|
@ -1550,9 +1555,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// Create child agents in neighbouring regions
|
// Create child agents in neighbouring regions
|
||||||
if (openChildAgents && !IsChildAgent)
|
if (openChildAgents && !IsChildAgent)
|
||||||
{
|
{
|
||||||
// Remember in HandleUseCircuitCode, we delayed this to here
|
|
||||||
SendInitialDataToMe();
|
|
||||||
|
|
||||||
IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
|
IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
|
||||||
if (m_agentTransfer != null)
|
if (m_agentTransfer != null)
|
||||||
m_agentTransfer.EnableChildAgents(this);
|
m_agentTransfer.EnableChildAgents(this);
|
||||||
|
@ -1575,6 +1577,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
|
// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
|
||||||
// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
|
// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
|
||||||
|
|
||||||
|
// DIVA NOTE: moved this here from MakeRoot. We don't want modules making heavy
|
||||||
|
// computations before CompleteMovement is over
|
||||||
|
m_scene.EventManager.TriggerOnMakeRootAgent(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -2886,11 +2893,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
SendOtherAgentsAppearanceToMe();
|
SendOtherAgentsAppearanceToMe();
|
||||||
|
|
||||||
EntityBase[] entities = Scene.Entities.GetEntities();
|
EntityBase[] entities = Scene.Entities.GetEntities();
|
||||||
foreach(EntityBase e in entities)
|
foreach (EntityBase e in entities)
|
||||||
{
|
{
|
||||||
if (e != null && e is SceneObjectGroup)
|
if (e != null && e is SceneObjectGroup)
|
||||||
((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient);
|
((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3116,7 +3124,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
cadu.Velocity = Velocity;
|
cadu.Velocity = Velocity;
|
||||||
|
|
||||||
AgentPosition agentpos = new AgentPosition();
|
AgentPosition agentpos = new AgentPosition();
|
||||||
agentpos.CopyFrom(cadu);
|
agentpos.CopyFrom(cadu, ControllingClient.SessionId);
|
||||||
|
|
||||||
// Let's get this out of the update loop
|
// Let's get this out of the update loop
|
||||||
Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); });
|
Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); });
|
||||||
|
@ -3355,7 +3363,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents");
|
m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents");
|
||||||
|
|
||||||
m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, byebyeRegions);
|
AgentCircuitData acd = Scene.AuthenticateHandler.GetAgentCircuitData(UUID);
|
||||||
|
string auth = string.Empty;
|
||||||
|
if (acd != null)
|
||||||
|
auth = acd.SessionID.ToString();
|
||||||
|
m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (ulong handle in byebyeRegions)
|
foreach (ulong handle in byebyeRegions)
|
||||||
|
@ -3456,6 +3468,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
cAgent.AgentID = UUID;
|
cAgent.AgentID = UUID;
|
||||||
cAgent.RegionID = Scene.RegionInfo.RegionID;
|
cAgent.RegionID = Scene.RegionInfo.RegionID;
|
||||||
|
cAgent.SessionID = ControllingClient.SessionId;
|
||||||
|
|
||||||
cAgent.Position = AbsolutePosition;
|
cAgent.Position = AbsolutePosition;
|
||||||
cAgent.Velocity = m_velocity;
|
cAgent.Velocity = m_velocity;
|
||||||
|
|
|
@ -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.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -112,6 +112,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||||
//moveArgs.BodyRotation = Quaternion.CreateFromEulers(Vector3.Zero);
|
//moveArgs.BodyRotation = Quaternion.CreateFromEulers(Vector3.Zero);
|
||||||
moveArgs.BodyRotation = Quaternion.CreateFromEulers(new Vector3(0, 0, (float)-(Math.PI / 2)));
|
moveArgs.BodyRotation = Quaternion.CreateFromEulers(new Vector3(0, 0, (float)-(Math.PI / 2)));
|
||||||
moveArgs.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS;
|
moveArgs.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS;
|
||||||
|
moveArgs.SessionID = acd.SessionID;
|
||||||
|
|
||||||
originalSp.HandleAgentUpdate(originalSp.ControllingClient, moveArgs);
|
originalSp.HandleAgentUpdate(originalSp.ControllingClient, moveArgs);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -587,6 +597,102 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||||
(throttleRates.Asset * 8) / 1000);
|
(throttleRates.Asset * 8) / 1000);
|
||||||
|
|
||||||
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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,14 +415,7 @@ 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
|
||||||
{
|
te.DefaultTexture.MaterialID = id;
|
||||||
if (te.DefaultTexture.MaterialID == null)
|
|
||||||
m_log.Debug("[MaterialsDemoModule]: te.DefaultTexture.MaterialID is null");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
te.DefaultTexture.MaterialID = id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,26 +1041,37 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
Vector3 linearDeflectionV = Vector3.Zero;
|
Vector3 linearDeflectionV = Vector3.Zero;
|
||||||
Vector3 velocityV = VehicleForwardVelocity;
|
Vector3 velocityV = VehicleForwardVelocity;
|
||||||
|
|
||||||
// Velocity in Y and Z dimensions is movement to the side or turning.
|
if (BSParam.VehicleEnableLinearDeflection)
|
||||||
// Compute deflection factor from the to the side and rotational velocity
|
{
|
||||||
linearDeflectionV.Y = SortedClampInRange(0, (velocityV.Y * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Y);
|
// Velocity in Y and Z dimensions is movement to the side or turning.
|
||||||
linearDeflectionV.Z = SortedClampInRange(0, (velocityV.Z * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Z);
|
// Compute deflection factor from the to the side and rotational velocity
|
||||||
|
linearDeflectionV.Y = SortedClampInRange(0, (velocityV.Y * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Y);
|
||||||
|
linearDeflectionV.Z = SortedClampInRange(0, (velocityV.Z * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Z);
|
||||||
|
|
||||||
// Velocity to the side and around is corrected and moved into the forward direction
|
// Velocity to the side and around is corrected and moved into the forward direction
|
||||||
linearDeflectionV.X += Math.Abs(linearDeflectionV.Y);
|
linearDeflectionV.X += Math.Abs(linearDeflectionV.Y);
|
||||||
linearDeflectionV.X += Math.Abs(linearDeflectionV.Z);
|
linearDeflectionV.X += Math.Abs(linearDeflectionV.Z);
|
||||||
|
|
||||||
// Scale the deflection to the fractional simulation time
|
// Scale the deflection to the fractional simulation time
|
||||||
linearDeflectionV *= pTimestep;
|
linearDeflectionV *= pTimestep;
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
||||||
VDetailLog("{0}, MoveLinear,LinearDeflection,linDefEff={1},linDefTS={2},linDeflectionV={3}",
|
// Optionally, if not colliding, don't effect world downward velocity. Let falling things fall.
|
||||||
ControllingPrim.LocalID, m_linearDeflectionEfficiency, m_linearDeflectionTimescale, linearDeflectionV);
|
if (BSParam.VehicleLinearDeflectionNotCollidingNoZ && !m_controllingPrim.IsColliding)
|
||||||
|
{
|
||||||
|
linearDeflectionW.Z = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
VehicleVelocity += linearDeflectionW;
|
||||||
|
|
||||||
|
VDetailLog("{0}, MoveLinear,LinearDeflection,linDefEff={1},linDefTS={2},linDeflectionV={3}",
|
||||||
|
ControllingPrim.LocalID, m_linearDeflectionEfficiency, m_linearDeflectionTimescale, linearDeflectionV);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ComputeLinearTerrainHeightCorrection(float pTimestep)
|
public void ComputeLinearTerrainHeightCorrection(float pTimestep)
|
||||||
|
@ -1385,116 +1384,134 @@ 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)
|
||||||
{
|
{
|
||||||
//Another formula to try got from :
|
Vector3 vehicleUpAxis = Vector3.UnitZ * VehicleOrientation;
|
||||||
//http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html
|
switch (BSParam.VehicleAngularVerticalAttractionAlgorithm)
|
||||||
|
|
||||||
Vector3 VehicleUpAxis = Vector3.UnitZ * VehicleOrientation;
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
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
|
|
||||||
// this makes for a smoother adjustment and less fighting between the various forces.
|
|
||||||
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.
|
|
||||||
Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ);
|
|
||||||
|
|
||||||
// Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared
|
|
||||||
Vector3 vertContributionV = torqueVector * VerticalAttractionSpeed * VerticalAttractionSpeed;
|
|
||||||
|
|
||||||
VehicleRotationalVelocity += vertContributionV;
|
|
||||||
|
|
||||||
VDetailLog("{0}, MoveAngular,verticalAttraction,UpAxis={1},PredictedUp={2},torqueVector={3},contrib={4}",
|
|
||||||
ControllingPrim.LocalID,
|
|
||||||
VehicleUpAxis,
|
|
||||||
predictedUp,
|
|
||||||
torqueVector,
|
|
||||||
vertContributionV);
|
|
||||||
//=====================================================================
|
|
||||||
/*
|
|
||||||
// Possible solution derived from a discussion at:
|
|
||||||
// http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no
|
|
||||||
|
|
||||||
// Create a rotation that is only the vehicle's rotation around Z
|
|
||||||
Vector3 currentEuler = Vector3.Zero;
|
|
||||||
VehicleOrientation.GetEulerAngles(out currentEuler.X, out currentEuler.Y, out currentEuler.Z);
|
|
||||||
Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEuler.Z);
|
|
||||||
|
|
||||||
// Create the axis that is perpendicular to the up vector and the rotated up vector.
|
|
||||||
Vector3 differenceAxis = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation);
|
|
||||||
// Compute the angle between those to vectors.
|
|
||||||
double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation)));
|
|
||||||
// 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical
|
|
||||||
|
|
||||||
// Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied.
|
|
||||||
// TODO: add 'efficiency'.
|
|
||||||
differenceAngle /= m_verticalAttractionTimescale;
|
|
||||||
|
|
||||||
// Create the quaterian representing the correction angle
|
|
||||||
Quaternion correctionRotation = Quaternion.CreateFromAxisAngle(differenceAxis, (float)differenceAngle);
|
|
||||||
|
|
||||||
// Turn that quaternion into Euler values to make it into velocities to apply.
|
|
||||||
Vector3 vertContributionV = Vector3.Zero;
|
|
||||||
correctionRotation.GetEulerAngles(out vertContributionV.X, out vertContributionV.Y, out vertContributionV.Z);
|
|
||||||
vertContributionV *= -1f;
|
|
||||||
|
|
||||||
VehicleRotationalVelocity += vertContributionV;
|
|
||||||
|
|
||||||
VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}",
|
|
||||||
ControllingPrim.LocalID,
|
|
||||||
differenceAxis,
|
|
||||||
differenceAngle,
|
|
||||||
correctionRotation,
|
|
||||||
vertContributionV);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// ===================================================================
|
|
||||||
/*
|
|
||||||
Vector3 vertContributionV = Vector3.Zero;
|
|
||||||
Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG
|
|
||||||
|
|
||||||
// Take a vector pointing up and convert it from world to vehicle relative coords.
|
|
||||||
Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleOrientation);
|
|
||||||
|
|
||||||
// If vertical attraction correction is needed, the vector that was pointing up (UnitZ)
|
|
||||||
// is now:
|
|
||||||
// leaning to one side: rotated around the X axis with the Y value going
|
|
||||||
// from zero (nearly straight up) to one (completely to the side)) or
|
|
||||||
// leaning front-to-back: rotated around the Y axis with the value of X being between
|
|
||||||
// zero and one.
|
|
||||||
// The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees.
|
|
||||||
|
|
||||||
// Y error means needed rotation around X axis and visa versa.
|
|
||||||
// Since the error goes from zero to one, the asin is the corresponding angle.
|
|
||||||
vertContributionV.X = (float)Math.Asin(verticalError.Y);
|
|
||||||
// (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.)
|
|
||||||
vertContributionV.Y = -(float)Math.Asin(verticalError.X);
|
|
||||||
|
|
||||||
// If verticalError.Z is negative, the vehicle is upside down. Add additional push.
|
|
||||||
if (verticalError.Z < 0f)
|
|
||||||
{
|
{
|
||||||
vertContributionV.X += Math.Sign(vertContributionV.X) * PIOverFour;
|
case 0:
|
||||||
// vertContribution.Y -= PIOverFour;
|
{
|
||||||
|
//Another formula to try got from :
|
||||||
|
//http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
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
|
||||||
|
// this makes for a smoother adjustment and less fighting between the various forces.
|
||||||
|
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.
|
||||||
|
Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ);
|
||||||
|
|
||||||
|
// Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared
|
||||||
|
Vector3 vertContributionV = torqueVector * VerticalAttractionSpeed * VerticalAttractionSpeed;
|
||||||
|
|
||||||
|
VehicleRotationalVelocity += vertContributionV;
|
||||||
|
|
||||||
|
VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},PredictedUp={2},torqueVector={3},contrib={4}",
|
||||||
|
ControllingPrim.LocalID,
|
||||||
|
vehicleUpAxis,
|
||||||
|
predictedUp,
|
||||||
|
torqueVector,
|
||||||
|
vertContributionV);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
// Possible solution derived from a discussion at:
|
||||||
|
// http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no
|
||||||
|
|
||||||
|
// Create a rotation that is only the vehicle's rotation around Z
|
||||||
|
Vector3 currentEuler = Vector3.Zero;
|
||||||
|
VehicleOrientation.GetEulerAngles(out currentEuler.X, out currentEuler.Y, out currentEuler.Z);
|
||||||
|
Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEuler.Z);
|
||||||
|
|
||||||
|
// Create the axis that is perpendicular to the up vector and the rotated up vector.
|
||||||
|
Vector3 differenceAxis = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation);
|
||||||
|
// Compute the angle between those to vectors.
|
||||||
|
double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation)));
|
||||||
|
// 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical
|
||||||
|
|
||||||
|
// Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied.
|
||||||
|
// TODO: add 'efficiency'.
|
||||||
|
differenceAngle /= m_verticalAttractionTimescale;
|
||||||
|
|
||||||
|
// Create the quaterian representing the correction angle
|
||||||
|
Quaternion correctionRotation = Quaternion.CreateFromAxisAngle(differenceAxis, (float)differenceAngle);
|
||||||
|
|
||||||
|
// Turn that quaternion into Euler values to make it into velocities to apply.
|
||||||
|
Vector3 vertContributionV = Vector3.Zero;
|
||||||
|
correctionRotation.GetEulerAngles(out vertContributionV.X, out vertContributionV.Y, out vertContributionV.Z);
|
||||||
|
vertContributionV *= -1f;
|
||||||
|
|
||||||
|
VehicleRotationalVelocity += vertContributionV;
|
||||||
|
|
||||||
|
VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},diffAxis={2},diffAng={3},corrRot={4},contrib={5}",
|
||||||
|
ControllingPrim.LocalID,
|
||||||
|
vehicleUpAxis,
|
||||||
|
differenceAxis,
|
||||||
|
differenceAngle,
|
||||||
|
correctionRotation,
|
||||||
|
vertContributionV);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
Vector3 vertContributionV = Vector3.Zero;
|
||||||
|
Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG
|
||||||
|
|
||||||
|
// Take a vector pointing up and convert it from world to vehicle relative coords.
|
||||||
|
Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleOrientation);
|
||||||
|
|
||||||
|
// If vertical attraction correction is needed, the vector that was pointing up (UnitZ)
|
||||||
|
// is now:
|
||||||
|
// leaning to one side: rotated around the X axis with the Y value going
|
||||||
|
// from zero (nearly straight up) to one (completely to the side)) or
|
||||||
|
// leaning front-to-back: rotated around the Y axis with the value of X being between
|
||||||
|
// zero and one.
|
||||||
|
// The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees.
|
||||||
|
|
||||||
|
// Y error means needed rotation around X axis and visa versa.
|
||||||
|
// Since the error goes from zero to one, the asin is the corresponding angle.
|
||||||
|
vertContributionV.X = (float)Math.Asin(verticalError.Y);
|
||||||
|
// (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.)
|
||||||
|
vertContributionV.Y = -(float)Math.Asin(verticalError.X);
|
||||||
|
|
||||||
|
// If verticalError.Z is negative, the vehicle is upside down. Add additional push.
|
||||||
|
if (verticalError.Z < 0f)
|
||||||
|
{
|
||||||
|
vertContributionV.X += Math.Sign(vertContributionV.X) * PIOverFour;
|
||||||
|
// vertContribution.Y -= PIOverFour;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'vertContrbution' is now the necessary angular correction to correct tilt in one second.
|
||||||
|
// Correction happens over a number of seconds.
|
||||||
|
Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG
|
||||||
|
|
||||||
|
// The correction happens over the user's time period
|
||||||
|
vertContributionV /= m_verticalAttractionTimescale;
|
||||||
|
|
||||||
|
// Rotate the vehicle rotation to the world coordinates.
|
||||||
|
VehicleRotationalVelocity += (vertContributionV * VehicleOrientation);
|
||||||
|
|
||||||
|
VDetailLog("{0}, MoveAngular,verticalAttraction,,upAxis={1},origRotVW={2},vertError={3},unscaledV={4},eff={5},ts={6},vertContribV={7}",
|
||||||
|
ControllingPrim.LocalID,
|
||||||
|
vehicleUpAxis,
|
||||||
|
origRotVelW,
|
||||||
|
verticalError,
|
||||||
|
unscaledContribVerticalErrorV,
|
||||||
|
m_verticalAttractionEfficiency,
|
||||||
|
m_verticalAttractionTimescale,
|
||||||
|
vertContributionV);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'vertContrbution' is now the necessary angular correction to correct tilt in one second.
|
|
||||||
// Correction happens over a number of seconds.
|
|
||||||
Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG
|
|
||||||
|
|
||||||
// The correction happens over the user's time period
|
|
||||||
vertContributionV /= m_verticalAttractionTimescale;
|
|
||||||
|
|
||||||
// Rotate the vehicle rotation to the world coordinates.
|
|
||||||
VehicleRotationalVelocity += (vertContributionV * VehicleOrientation);
|
|
||||||
|
|
||||||
VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}",
|
|
||||||
Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV,
|
|
||||||
m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1504,13 +1521,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// in that direction.
|
// in that direction.
|
||||||
// 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;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
// Root shape is always index zero.
|
if (IsRoot(cPrim))
|
||||||
cPrim.LinksetChildIndex = IsRoot(cPrim) ? 0 : memberIndex;
|
{
|
||||||
|
// Root shape is always index zero.
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,14 +414,14 @@ 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);
|
||||||
derivFactor = new Vector3(factor, factor, factor);
|
derivFactor = new Vector3(factor, factor, factor);
|
||||||
|
|
||||||
MDetailLog("{0},BSPIDVMotor.setEfficiency,eff={1},factor={2}", BSScene.DetailLogZero, Efficiency, factor);
|
MDetailLog("{0}, BSPIDVMotor.setEfficiency,eff={1},factor={2}", BSScene.DetailLogZero, Efficiency, 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
PositionDisplacement = OMV.Vector3.Zero;
|
if (UserSetCenterOfMassDisplacement.HasValue)
|
||||||
OrientationDisplacement = OMV.Quaternion.Identity;
|
PositionDisplacement = (OMV.Vector3)UserSetCenterOfMassDisplacement;
|
||||||
|
else
|
||||||
|
PositionDisplacement = OMV.Vector3.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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);
|
|
||||||
DetailLog("{0},BSPrimDisplaced.ForcePosition,physPos={1},disp={2},newPos={3}", LocalID, entprop.Position, PositionDisplacement, displacedPos);
|
// Move the returned center-of-mass location to the root prim location.
|
||||||
|
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);
|
||||||
|
|
|
@ -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,13 +156,17 @@ 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 (makeStatic)
|
if (Linkset != null) // null can happen during initialization
|
||||||
Linkset.MakeStatic(this);
|
{
|
||||||
else
|
if (makeStatic)
|
||||||
Linkset.MakeDynamic(this);
|
Linkset.MakeStatic(this);
|
||||||
|
else
|
||||||
|
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.
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -353,6 +353,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||||
// Position of a sensor in a child prim attached to an avatar
|
// Position of a sensor in a child prim attached to an avatar
|
||||||
// will be still wrong.
|
// will be still wrong.
|
||||||
ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
|
ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
|
||||||
|
|
||||||
|
// Don't proceed if the avatar for this attachment has since been removed from the scene.
|
||||||
|
if (avatar == null)
|
||||||
|
return sensedEntities;
|
||||||
|
|
||||||
fromRegionPos = avatar.AbsolutePosition;
|
fromRegionPos = avatar.AbsolutePosition;
|
||||||
q = avatar.Rotation;
|
q = avatar.Rotation;
|
||||||
}
|
}
|
||||||
|
@ -483,6 +488,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||||
// Position of a sensor in a child prim attached to an avatar
|
// Position of a sensor in a child prim attached to an avatar
|
||||||
// will be still wrong.
|
// will be still wrong.
|
||||||
ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
|
ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
|
||||||
|
|
||||||
|
// Don't proceed if the avatar for this attachment has since been removed from the scene.
|
||||||
if (avatar == null)
|
if (avatar == null)
|
||||||
return sensedEntities;
|
return sensedEntities;
|
||||||
fromRegionPos = avatar.AbsolutePosition;
|
fromRegionPos = avatar.AbsolutePosition;
|
||||||
|
|
|
@ -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,7 @@ 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 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);
|
||||||
|
|
|
@ -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,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||||
m_LSL_Functions.llSetForceAndTorque(force, torque, local);
|
m_LSL_Functions.llSetForceAndTorque(force, torque, 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);
|
||||||
|
|
|
@ -242,7 +242,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op")
|
if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op")
|
||||||
{
|
{
|
||||||
m_coopTermination = true;
|
m_coopTermination = true;
|
||||||
m_coopSleepHandle = new AutoResetEvent(false);
|
m_coopSleepHandle = new XEngineEventWaitHandle(false, EventResetMode.AutoReset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1221,4 +1221,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
Suspended = false;
|
Suspended = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
|
/// Xengine event wait handle.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This class exists becase XEngineScriptBase gets a reference to this wait handle. We need to make sure that
|
||||||
|
/// when scripts are running in different AppDomains the lease does not expire.
|
||||||
|
/// FIXME: Like LSL_Api, etc., this effectively leaks memory since the GC will never collect it. To avoid this,
|
||||||
|
/// proper remoting sponsorship needs to be implemented across the board.
|
||||||
|
/// </remarks>
|
||||||
|
public class XEngineEventWaitHandle : EventWaitHandle
|
||||||
|
{
|
||||||
|
public XEngineEventWaitHandle(bool initialState, EventResetMode mode) : base(initialState, mode) {}
|
||||||
|
|
||||||
|
public override Object InitializeLifetimeService()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue