Merge branch 'master' into careminster
Conflicts: OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.csavinationmerge
commit
a7eb1b5b85
|
@ -64,7 +64,11 @@ namespace OpenSim.Framework.Capabilities
|
|||
public string CapsObjectPath { get { return m_capsObjectPath; } }
|
||||
|
||||
private CapsHandlers m_capsHandlers;
|
||||
private Dictionary<string, string> m_externalCapsHandlers;
|
||||
|
||||
private Dictionary<string, PollServiceEventArgs> m_pollServiceHandlers
|
||||
= new Dictionary<string, PollServiceEventArgs>();
|
||||
|
||||
private Dictionary<string, string> m_externalCapsHandlers = new Dictionary<string, string>();
|
||||
|
||||
private IHttpServer m_httpListener;
|
||||
private UUID m_agentID;
|
||||
|
@ -134,7 +138,6 @@ namespace OpenSim.Framework.Capabilities
|
|||
|
||||
m_agentID = agent;
|
||||
m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL);
|
||||
m_externalCapsHandlers = new Dictionary<string, string>();
|
||||
m_regionName = regionName;
|
||||
}
|
||||
|
||||
|
@ -149,6 +152,27 @@ namespace OpenSim.Framework.Capabilities
|
|||
m_capsHandlers[capName] = handler;
|
||||
}
|
||||
|
||||
public void RegisterPollHandler(string capName, PollServiceEventArgs pollServiceHandler)
|
||||
{
|
||||
m_pollServiceHandlers.Add(capName, pollServiceHandler);
|
||||
|
||||
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler.Url, pollServiceHandler);
|
||||
|
||||
// uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||
// string protocol = "http";
|
||||
// string hostName = m_httpListenerHostName;
|
||||
//
|
||||
// if (MainServer.Instance.UseSSL)
|
||||
// {
|
||||
// hostName = MainServer.Instance.SSLCommonName;
|
||||
// port = MainServer.Instance.SSLPort;
|
||||
// protocol = "https";
|
||||
// }
|
||||
|
||||
// RegisterHandler(
|
||||
// capName, String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, pollServiceHandler.Url));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register an external handler. The service for this capability is somewhere else
|
||||
/// given by the URL.
|
||||
|
@ -165,13 +189,70 @@ namespace OpenSim.Framework.Capabilities
|
|||
/// </summary>
|
||||
public void DeregisterHandlers()
|
||||
{
|
||||
if (m_capsHandlers != null)
|
||||
foreach (string capsName in m_capsHandlers.Caps)
|
||||
{
|
||||
foreach (string capsName in m_capsHandlers.Caps)
|
||||
m_capsHandlers.Remove(capsName);
|
||||
}
|
||||
|
||||
foreach (PollServiceEventArgs handler in m_pollServiceHandlers.Values)
|
||||
{
|
||||
m_httpListener.RemovePollServiceHTTPHandler("", handler.Url);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetPollHandler(string name, out PollServiceEventArgs pollHandler)
|
||||
{
|
||||
return m_pollServiceHandlers.TryGetValue(name, out pollHandler);
|
||||
}
|
||||
|
||||
public Dictionary<string, PollServiceEventArgs> GetPollHandlers()
|
||||
{
|
||||
return new Dictionary<string, PollServiceEventArgs>(m_pollServiceHandlers);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return an LLSD-serializable Hashtable describing the
|
||||
/// capabilities and their handler details.
|
||||
/// </summary>
|
||||
/// <param name="excludeSeed">If true, then exclude the seed cap.</param>
|
||||
public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps)
|
||||
{
|
||||
Hashtable caps = CapsHandlers.GetCapsDetails(excludeSeed, requestedCaps);
|
||||
|
||||
lock (m_pollServiceHandlers)
|
||||
{
|
||||
foreach (KeyValuePair <string, PollServiceEventArgs> kvp in m_pollServiceHandlers)
|
||||
{
|
||||
m_capsHandlers.Remove(capsName);
|
||||
if (!requestedCaps.Contains(kvp.Key))
|
||||
continue;
|
||||
|
||||
string hostName = m_httpListenerHostName;
|
||||
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||
string protocol = "http";
|
||||
|
||||
if (MainServer.Instance.UseSSL)
|
||||
{
|
||||
hostName = MainServer.Instance.SSLCommonName;
|
||||
port = MainServer.Instance.SSLPort;
|
||||
protocol = "https";
|
||||
}
|
||||
//
|
||||
// caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
|
||||
|
||||
caps[kvp.Key] = string.Format("{0}://{1}:{2}{3}", protocol, hostName, port, kvp.Value.Url);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the external too
|
||||
foreach (KeyValuePair<string, string> kvp in ExternalCapsHandlers)
|
||||
{
|
||||
if (!requestedCaps.Contains(kvp.Key))
|
||||
continue;
|
||||
|
||||
caps[kvp.Key] = kvp.Value;
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
|
@ -185,4 +266,4 @@ namespace OpenSim.Framework.Capabilities
|
|||
return m_capsActive.WaitOne(30000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -77,20 +77,34 @@ namespace OpenSim.Data.Null
|
|||
}
|
||||
|
||||
#region Environment Settings
|
||||
|
||||
private Dictionary<UUID, string> EnvironmentSettings = new Dictionary<UUID, string>();
|
||||
|
||||
public string LoadRegionEnvironmentSettings(UUID regionUUID)
|
||||
{
|
||||
//This connector doesn't support the Environment module yet
|
||||
lock (EnvironmentSettings)
|
||||
{
|
||||
if (EnvironmentSettings.ContainsKey(regionUUID))
|
||||
return EnvironmentSettings[regionUUID];
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
|
||||
{
|
||||
//This connector doesn't support the Environment module yet
|
||||
lock (EnvironmentSettings)
|
||||
{
|
||||
EnvironmentSettings[regionUUID] = settings;
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
|
||||
{
|
||||
//This connector doesn't support the Environment module yet
|
||||
lock (EnvironmentSettings)
|
||||
{
|
||||
if (EnvironmentSettings.ContainsKey(regionUUID))
|
||||
EnvironmentSettings.Remove(regionUUID);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
:VERSION 1 # --------------------------
|
||||
:VERSION 2 # --------------------------
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE hg_traveling_data (
|
||||
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;
|
||||
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 DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY(SessionID),
|
||||
UNIQUE(UserID)
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace OpenSim.Framework
|
|||
{
|
||||
lock (m_queueSync)
|
||||
{
|
||||
if (m_queue.Count < 1 && m_pqueue.Count < 1)
|
||||
while (m_queue.Count < 1 && m_pqueue.Count < 1)
|
||||
{
|
||||
Monitor.Wait(m_queueSync);
|
||||
}
|
||||
|
@ -76,9 +76,10 @@ namespace OpenSim.Framework
|
|||
{
|
||||
lock (m_queueSync)
|
||||
{
|
||||
if (m_queue.Count < 1 && m_pqueue.Count < 1)
|
||||
bool success = true;
|
||||
while (m_queue.Count < 1 && m_pqueue.Count < 1 && success)
|
||||
{
|
||||
Monitor.Wait(m_queueSync, msTimeout);
|
||||
success = Monitor.Wait(m_queueSync, msTimeout);
|
||||
}
|
||||
|
||||
if (m_pqueue.Count > 0)
|
||||
|
@ -89,8 +90,17 @@ namespace OpenSim.Framework
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicate whether this queue contains the given item.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method is not thread-safe. Do not rely on the result without consistent external locking.
|
||||
/// </remarks>
|
||||
public bool Contains(T item)
|
||||
{
|
||||
if (m_queue.Count < 1 && m_pqueue.Count < 1)
|
||||
return false;
|
||||
|
||||
lock (m_queueSync)
|
||||
{
|
||||
if (m_pqueue.Contains(item))
|
||||
|
@ -99,16 +109,28 @@ namespace OpenSim.Framework
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a count of the number of requests on this queue.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method is not thread-safe. Do not rely on the result without consistent external locking.
|
||||
/// </remarks>
|
||||
public int Count()
|
||||
{
|
||||
lock (m_queueSync)
|
||||
{
|
||||
return m_queue.Count+m_pqueue.Count;
|
||||
}
|
||||
return m_queue.Count + m_pqueue.Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the array of items on this queue.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method is not thread-safe. Do not rely on the result without consistent external locking.
|
||||
/// </remarks>
|
||||
public T[] GetQueueArray()
|
||||
{
|
||||
if (m_queue.Count < 1 && m_pqueue.Count < 1)
|
||||
return new T[0];
|
||||
|
||||
lock (m_queueSync)
|
||||
{
|
||||
return m_queue.ToArray();
|
||||
|
|
|
@ -234,7 +234,7 @@ namespace OpenSim.Framework.Console
|
|||
string uri = "/ReadResponses/" + sessionID.ToString() + "/";
|
||||
|
||||
m_Server.AddPollServiceHTTPHandler(
|
||||
uri, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout
|
||||
uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout
|
||||
|
||||
XmlDocument xmldoc = new XmlDocument();
|
||||
XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
|
||||
|
|
|
@ -387,6 +387,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
|
||||
if (TryGetPollServiceHTTPHandler(request.UriPath.ToString(), out psEvArgs))
|
||||
{
|
||||
psEvArgs.RequestsReceived++;
|
||||
|
||||
PollServiceHttpRequest psreq = new PollServiceHttpRequest(psEvArgs, context, request);
|
||||
|
||||
if (psEvArgs.Request != null)
|
||||
|
|
|
@ -50,25 +50,39 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
|
||||
public enum EventType : int
|
||||
{
|
||||
Normal = 0,
|
||||
LongPoll = 0,
|
||||
LslHttp = 1,
|
||||
Inventory = 2,
|
||||
Texture = 3,
|
||||
Mesh = 4
|
||||
}
|
||||
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of requests received for this poll service.
|
||||
/// </summary>
|
||||
public int RequestsReceived { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of requests handled by this poll service.
|
||||
/// </summary>
|
||||
public int RequestsHandled { get; set; }
|
||||
|
||||
public PollServiceEventArgs(
|
||||
RequestMethod pRequest,
|
||||
string pUrl,
|
||||
HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,
|
||||
UUID pId, int pTimeOutms)
|
||||
{
|
||||
Request = pRequest;
|
||||
Url = pUrl;
|
||||
HasEvents = pHasEvents;
|
||||
GetEvents = pGetEvents;
|
||||
NoEvents = pNoEvents;
|
||||
Id = pId;
|
||||
TimeOutms = pTimeOutms;
|
||||
Type = EventType.Normal;
|
||||
Type = EventType.LongPoll;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,13 +26,19 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using HttpServer;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
public class PollServiceHttpRequest
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public readonly PollServiceEventArgs PollServiceArgs;
|
||||
public readonly IHttpClientContext HttpContext;
|
||||
public readonly IHttpRequest Request;
|
||||
|
@ -48,5 +54,44 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
RequestTime = System.Environment.TickCount;
|
||||
RequestID = UUID.Random();
|
||||
}
|
||||
|
||||
internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata)
|
||||
{
|
||||
OSHttpResponse response
|
||||
= new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext);
|
||||
|
||||
byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
|
||||
|
||||
response.SendChunked = false;
|
||||
response.ContentLength64 = buffer.Length;
|
||||
response.ContentEncoding = Encoding.UTF8;
|
||||
|
||||
try
|
||||
{
|
||||
response.OutputStream.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex));
|
||||
}
|
||||
finally
|
||||
{
|
||||
//response.OutputStream.Close();
|
||||
try
|
||||
{
|
||||
response.OutputStream.Flush();
|
||||
response.Send();
|
||||
|
||||
//if (!response.KeepAlive && response.ReuseContext)
|
||||
// response.FreeContext();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e));
|
||||
}
|
||||
|
||||
PollServiceArgs.RequestsHandled++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -105,7 +105,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
{
|
||||
if (m_running)
|
||||
{
|
||||
if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.Normal)
|
||||
if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.LongPoll)
|
||||
{
|
||||
m_requests.Enqueue(req);
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
if (responsedata == null)
|
||||
continue;
|
||||
|
||||
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.Normal) // This is the event queue
|
||||
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) // This is the event queue
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
@ -1791,10 +1791,12 @@ namespace OpenSim.Framework
|
|||
FireAndForget(callback, null);
|
||||
}
|
||||
|
||||
public static void InitThreadPool(int maxThreads)
|
||||
public static void InitThreadPool(int minThreads, int maxThreads)
|
||||
{
|
||||
if (maxThreads < 2)
|
||||
throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2");
|
||||
if (minThreads > maxThreads || minThreads < 2)
|
||||
throw new ArgumentOutOfRangeException("minThreads", "minThreads must be greater than 2 and less than or equal to maxThreads");
|
||||
if (m_ThreadPool != null)
|
||||
throw new InvalidOperationException("SmartThreadPool is already initialized");
|
||||
|
||||
|
@ -1802,7 +1804,7 @@ namespace OpenSim.Framework
|
|||
startInfo.ThreadPoolName = "Util";
|
||||
startInfo.IdleTimeout = 2000;
|
||||
startInfo.MaxWorkerThreads = maxThreads;
|
||||
startInfo.MinWorkerThreads = 2;
|
||||
startInfo.MinWorkerThreads = minThreads;
|
||||
|
||||
m_ThreadPool = new SmartThreadPool(startInfo);
|
||||
}
|
||||
|
@ -1877,7 +1879,7 @@ namespace OpenSim.Framework
|
|||
break;
|
||||
case FireAndForgetMethod.SmartThreadPool:
|
||||
if (m_ThreadPool == null)
|
||||
InitThreadPool(15);
|
||||
InitThreadPool(2, 15);
|
||||
m_ThreadPool.QueueWorkItem((cb, o) => cb(o), realCallback, obj);
|
||||
break;
|
||||
case FireAndForgetMethod.Thread:
|
||||
|
@ -2265,7 +2267,7 @@ namespace OpenSim.Framework
|
|||
{
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
m_lowQueue.Enqueue(data);
|
||||
q.Enqueue(data);
|
||||
m_s.WaitOne(0);
|
||||
m_s.Release();
|
||||
}
|
||||
|
@ -2305,7 +2307,7 @@ namespace OpenSim.Framework
|
|||
{
|
||||
if (m_highQueue.Count > 0)
|
||||
res = m_highQueue.Dequeue();
|
||||
else
|
||||
else if (m_lowQueue.Count > 0)
|
||||
res = m_lowQueue.Dequeue();
|
||||
|
||||
if (m_highQueue.Count == 0 && m_lowQueue.Count == 0)
|
||||
|
|
|
@ -86,6 +86,7 @@ namespace OpenSim
|
|||
IConfig startupConfig = Config.Configs["Startup"];
|
||||
IConfig networkConfig = Config.Configs["Network"];
|
||||
|
||||
int stpMinThreads = 2;
|
||||
int stpMaxThreads = 15;
|
||||
|
||||
if (startupConfig != null)
|
||||
|
@ -112,12 +113,13 @@ namespace OpenSim
|
|||
if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod))
|
||||
Util.FireAndForgetMethod = asyncCallMethod;
|
||||
|
||||
stpMinThreads = startupConfig.GetInt("MinPoolThreads", 15);
|
||||
stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 15);
|
||||
m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) ");
|
||||
}
|
||||
|
||||
if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
|
||||
Util.InitThreadPool(stpMaxThreads);
|
||||
Util.InitThreadPool(stpMinThreads, stpMaxThreads);
|
||||
|
||||
m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod);
|
||||
}
|
||||
|
@ -423,8 +425,8 @@ namespace OpenSim
|
|||
{
|
||||
RegionInfo regionInfo = presence.Scene.RegionInfo;
|
||||
|
||||
if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) &&
|
||||
presence.Lastname.ToLower().Contains(mainParams[3].ToLower()))
|
||||
if (presence.Firstname.ToLower().Equals(mainParams[2].ToLower()) &&
|
||||
presence.Lastname.ToLower().Equals(mainParams[3].ToLower()))
|
||||
{
|
||||
MainConsole.Instance.Output(
|
||||
String.Format(
|
||||
|
@ -438,6 +440,7 @@ namespace OpenSim
|
|||
presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n");
|
||||
|
||||
presence.Scene.IncomingCloseAgent(presence.UUID, force);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -367,18 +367,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
foreach (OSD c in capsRequested)
|
||||
validCaps.Add(c.AsString());
|
||||
|
||||
Hashtable caps = m_HostCapsObj.CapsHandlers.GetCapsDetails(true, validCaps);
|
||||
|
||||
// Add the external too
|
||||
foreach (KeyValuePair<string, string> kvp in m_HostCapsObj.ExternalCapsHandlers)
|
||||
{
|
||||
if (!validCaps.Contains(kvp.Key))
|
||||
continue;
|
||||
|
||||
caps[kvp.Key] = kvp.Value;
|
||||
}
|
||||
|
||||
string result = LLSDHelpers.SerialiseLLSDReply(caps);
|
||||
string result = LLSDHelpers.SerialiseLLSDReply(m_HostCapsObj.GetCapsDetails(true, validCaps));
|
||||
|
||||
//m_log.DebugFormat("[CAPS] CapsRequest {0}", result);
|
||||
|
||||
|
|
|
@ -65,6 +65,13 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
/// </value>
|
||||
public int DebugLevel { get; set; }
|
||||
|
||||
// Viewer post requests timeout in 60 secs
|
||||
// https://bitbucket.org/lindenlab/viewer-release/src/421c20423df93d650cc305dc115922bb30040999/indra/llmessage/llhttpclient.cpp?at=default#cl-44
|
||||
//
|
||||
private const int VIEWER_TIMEOUT = 60 * 1000;
|
||||
// Just to be safe, we work on a 10 sec shorter cycle
|
||||
private const int SERVER_EQ_TIME_NO_EVENTS = VIEWER_TIMEOUT - (10 * 1000);
|
||||
|
||||
protected Scene m_scene;
|
||||
|
||||
private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
|
||||
|
@ -252,29 +259,32 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
|
||||
List<UUID> removeitems = new List<UUID>();
|
||||
lock (m_AvatarQueueUUIDMapping)
|
||||
{
|
||||
foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
|
||||
{
|
||||
// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
|
||||
if (ky == agentID)
|
||||
{
|
||||
removeitems.Add(ky);
|
||||
}
|
||||
}
|
||||
m_AvatarQueueUUIDMapping.Remove(agentID);
|
||||
|
||||
foreach (UUID ky in removeitems)
|
||||
{
|
||||
UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
|
||||
m_AvatarQueueUUIDMapping.Remove(ky);
|
||||
|
||||
string eqgPath = GenerateEqgCapPath(eventQueueGetUuid);
|
||||
MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}",
|
||||
// eqgPath, agentID, m_scene.RegionInfo.RegionName);
|
||||
}
|
||||
}
|
||||
// lock (m_AvatarQueueUUIDMapping)
|
||||
// {
|
||||
// foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
|
||||
// {
|
||||
//// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
|
||||
// if (ky == agentID)
|
||||
// {
|
||||
// removeitems.Add(ky);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// foreach (UUID ky in removeitems)
|
||||
// {
|
||||
// UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
|
||||
// m_AvatarQueueUUIDMapping.Remove(ky);
|
||||
//
|
||||
// string eqgPath = GenerateEqgCapPath(eventQueueGetUuid);
|
||||
// MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath);
|
||||
//
|
||||
//// m_log.DebugFormat(
|
||||
//// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}",
|
||||
//// eqgPath, agentID, m_scene.RegionInfo.RegionName);
|
||||
// }
|
||||
// }
|
||||
|
||||
UUID searchval = UUID.Zero;
|
||||
|
||||
|
@ -359,29 +369,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
|
||||
}
|
||||
|
||||
string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID);
|
||||
|
||||
// Register this as a caps handler
|
||||
// FIXME: Confusingly, we need to register separate as a capability so that the client is told about
|
||||
// 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
|
||||
// really it should be possible to directly register the poll handler as a capability.
|
||||
caps.RegisterHandler(
|
||||
"EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null, "EventQueueGet", null));
|
||||
// delegate(Hashtable m_dhttpMethod)
|
||||
// {
|
||||
// return ProcessQueue(m_dhttpMethod, agentID, caps);
|
||||
// }));
|
||||
|
||||
// This will persist this beyond the expiry of the caps handlers
|
||||
// TODO: Add EventQueueGet name/description for diagnostics
|
||||
MainServer.Instance.AddPollServiceHTTPHandler(
|
||||
eventQueueGetPath,
|
||||
new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID, 40000));
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}",
|
||||
// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName);
|
||||
caps.RegisterPollHandler(
|
||||
"EventQueueGet",
|
||||
new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
|
||||
|
||||
Random rnd = new Random(Environment.TickCount);
|
||||
lock (m_ids)
|
||||
|
@ -399,7 +389,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
Queue<OSD> queue = GetQueue(agentID);
|
||||
if (queue != null)
|
||||
lock (queue)
|
||||
{
|
||||
//m_log.WarnFormat("POLLED FOR EVENTS BY {0} in {1} -- {2}", agentID, m_scene.RegionInfo.RegionName, queue.Count);
|
||||
return queue.Count > 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -422,7 +415,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
public Hashtable GetEvents(UUID requestID, UUID pAgentId)
|
||||
{
|
||||
if (DebugLevel >= 2)
|
||||
m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName);
|
||||
m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName);
|
||||
|
||||
Queue<OSD> queue = TryGetQueue(pAgentId);
|
||||
OSD element;
|
||||
|
|
|
@ -246,8 +246,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
|
||||
private Scene m_scene;
|
||||
private MeshCapsDataThrottler m_throttler;
|
||||
public PollServiceMeshEventArgs(UUID pId, Scene scene) :
|
||||
base(null, null, null, null, pId, int.MaxValue)
|
||||
public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) :
|
||||
base(null, uri, null, null, null, pId, int.MaxValue)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId);
|
||||
|
@ -361,7 +361,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
string capUrl = "/CAPS/" + UUID.Random() + "/";
|
||||
|
||||
// Register this as a poll service
|
||||
PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(agentID, m_scene);
|
||||
PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(capUrl, agentID, m_scene);
|
||||
|
||||
args.Type = PollServiceEventArgs.EventType.Mesh;
|
||||
MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
|
||||
|
|
|
@ -210,7 +210,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
private Scene m_scene;
|
||||
private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000);
|
||||
public PollServiceTextureEventArgs(UUID pId, Scene scene) :
|
||||
base(null, null, null, null, pId, int.MaxValue)
|
||||
base(null, "", null, null, null, pId, int.MaxValue)
|
||||
{
|
||||
m_scene = scene;
|
||||
// x is request id, y is userid
|
||||
|
|
|
@ -78,7 +78,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
|
||||
private static WebFetchInvDescHandler m_webFetchHandler;
|
||||
|
||||
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
|
||||
private static Thread[] m_workerThreads = null;
|
||||
|
||||
private static DoubleQueue<aPollRequest> m_queue =
|
||||
|
@ -115,7 +114,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
return;
|
||||
|
||||
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||
m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
|
||||
|
||||
foreach (Thread t in m_workerThreads)
|
||||
Watchdog.AbortThread(t.ManagedThreadId);
|
||||
|
@ -135,7 +133,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
|
||||
|
||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||
m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
|
||||
|
||||
if (m_workerThreads == null)
|
||||
{
|
||||
|
@ -178,8 +175,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
|
||||
private Scene m_scene;
|
||||
|
||||
public PollServiceInventoryEventArgs(Scene scene, UUID pId) :
|
||||
base(null, null, null, null, pId, int.MaxValue)
|
||||
public PollServiceInventoryEventArgs(Scene scene, string url, UUID pId) :
|
||||
base(null, url, null, null, null, pId, int.MaxValue)
|
||||
{
|
||||
m_scene = scene;
|
||||
|
||||
|
@ -310,40 +307,39 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
if (m_fetchInventoryDescendents2Url == "")
|
||||
return;
|
||||
|
||||
string capUrl = "/CAPS/" + UUID.Random() + "/";
|
||||
|
||||
// Register this as a poll service
|
||||
PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(m_scene, agentID);
|
||||
|
||||
PollServiceInventoryEventArgs args
|
||||
= new PollServiceInventoryEventArgs(m_scene, "/CAPS/" + UUID.Random() + "/", agentID);
|
||||
args.Type = PollServiceEventArgs.EventType.Inventory;
|
||||
MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
|
||||
|
||||
string hostName = m_scene.RegionInfo.ExternalHostName;
|
||||
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||
string protocol = "http";
|
||||
|
||||
if (MainServer.Instance.UseSSL)
|
||||
{
|
||||
hostName = MainServer.Instance.SSLCommonName;
|
||||
port = MainServer.Instance.SSLPort;
|
||||
protocol = "https";
|
||||
}
|
||||
caps.RegisterPollHandler("FetchInventoryDescendents2", args);
|
||||
|
||||
caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
|
||||
|
||||
m_capsDict[agentID] = capUrl;
|
||||
// MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
|
||||
//
|
||||
// string hostName = m_scene.RegionInfo.ExternalHostName;
|
||||
// uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||
// string protocol = "http";
|
||||
//
|
||||
// if (MainServer.Instance.UseSSL)
|
||||
// {
|
||||
// hostName = MainServer.Instance.SSLCommonName;
|
||||
// port = MainServer.Instance.SSLPort;
|
||||
// protocol = "https";
|
||||
// }
|
||||
//
|
||||
// caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
|
||||
}
|
||||
|
||||
private void DeregisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
string capUrl;
|
||||
|
||||
if (m_capsDict.TryGetValue(agentID, out capUrl))
|
||||
{
|
||||
MainServer.Instance.RemoveHTTPHandler("", capUrl);
|
||||
m_capsDict.Remove(agentID);
|
||||
}
|
||||
}
|
||||
// private void DeregisterCaps(UUID agentID, Caps caps)
|
||||
// {
|
||||
// string capUrl;
|
||||
//
|
||||
// if (m_capsDict.TryGetValue(agentID, out capUrl))
|
||||
// {
|
||||
// MainServer.Instance.RemoveHTTPHandler("", capUrl);
|
||||
// m_capsDict.Remove(agentID);
|
||||
// }
|
||||
// }
|
||||
|
||||
private void DoInventoryRequests()
|
||||
{
|
||||
|
@ -353,7 +349,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
|
||||
aPollRequest poolreq = m_queue.Dequeue();
|
||||
|
||||
poolreq.thepoll.Process(poolreq);
|
||||
if (poolreq != null && poolreq.thepoll != null)
|
||||
poolreq.thepoll.Process(poolreq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3816,6 +3816,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
ResendPrimUpdate(update);
|
||||
}
|
||||
|
||||
// OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
|
||||
// OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
|
||||
// OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
|
||||
// OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
|
||||
//
|
||||
// OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||
// OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||
// OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||
// OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||
|
||||
|
||||
private void ProcessEntityUpdates(int maxUpdates)
|
||||
{
|
||||
OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
|
||||
|
@ -3828,6 +3839,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||
OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||
|
||||
// objectUpdateBlocks.Value.Clear();
|
||||
// compressedUpdateBlocks.Value.Clear();
|
||||
// terseUpdateBlocks.Value.Clear();
|
||||
// terseAgentUpdateBlocks.Value.Clear();
|
||||
// objectUpdates.Value.Clear();
|
||||
// compressedUpdates.Value.Clear();
|
||||
// terseUpdates.Value.Clear();
|
||||
// terseAgentUpdates.Value.Clear();
|
||||
|
||||
// Check to see if this is a flush
|
||||
if (maxUpdates <= 0)
|
||||
{
|
||||
|
|
|
@ -809,8 +809,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
}
|
||||
|
||||
PacketPool.Instance.ReturnPacket(packet);
|
||||
m_dataPresentEvent.Set();
|
||||
|
||||
}
|
||||
|
||||
private AutoResetEvent m_dataPresentEvent = new AutoResetEvent(false);
|
||||
|
||||
/// <summary>
|
||||
/// Start the process of sending a packet to the client.
|
||||
/// </summary>
|
||||
|
@ -1730,6 +1734,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// Action generic every round
|
||||
Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler;
|
||||
|
||||
// while (true)
|
||||
while (base.IsRunningOutbound)
|
||||
{
|
||||
m_scene.ThreadAlive(2);
|
||||
|
@ -1791,8 +1796,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
// If nothing was sent, sleep for the minimum amount of time before a
|
||||
// token bucket could get more tokens
|
||||
if (!m_packetSent)
|
||||
Thread.Sleep((int)TickCountResolution);
|
||||
//if (!m_packetSent)
|
||||
// Thread.Sleep((int)TickCountResolution);
|
||||
m_dataPresentEvent.WaitOne(100);
|
||||
|
||||
Watchdog.UpdateThread();
|
||||
}
|
||||
|
|
|
@ -75,10 +75,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
public void AddRegion(Scene scene)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
|
||||
|
||||
if (Enabled)
|
||||
{
|
||||
// Only register module with scene if it is enabled. All callers check for a null attachments module.
|
||||
// Ideally, there should be a null attachments module for when this core attachments module has been
|
||||
// disabled. Registering only when enabled allows for other attachments module implementations.
|
||||
m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
|
||||
m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
|
||||
m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true);
|
||||
m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false);
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Comms", false, "show caps stats by user",
|
||||
"show caps stats [<first-name> <last-name>]",
|
||||
"show caps stats by user [<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);
|
||||
|
@ -296,27 +296,31 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
return;
|
||||
|
||||
StringBuilder caps = new StringBuilder();
|
||||
caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
|
||||
StringBuilder capsReport = new StringBuilder();
|
||||
capsReport.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
|
||||
|
||||
lock (m_capsObjects)
|
||||
{
|
||||
foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects)
|
||||
{
|
||||
caps.AppendFormat("** Circuit {0}:\n", kvp.Key);
|
||||
capsReport.AppendFormat("** Circuit {0}:\n", kvp.Key);
|
||||
Caps caps = kvp.Value;
|
||||
|
||||
for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); )
|
||||
for (IDictionaryEnumerator kvp2 = caps.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); )
|
||||
{
|
||||
Uri uri = new Uri(kvp2.Value.ToString());
|
||||
caps.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery);
|
||||
capsReport.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, string> kvp3 in kvp.Value.ExternalCapsHandlers)
|
||||
caps.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value);
|
||||
foreach (KeyValuePair<string, PollServiceEventArgs> kvp2 in caps.GetPollHandlers())
|
||||
capsReport.AppendFormat(m_showCapsCommandFormat, kvp2.Key, kvp2.Value.Url);
|
||||
|
||||
foreach (KeyValuePair<string, string> kvp3 in caps.ExternalCapsHandlers)
|
||||
capsReport.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value);
|
||||
}
|
||||
}
|
||||
|
||||
MainConsole.Instance.Output(caps.ToString());
|
||||
MainConsole.Instance.Output(capsReport.ToString());
|
||||
}
|
||||
|
||||
private void HandleShowCapsStatsByCapCommand(string module, string[] cmdParams)
|
||||
|
@ -374,7 +378,16 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
{
|
||||
receivedStats[sp.Name] = reqHandler.RequestsReceived;
|
||||
handledStats[sp.Name] = reqHandler.RequestsHandled;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PollServiceEventArgs pollHandler = null;
|
||||
if (caps.TryGetPollHandler(capName, out pollHandler))
|
||||
{
|
||||
receivedStats[sp.Name] = pollHandler.RequestsReceived;
|
||||
handledStats[sp.Name] = pollHandler.RequestsHandled;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -405,11 +418,9 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
|
||||
|
||||
if (caps == null)
|
||||
return;
|
||||
return;
|
||||
|
||||
Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
|
||||
|
||||
foreach (IRequestHandler reqHandler in capsHandlers.Values)
|
||||
foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values)
|
||||
{
|
||||
string reqName = reqHandler.Name ?? "";
|
||||
|
||||
|
@ -424,6 +435,23 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
handledStats[reqName] += reqHandler.RequestsHandled;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, PollServiceEventArgs> kvp in caps.GetPollHandlers())
|
||||
{
|
||||
string name = kvp.Key;
|
||||
PollServiceEventArgs pollHandler = kvp.Value;
|
||||
|
||||
if (!receivedStats.ContainsKey(name))
|
||||
{
|
||||
receivedStats[name] = pollHandler.RequestsReceived;
|
||||
handledStats[name] = pollHandler.RequestsHandled;
|
||||
}
|
||||
else
|
||||
{
|
||||
receivedStats[name] += pollHandler.RequestsReceived;
|
||||
handledStats[name] += pollHandler.RequestsHandled;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -486,12 +514,16 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
if (caps == null)
|
||||
return;
|
||||
|
||||
Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
|
||||
List<CapTableRow> capRows = new List<CapTableRow>();
|
||||
|
||||
foreach (IRequestHandler reqHandler in capsHandlers.Values.OrderByDescending(rh => rh.RequestsReceived))
|
||||
{
|
||||
cdt.AddRow(reqHandler.Name, reqHandler.RequestsReceived, reqHandler.RequestsHandled);
|
||||
}
|
||||
foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values)
|
||||
capRows.Add(new CapTableRow(reqHandler.Name, reqHandler.RequestsReceived, reqHandler.RequestsHandled));
|
||||
|
||||
foreach (KeyValuePair<string, PollServiceEventArgs> kvp in caps.GetPollHandlers())
|
||||
capRows.Add(new CapTableRow(kvp.Key, kvp.Value.RequestsReceived, kvp.Value.RequestsHandled));
|
||||
|
||||
foreach (CapTableRow ctr in capRows.OrderByDescending(ctr => ctr.RequestsReceived))
|
||||
cdt.AddRow(ctr.Name, ctr.RequestsReceived, ctr.RequestsHandled);
|
||||
|
||||
sb.Append(cdt.ToString());
|
||||
*/
|
||||
|
@ -525,6 +557,14 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
totalRequestsReceived += reqHandler.RequestsReceived;
|
||||
totalRequestsHandled += reqHandler.RequestsHandled;
|
||||
}
|
||||
|
||||
Dictionary<string, PollServiceEventArgs> capsPollHandlers = caps.GetPollHandlers();
|
||||
|
||||
foreach (PollServiceEventArgs handler in capsPollHandlers.Values)
|
||||
{
|
||||
totalRequestsReceived += handler.RequestsReceived;
|
||||
totalRequestsHandled += handler.RequestsHandled;
|
||||
}
|
||||
|
||||
cdt.AddRow(sp.Name, sp.IsChildAgent ? "child" : "root", totalRequestsReceived, totalRequestsHandled);
|
||||
}
|
||||
|
@ -533,5 +573,19 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
sb.Append(cdt.ToString());
|
||||
*/
|
||||
}
|
||||
|
||||
private class CapTableRow
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int RequestsReceived { get; set; }
|
||||
public int RequestsHandled { get; set; }
|
||||
|
||||
public CapTableRow(string name, int requestsReceived, int requestsHandled)
|
||||
{
|
||||
Name = name;
|
||||
RequestsReceived = requestsReceived;
|
||||
RequestsHandled = requestsHandled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,23 +42,37 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
|||
namespace OpenSim.Region.CoreModules.Framework
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GridServiceThrottleModule")]
|
||||
public class GridServiceThrottleModule : ISharedRegionModule
|
||||
public class ServiceThrottleModule : ISharedRegionModule, IServiceThrottleModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private readonly List<Scene> m_scenes = new List<Scene>();
|
||||
private System.Timers.Timer m_timer = new System.Timers.Timer();
|
||||
|
||||
private OpenSim.Framework.BlockingQueue<GridRegionRequest> m_RequestQueue = new OpenSim.Framework.BlockingQueue<GridRegionRequest>();
|
||||
private Queue<Action> m_RequestQueue = new Queue<Action>();
|
||||
private Dictionary<string, List<string>> m_Pending = new Dictionary<string, List<string>>();
|
||||
private int m_Interval;
|
||||
|
||||
#region ISharedRegionModule
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
Watchdog.StartThread(
|
||||
ProcessQueue,
|
||||
"GridServiceRequestThread",
|
||||
ThreadPriority.BelowNormal,
|
||||
true,
|
||||
false);
|
||||
m_Interval = Util.GetConfigVarFromSections<int>(config, "Interval", new string[] { "ServiceThrottle" }, 5000);
|
||||
|
||||
m_timer = new System.Timers.Timer();
|
||||
m_timer.AutoReset = false;
|
||||
m_timer.Enabled = true;
|
||||
m_timer.Interval = 15000; // 15 secs at first
|
||||
m_timer.Elapsed += ProcessQueue;
|
||||
m_timer.Start();
|
||||
|
||||
//Watchdog.StartThread(
|
||||
// ProcessQueue,
|
||||
// "GridServiceRequestThread",
|
||||
// ThreadPriority.BelowNormal,
|
||||
// true,
|
||||
// false);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
|
@ -66,7 +80,9 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
lock (m_scenes)
|
||||
{
|
||||
m_scenes.Add(scene);
|
||||
scene.RegisterModuleInterface<IServiceThrottleModule>(this);
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,11 +99,6 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
}
|
||||
}
|
||||
|
||||
void OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnRegionHandleRequest += OnRegionHandleRequest;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
@ -98,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
|
||||
public string Name
|
||||
{
|
||||
get { return "GridServiceThrottleModule"; }
|
||||
get { return "ServiceThrottleModule"; }
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
|
@ -106,9 +117,31 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion ISharedRegionMOdule
|
||||
|
||||
#region Events
|
||||
|
||||
void OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnRegionHandleRequest += OnRegionHandleRequest;
|
||||
}
|
||||
|
||||
void OnMakeRootAgent(ScenePresence obj)
|
||||
{
|
||||
lock (m_timer)
|
||||
{
|
||||
if (!m_timer.Enabled)
|
||||
{
|
||||
m_timer.Interval = m_Interval;
|
||||
m_timer.Enabled = true;
|
||||
m_timer.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnRegionHandleRequest(IClientAPI client, UUID regionID)
|
||||
{
|
||||
//m_log.DebugFormat("[GRIDSERVICE THROTTLE]: RegionHandleRequest {0}", regionID);
|
||||
//m_log.DebugFormat("[SERVICE THROTTLE]: RegionHandleRequest {0}", regionID);
|
||||
ulong handle = 0;
|
||||
if (IsLocalRegionHandle(regionID, out handle))
|
||||
{
|
||||
|
@ -116,11 +149,83 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
return;
|
||||
}
|
||||
|
||||
GridRegionRequest request = new GridRegionRequest(client, regionID);
|
||||
m_RequestQueue.Enqueue(request);
|
||||
Action action = delegate
|
||||
{
|
||||
GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, regionID);
|
||||
|
||||
if (r != null && r.RegionHandle != 0)
|
||||
client.SendRegionHandle(regionID, r.RegionHandle);
|
||||
};
|
||||
|
||||
Enqueue("region", regionID.ToString(), action);
|
||||
}
|
||||
|
||||
#endregion Events
|
||||
|
||||
#region IServiceThrottleModule
|
||||
|
||||
public void Enqueue(string category, string itemid, Action continuation)
|
||||
{
|
||||
lock (m_RequestQueue)
|
||||
{
|
||||
if (m_Pending.ContainsKey(category))
|
||||
{
|
||||
if (m_Pending[category].Contains(itemid))
|
||||
// Don't enqueue, it's already pending
|
||||
return;
|
||||
}
|
||||
else
|
||||
m_Pending.Add(category, new List<string>());
|
||||
|
||||
m_Pending[category].Add(itemid);
|
||||
|
||||
m_RequestQueue.Enqueue(delegate
|
||||
{
|
||||
lock (m_RequestQueue)
|
||||
m_Pending[category].Remove(itemid);
|
||||
|
||||
continuation();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#endregion IServiceThrottleModule
|
||||
|
||||
#region Process Continuation Queue
|
||||
|
||||
private void ProcessQueue(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
//m_log.DebugFormat("[YYY]: Process queue with {0} continuations", m_RequestQueue.Count);
|
||||
|
||||
while (m_RequestQueue.Count > 0)
|
||||
{
|
||||
Action continuation = null;
|
||||
lock (m_RequestQueue)
|
||||
continuation = m_RequestQueue.Dequeue();
|
||||
|
||||
if (continuation != null)
|
||||
continuation();
|
||||
}
|
||||
|
||||
if (AreThereRootAgents())
|
||||
{
|
||||
lock (m_timer)
|
||||
{
|
||||
m_timer.Interval = 1000; // 1 sec
|
||||
m_timer.Enabled = true;
|
||||
m_timer.Start();
|
||||
}
|
||||
}
|
||||
else
|
||||
lock (m_timer)
|
||||
m_timer.Enabled = false;
|
||||
|
||||
}
|
||||
|
||||
#endregion Process Continuation Queue
|
||||
|
||||
#region Misc
|
||||
|
||||
private bool IsLocalRegionHandle(UUID regionID, out ulong regionHandle)
|
||||
{
|
||||
regionHandle = 0;
|
||||
|
@ -133,31 +238,19 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
return false;
|
||||
}
|
||||
|
||||
private void ProcessQueue()
|
||||
private bool AreThereRootAgents()
|
||||
{
|
||||
while (true)
|
||||
foreach (Scene s in m_scenes)
|
||||
{
|
||||
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);
|
||||
|
||||
foreach (ScenePresence sp in s.GetScenePresences())
|
||||
if (!sp.IsChildAgent)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion Misc
|
||||
}
|
||||
|
||||
class GridRegionRequest
|
||||
{
|
||||
public IClientAPI client;
|
||||
public UUID regionID;
|
||||
|
||||
public GridRegionRequest(IClientAPI c, UUID r)
|
||||
{
|
||||
client = c;
|
||||
regionID = r;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -56,13 +56,10 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
protected bool m_Enabled;
|
||||
protected List<Scene> m_Scenes = new List<Scene>();
|
||||
|
||||
protected IServiceThrottleModule m_ServiceThrottle;
|
||||
// The cache
|
||||
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
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
|
@ -115,6 +112,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
|
||||
public void RegionLoaded(Scene s)
|
||||
{
|
||||
if (m_Enabled && m_ServiceThrottle == null)
|
||||
m_ServiceThrottle = s.RequestModuleInterface<IServiceThrottleModule>();
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
|
@ -154,7 +153,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest);
|
||||
}
|
||||
|
||||
void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client)
|
||||
void HandleUUIDNameRequest(UUID uuid, IClientAPI client)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}",
|
||||
|
@ -162,12 +161,31 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
|
||||
if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
|
||||
{
|
||||
remote_client.SendNameReply(uuid, "Mr", "OpenSim");
|
||||
client.SendNameReply(uuid, "Mr", "OpenSim");
|
||||
}
|
||||
else
|
||||
{
|
||||
NameRequest request = new NameRequest(remote_client, uuid);
|
||||
m_RequestQueue.Enqueue(request);
|
||||
string[] names = new string[2];
|
||||
if (TryGetUserNamesFromCache(uuid, names))
|
||||
{
|
||||
client.SendNameReply(uuid, names[0], names[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Not found in cache, queue continuation
|
||||
m_ServiceThrottle.Enqueue("name", uuid.ToString(), delegate
|
||||
{
|
||||
//m_log.DebugFormat("[YYY]: Name request {0}", uuid);
|
||||
bool foundRealName = TryGetUserNames(uuid, 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], uuid, client.Name);
|
||||
|
||||
client.SendNameReply(uuid, names[0], names[1]);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -283,15 +301,27 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to get the names bound to the given uuid.
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns>True if the name was found, false if not.</returns>
|
||||
/// <param name='uuid'></param>
|
||||
/// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param>
|
||||
private bool TryGetUserNames(UUID uuid, out string[] names)
|
||||
/// <param name="uuid"></param>
|
||||
/// <param name="names">Caller please provide a properly instantiated array for names, string[2]</param>
|
||||
/// <returns></returns>
|
||||
private bool TryGetUserNames(UUID uuid, string[] names)
|
||||
{
|
||||
names = new string[2];
|
||||
if (names == null)
|
||||
names = new string[2];
|
||||
|
||||
if (TryGetUserNamesFromCache(uuid, names))
|
||||
return true;
|
||||
|
||||
if (TryGetUserNamesFromServices(uuid, names))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetUserNamesFromCache(UUID uuid, string[] names)
|
||||
{
|
||||
lock (m_UserCache)
|
||||
{
|
||||
if (m_UserCache.ContainsKey(uuid))
|
||||
|
@ -303,6 +333,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to get the names bound to the given uuid, from the services.
|
||||
/// </summary>
|
||||
/// <returns>True if the name was found, false if not.</returns>
|
||||
/// <param name='uuid'></param>
|
||||
/// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param>
|
||||
private bool TryGetUserNamesFromServices(UUID uuid, string[] names)
|
||||
{
|
||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid);
|
||||
|
||||
if (account != null)
|
||||
|
@ -387,18 +428,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
|
||||
public string GetUserName(UUID uuid)
|
||||
{
|
||||
string[] names;
|
||||
TryGetUserNames(uuid, out names);
|
||||
string[] names = new string[2];
|
||||
TryGetUserNames(uuid, names);
|
||||
|
||||
if (names.Length == 2)
|
||||
{
|
||||
string firstname = names[0];
|
||||
string lastname = names[1];
|
||||
return names[0] + " " + names[1];
|
||||
|
||||
return firstname + " " + lastname;
|
||||
}
|
||||
|
||||
return "(hippos)";
|
||||
}
|
||||
|
||||
public string GetUserHomeURL(UUID userID)
|
||||
|
@ -598,13 +632,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
protected void Init()
|
||||
{
|
||||
RegisterConsoleCmds();
|
||||
Watchdog.StartThread(
|
||||
ProcessQueue,
|
||||
"NameRequestThread",
|
||||
ThreadPriority.BelowNormal,
|
||||
true,
|
||||
false);
|
||||
|
||||
}
|
||||
|
||||
protected void RegisterConsoleCmds()
|
||||
|
@ -674,39 +701,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -219,7 +219,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
|||
|
||||
string uri = "/lslhttp/" + urlcode.ToString();
|
||||
|
||||
PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000);
|
||||
PollServiceEventArgs args
|
||||
= new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000);
|
||||
args.Type = PollServiceEventArgs.EventType.LslHttp;
|
||||
m_HttpServer.AddPollServiceHTTPHandler(uri, args);
|
||||
|
||||
|
@ -266,7 +267,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
|||
|
||||
string uri = "/lslhttps/" + urlcode.ToString();
|
||||
|
||||
PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000);
|
||||
PollServiceEventArgs args
|
||||
= new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000);
|
||||
args.Type = PollServiceEventArgs.EventType.LslHttp;
|
||||
m_HttpsServer.AddPollServiceHTTPHandler(uri, args);
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenSim.Region.Framework.Interfaces
|
||||
{
|
||||
public interface IServiceThrottleModule
|
||||
{
|
||||
/// <summary>
|
||||
/// Enqueue a continuation meant to get a resource from elsewhere.
|
||||
/// As usual with CPS, caller beware: if that continuation is a never-ending computation,
|
||||
/// the whole thread will be blocked, and no requests are processed
|
||||
/// </summary>
|
||||
/// <param name="category">Category of the resource (e.g. name, region)</param>
|
||||
/// <param name="itemid">The resource identifier</param>
|
||||
/// <param name="continuation">The continuation to be executed</param>
|
||||
void Enqueue(string category, string itemid, Action continuation);
|
||||
}
|
||||
|
||||
}
|
|
@ -116,7 +116,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
|||
return false;
|
||||
|
||||
// Delete existing npc attachments
|
||||
scene.AttachmentsModule.DeleteAttachmentsFromScene(npc, false);
|
||||
if(scene.AttachmentsModule != null)
|
||||
scene.AttachmentsModule.DeleteAttachmentsFromScene(npc, false);
|
||||
|
||||
// XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet
|
||||
// since it doesn't transfer attachments
|
||||
|
@ -125,7 +126,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
|||
npc.Appearance = npcAppearance;
|
||||
|
||||
// Rez needed npc attachments
|
||||
scene.AttachmentsModule.RezAttachments(npc);
|
||||
if (scene.AttachmentsModule != null)
|
||||
scene.AttachmentsModule.RezAttachments(npc);
|
||||
|
||||
IAvatarFactoryModule module =
|
||||
scene.RequestModuleInterface<IAvatarFactoryModule>();
|
||||
|
|
|
@ -130,6 +130,7 @@ public class BSActorAvatarMove : BSActor
|
|||
SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */);
|
||||
|
||||
m_physicsScene.BeforeStep += Mover;
|
||||
m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty;
|
||||
|
||||
m_walkingUpStairs = 0;
|
||||
}
|
||||
|
@ -139,6 +140,7 @@ public class BSActorAvatarMove : BSActor
|
|||
{
|
||||
if (m_velocityMotor != null)
|
||||
{
|
||||
m_controllingPrim.OnPreUpdateProperty -= Process_OnPreUpdateProperty;
|
||||
m_physicsScene.BeforeStep -= Mover;
|
||||
m_velocityMotor = null;
|
||||
}
|
||||
|
@ -197,7 +199,7 @@ public class BSActorAvatarMove : BSActor
|
|||
{
|
||||
if (m_controllingPrim.Flying)
|
||||
{
|
||||
// Flying and not collising and velocity nearly zero.
|
||||
// Flying and not colliding and velocity nearly zero.
|
||||
m_controllingPrim.ZeroMotion(true /* inTaintTime */);
|
||||
}
|
||||
}
|
||||
|
@ -266,6 +268,19 @@ public class BSActorAvatarMove : BSActor
|
|||
}
|
||||
}
|
||||
|
||||
// Called just as the property update is received from the physics engine.
|
||||
// Do any mode necessary for avatar movement.
|
||||
private void Process_OnPreUpdateProperty(ref EntityProperties entprop)
|
||||
{
|
||||
// Don't change position if standing on a stationary object.
|
||||
if (m_controllingPrim.IsStationary)
|
||||
{
|
||||
entprop.Position = m_controllingPrim.RawPosition;
|
||||
m_physicsScene.PE.SetTranslation(m_controllingPrim.PhysBody, entprop.Position, entprop.Rotation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Decide if the character is colliding with a low object and compute a force to pop the
|
||||
// avatar up so it can walk up and over the low objects.
|
||||
private OMV.Vector3 WalkUpStairs()
|
||||
|
|
|
@ -709,10 +709,10 @@ public sealed class BSCharacter : BSPhysObject
|
|||
// the world that things have changed.
|
||||
public override void UpdateProperties(EntityProperties entprop)
|
||||
{
|
||||
// Don't change position if standing on a stationary object.
|
||||
if (!IsStationary)
|
||||
RawPosition = entprop.Position;
|
||||
// Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator.
|
||||
TriggerPreUpdatePropertyAction(ref entprop);
|
||||
|
||||
RawPosition = entprop.Position;
|
||||
RawOrientation = entprop.Rotation;
|
||||
|
||||
// Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar
|
||||
|
@ -740,7 +740,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
// Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
|
||||
|
||||
// Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
|
||||
// base.RequestPhysicsterseUpdate();
|
||||
// PhysScene.PostUpdate(this);
|
||||
|
||||
DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
||||
LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, _rotationalVelocity);
|
||||
|
|
|
@ -103,9 +103,10 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
CollisionsLastTickStep = -1;
|
||||
|
||||
SubscribedEventsMs = 0;
|
||||
CollidingStep = 0;
|
||||
CollidingGroundStep = 0;
|
||||
CollisionAccumulation = 0;
|
||||
// Crazy values that will never be true
|
||||
CollidingStep = BSScene.NotASimulationStep;
|
||||
CollidingGroundStep = BSScene.NotASimulationStep;
|
||||
CollisionAccumulation = BSScene.NotASimulationStep;
|
||||
ColliderIsMoving = false;
|
||||
CollisionScore = 0;
|
||||
|
||||
|
@ -349,7 +350,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
if (value)
|
||||
CollidingStep = PhysScene.SimulationStep;
|
||||
else
|
||||
CollidingStep = 0;
|
||||
CollidingStep = BSScene.NotASimulationStep;
|
||||
}
|
||||
}
|
||||
public override bool CollidingGround {
|
||||
|
@ -359,7 +360,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
if (value)
|
||||
CollidingGroundStep = PhysScene.SimulationStep;
|
||||
else
|
||||
CollidingGroundStep = 0;
|
||||
CollidingGroundStep = BSScene.NotASimulationStep;
|
||||
}
|
||||
}
|
||||
public override bool CollidingObj {
|
||||
|
@ -368,7 +369,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
if (value)
|
||||
CollidingObjectStep = PhysScene.SimulationStep;
|
||||
else
|
||||
CollidingObjectStep = 0;
|
||||
CollidingObjectStep = BSScene.NotASimulationStep;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -97,6 +97,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
|
||||
internal long m_simulationStep = 0; // The current simulation step.
|
||||
public long SimulationStep { get { return m_simulationStep; } }
|
||||
// A number to use for SimulationStep that is probably not any step value
|
||||
// Used by the collision code (which remembers the step when a collision happens) to remember not any simulation step.
|
||||
public static long NotASimulationStep = -1234;
|
||||
|
||||
internal float LastTimeStep { get; private set; } // The simulation time from the last invocation of Simulate()
|
||||
|
||||
|
|
|
@ -51,7 +51,8 @@ namespace OpenSim.Region.RegionCombinerModule
|
|||
m_virtScene.UnSubscribeToClientPrimEvents(client);
|
||||
m_virtScene.UnSubscribeToClientPrimRezEvents(client);
|
||||
m_virtScene.UnSubscribeToClientInventoryEvents(client);
|
||||
((AttachmentsModule)m_virtScene.AttachmentsModule).UnsubscribeFromClientEvents(client);
|
||||
if(m_virtScene.AttachmentsModule != null)
|
||||
((AttachmentsModule)m_virtScene.AttachmentsModule).UnsubscribeFromClientEvents(client);
|
||||
//m_virtScene.UnSubscribeToClientTeleportEvents(client);
|
||||
m_virtScene.UnSubscribeToClientScriptEvents(client);
|
||||
|
||||
|
@ -66,7 +67,8 @@ namespace OpenSim.Region.RegionCombinerModule
|
|||
client.OnRezObject += LocalRezObject;
|
||||
|
||||
m_rootScene.SubscribeToClientInventoryEvents(client);
|
||||
((AttachmentsModule)m_rootScene.AttachmentsModule).SubscribeToClientEvents(client);
|
||||
if (m_rootScene.AttachmentsModule != null)
|
||||
((AttachmentsModule)m_rootScene.AttachmentsModule).SubscribeToClientEvents(client);
|
||||
//m_rootScene.SubscribeToClientTeleportEvents(client);
|
||||
m_rootScene.SubscribeToClientScriptEvents(client);
|
||||
|
||||
|
|
|
@ -1723,5 +1723,9 @@ MaxStringSpace = 0
|
|||
;; {MaxDistance} {} {Cut-off distance at which sounds will not be sent to users} {100.0}
|
||||
MaxDistance = 100.0
|
||||
|
||||
[ServiceThrottle]
|
||||
;; Default time interval (in ms) for the throttle service thread to wake up
|
||||
Interval = 5000
|
||||
|
||||
[Modules]
|
||||
Include-modules = "addon-modules/*/config/*.ini"
|
||||
|
|
Loading…
Reference in New Issue