Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e1404adac6 | ||
|
|
1d27c9f4d1 | ||
|
|
428b51ffda | ||
|
|
fe2487f8d3 | ||
|
|
b69ddbb66b | ||
|
|
1cb5e31716 | ||
|
|
7f60800ca6 | ||
|
|
ceaa7e9a54 | ||
|
|
cab3e9978b | ||
|
|
049022717c | ||
|
|
40c54a718f | ||
|
|
315097b8b9 | ||
|
|
5e5aa5fba7 | ||
|
|
9801d0d4c8 | ||
|
|
d95a470442 | ||
|
|
74a341fd22 | ||
|
|
95b248e9e5 | ||
|
|
340abd1110 | ||
|
|
0910c5c101 | ||
|
|
f0126a1575 | ||
|
|
0d5b2dd5ce | ||
|
|
64cda1b26e | ||
|
|
778babaab2 | ||
|
|
d30e5f7ded | ||
|
|
f05654d8d6 | ||
|
|
52bb732692 | ||
|
|
dc88ffc5b4 | ||
|
|
07420a3b4d | ||
|
|
42e5856464 | ||
|
|
3b8e7ff013 | ||
|
|
5c74f3ec9c | ||
|
|
d1e9beead8 | ||
|
|
35aa6c86fe | ||
|
|
5cdc21aac7 | ||
|
|
cbb47f8489 | ||
|
|
b2b29b7ec0 | ||
|
|
27377194cd | ||
|
|
8c6761c152 | ||
|
|
553d9cc5d2 | ||
|
|
c685cc1799 | ||
|
|
1ba5a05cf7 | ||
|
|
0af3b5ed9a | ||
|
|
a94a43d249 | ||
|
|
7c544c0d4e | ||
|
|
b402220dbb |
@@ -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;
|
||||
|
||||
|
||||
@@ -634,17 +634,17 @@ namespace OpenSim.Framework
|
||||
// The code to unpack textures, visuals, wearables and attachments
|
||||
// should be removed; packed appearance contains the full appearance
|
||||
// This is retained for backward compatibility only
|
||||
if (args["texture_entry"] != null)
|
||||
if (args.ContainsKey("texture_entry") && args["texture_entry"] != null)
|
||||
{
|
||||
byte[] rawtextures = args["texture_entry"].AsBinary();
|
||||
Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures,0,rawtextures.Length);
|
||||
Appearance.SetTextureEntries(textures);
|
||||
}
|
||||
|
||||
if (args["visual_params"] != null)
|
||||
if (args.ContainsKey("visual_params") && args["visual_params"] != null)
|
||||
Appearance.SetVisualParams(args["visual_params"].AsBinary());
|
||||
|
||||
if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
|
||||
if (args.ContainsKey("wearables") && (args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
|
||||
{
|
||||
OSDArray wears = (OSDArray)(args["wearables"]);
|
||||
for (int i = 0; i < wears.Count / 2; i++)
|
||||
@@ -654,7 +654,7 @@ namespace OpenSim.Framework
|
||||
}
|
||||
}
|
||||
|
||||
if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
|
||||
if (args.ContainsKey("attachments") && (args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
|
||||
{
|
||||
OSDArray attachs = (OSDArray)(args["attachments"]);
|
||||
foreach (OSD o in attachs)
|
||||
|
||||
@@ -825,6 +825,8 @@ namespace OpenSim.Framework
|
||||
/// </remarks>
|
||||
event UpdateAgent OnAgentUpdate;
|
||||
|
||||
event UpdateAgent OnAgentCameraUpdate;
|
||||
|
||||
event AgentRequestSit OnAgentRequestSit;
|
||||
event AgentSit OnAgentSit;
|
||||
event AvatarPickerRequest OnAvatarPickerRequest;
|
||||
@@ -1474,7 +1476,7 @@ namespace OpenSim.Framework
|
||||
void SendChangeUserRights(UUID agentID, UUID friendID, int rights);
|
||||
void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId);
|
||||
|
||||
void StopFlying(ISceneEntity presence);
|
||||
void SendAgentTerseUpdate(ISceneEntity presence);
|
||||
|
||||
void SendPlacesReply(UUID queryID, UUID transactionID, PlacesReplyData[] data);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
private readonly BaseHttpServer m_server;
|
||||
|
||||
private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>();
|
||||
private static Queue<PollServiceHttpRequest> m_longPollRequests = new Queue<PollServiceHttpRequest>();
|
||||
private static List<PollServiceHttpRequest> m_longPollRequests = new List<PollServiceHttpRequest>();
|
||||
|
||||
private uint m_WorkerThreadCount = 0;
|
||||
private Thread[] m_workerThreads;
|
||||
@@ -96,7 +96,17 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
private void ReQueueEvent(PollServiceHttpRequest req)
|
||||
{
|
||||
if (m_running)
|
||||
m_requests.Enqueue(req);
|
||||
{
|
||||
// delay the enqueueing for 100ms. There's no need to have the event
|
||||
// actively on the queue
|
||||
Timer t = new Timer(self => {
|
||||
((Timer)self).Dispose();
|
||||
m_requests.Enqueue(req);
|
||||
});
|
||||
|
||||
t.Change(100, Timeout.Infinite);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void Enqueue(PollServiceHttpRequest req)
|
||||
@@ -106,7 +116,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll)
|
||||
{
|
||||
lock (m_longPollRequests)
|
||||
m_longPollRequests.Enqueue(req);
|
||||
m_longPollRequests.Add(req);
|
||||
}
|
||||
else
|
||||
m_requests.Enqueue(req);
|
||||
@@ -118,7 +128,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
// The only purpose of this thread is to check the EQs for events.
|
||||
// If there are events, that thread will be placed in the "ready-to-serve" queue, m_requests.
|
||||
// If there are no events, that thread will be back to its "waiting" queue, m_longPollRequests.
|
||||
// All other types of tasks (Inventory handlers) don't have the long-poll nature,
|
||||
// All other types of tasks (Inventory handlers, http-in, etc) don't have the long-poll nature,
|
||||
// so if they aren't ready to be served by a worker thread (no events), they are placed
|
||||
// directly back in the "ready-to-serve" queue by the worker thread.
|
||||
while (m_running)
|
||||
@@ -129,18 +139,20 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
List<PollServiceHttpRequest> not_ready = new List<PollServiceHttpRequest>();
|
||||
lock (m_longPollRequests)
|
||||
{
|
||||
while (m_longPollRequests.Count > 0 && m_running)
|
||||
if (m_longPollRequests.Count > 0 && m_running)
|
||||
{
|
||||
PollServiceHttpRequest req = m_longPollRequests.Dequeue();
|
||||
if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id) || // there are events in this EQ
|
||||
List<PollServiceHttpRequest> ready = m_longPollRequests.FindAll(req =>
|
||||
(req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id) || // there are events in this EQ
|
||||
(Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) // no events, but timeout
|
||||
m_requests.Enqueue(req);
|
||||
else
|
||||
not_ready.Add(req);
|
||||
}
|
||||
);
|
||||
|
||||
foreach (PollServiceHttpRequest req in not_ready)
|
||||
m_longPollRequests.Enqueue(req);
|
||||
ready.ForEach(req =>
|
||||
{
|
||||
m_requests.Enqueue(req);
|
||||
m_longPollRequests.Remove(req);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -159,8 +171,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
lock (m_longPollRequests)
|
||||
{
|
||||
while (m_longPollRequests.Count > 0 && m_running)
|
||||
m_requests.Enqueue(m_longPollRequests.Dequeue());
|
||||
if (m_longPollRequests.Count > 0 && m_running)
|
||||
m_longPollRequests.ForEach(req => m_requests.Enqueue(req));
|
||||
}
|
||||
|
||||
while (m_requests.Count() > 0)
|
||||
@@ -176,6 +188,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
}
|
||||
}
|
||||
|
||||
m_longPollRequests.Clear();
|
||||
m_requests.Clear();
|
||||
}
|
||||
|
||||
@@ -185,33 +198,35 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
while (m_running)
|
||||
{
|
||||
PollServiceHttpRequest req = m_requests.Dequeue(5000);
|
||||
//m_log.WarnFormat("[YYY]: Dequeued {0}", (req == null ? "null" : req.PollServiceArgs.Type.ToString()));
|
||||
|
||||
Watchdog.UpdateThread();
|
||||
|
||||
PollServiceHttpRequest req = null;
|
||||
lock (m_requests)
|
||||
if (req != null)
|
||||
{
|
||||
if (m_requests.Count() > 0)
|
||||
req = m_requests.Dequeue();
|
||||
}
|
||||
if (req == null)
|
||||
Thread.Sleep(100);
|
||||
else
|
||||
{
|
||||
//PollServiceHttpRequest req = m_requests.Dequeue(5000);
|
||||
//m_log.WarnFormat("[YYY]: Dequeued {0}", (req == null ? "null" : req.PollServiceArgs.Type.ToString()));
|
||||
|
||||
if (req != null)
|
||||
try
|
||||
{
|
||||
try
|
||||
if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
|
||||
{
|
||||
if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
|
||||
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
|
||||
|
||||
if (responsedata == null)
|
||||
continue;
|
||||
|
||||
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) // This is the event queue
|
||||
{
|
||||
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
|
||||
|
||||
if (responsedata == null)
|
||||
continue;
|
||||
|
||||
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) // This is the event queue
|
||||
try
|
||||
{
|
||||
req.DoHTTPGruntWork(m_server, responsedata);
|
||||
}
|
||||
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
|
||||
{
|
||||
// Ignore it, no need to reply
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_threadPool.QueueWorkItem(x =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -221,41 +236,27 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
// Ignore it, no need to reply
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_threadPool.QueueWorkItem(x =>
|
||||
{
|
||||
try
|
||||
{
|
||||
req.DoHTTPGruntWork(m_server, responsedata);
|
||||
}
|
||||
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
|
||||
{
|
||||
// Ignore it, no need to reply
|
||||
}
|
||||
|
||||
return null;
|
||||
}, null);
|
||||
}
|
||||
return null;
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
|
||||
{
|
||||
req.DoHTTPGruntWork(
|
||||
m_server, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
|
||||
{
|
||||
req.DoHTTPGruntWork(
|
||||
m_server, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
|
||||
}
|
||||
else
|
||||
{
|
||||
ReQueueEvent(req);
|
||||
}
|
||||
ReQueueEvent(req);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1779,10 +1779,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");
|
||||
|
||||
@@ -1791,6 +1793,7 @@ namespace OpenSim.Framework
|
||||
startInfo.IdleTimeout = 2000;
|
||||
startInfo.MaxWorkerThreads = maxThreads;
|
||||
startInfo.MinWorkerThreads = 2;
|
||||
startInfo.MinWorkerThreads = minThreads;
|
||||
|
||||
m_ThreadPool = new SmartThreadPool(startInfo);
|
||||
}
|
||||
@@ -1865,7 +1868,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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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>();
|
||||
@@ -363,8 +370,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
}
|
||||
|
||||
caps.RegisterPollHandler(
|
||||
"EventQueueGet",
|
||||
new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, 40000));
|
||||
"EventQueueGet",
|
||||
new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
|
||||
|
||||
Random rnd = new Random(Environment.TickCount);
|
||||
lock (m_ids)
|
||||
|
||||
@@ -96,6 +96,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
|
||||
public event UpdateAgent OnPreAgentUpdate;
|
||||
public event UpdateAgent OnAgentUpdate;
|
||||
public event UpdateAgent OnAgentCameraUpdate;
|
||||
public event AgentRequestSit OnAgentRequestSit;
|
||||
public event AgentSit OnAgentSit;
|
||||
public event AvatarPickerRequest OnAvatarPickerRequest;
|
||||
@@ -357,7 +358,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// This does mean that agent updates must be processed synchronously, at least for each client, and called methods
|
||||
/// cannot retain a reference to it outside of that method.
|
||||
/// </remarks>
|
||||
private AgentUpdateArgs m_lastAgentUpdateArgs;
|
||||
private AgentUpdateArgs m_thisAgentUpdateArgs = new AgentUpdateArgs();
|
||||
private float qdelta1;
|
||||
private float qdelta2;
|
||||
private float vdelta1;
|
||||
private float vdelta2;
|
||||
private float vdelta3;
|
||||
private float vdelta4;
|
||||
|
||||
protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
|
||||
protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
|
||||
@@ -485,6 +492,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
m_udpServer = udpServer;
|
||||
m_udpClient = udpClient;
|
||||
m_udpClient.OnQueueEmpty += HandleQueueEmpty;
|
||||
m_udpClient.HasUpdates += HandleHasUpdates;
|
||||
m_udpClient.OnPacketStats += PopulateStats;
|
||||
|
||||
m_prioritizer = new Prioritizer(m_scene);
|
||||
@@ -3776,6 +3784,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>>();
|
||||
@@ -3788,6 +3807,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)
|
||||
{
|
||||
@@ -4113,8 +4141,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories)
|
||||
{
|
||||
// if (!m_udpServer.IsRunningOutbound)
|
||||
// return;
|
||||
|
||||
if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
|
||||
{
|
||||
// if (!m_udpServer.IsRunningOutbound)
|
||||
// return;
|
||||
|
||||
if (m_maxUpdates == 0 || m_LastQueueFill == 0)
|
||||
{
|
||||
m_maxUpdates = m_udpServer.PrimUpdatesPerCallback;
|
||||
@@ -4140,6 +4174,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit);
|
||||
}
|
||||
|
||||
internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories)
|
||||
{
|
||||
bool hasUpdates = false;
|
||||
|
||||
if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
|
||||
{
|
||||
if (m_entityUpdates.Count > 0)
|
||||
hasUpdates = true;
|
||||
else if (m_entityProps.Count > 0)
|
||||
hasUpdates = true;
|
||||
}
|
||||
|
||||
if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
|
||||
{
|
||||
if (ImageManager.HasUpdates())
|
||||
hasUpdates = true;
|
||||
}
|
||||
|
||||
return hasUpdates;
|
||||
}
|
||||
|
||||
public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
|
||||
{
|
||||
AssetUploadCompletePacket newPack = new AssetUploadCompletePacket();
|
||||
@@ -4961,7 +5016,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
ScenePresence presence = (ScenePresence)entity;
|
||||
|
||||
attachPoint = 0;
|
||||
attachPoint = presence.State;
|
||||
collisionPlane = presence.CollisionPlane;
|
||||
position = presence.OffsetPosition;
|
||||
velocity = presence.Velocity;
|
||||
@@ -4985,7 +5040,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
SceneObjectPart part = (SceneObjectPart)entity;
|
||||
|
||||
attachPoint = part.ParentGroup.AttachmentPoint;
|
||||
|
||||
attachPoint = ((attachPoint % 16) * 16 + (attachPoint / 16));
|
||||
// m_log.DebugFormat(
|
||||
// "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}",
|
||||
// attachPoint, part.Name, part.LocalId, Name);
|
||||
@@ -5013,7 +5068,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
pos += 4;
|
||||
|
||||
// Avatar/CollisionPlane
|
||||
data[pos++] = (byte)((attachPoint % 16) * 16 + (attachPoint / 16)); ;
|
||||
data[pos++] = (byte) attachPoint;
|
||||
if (avatar)
|
||||
{
|
||||
data[pos++] = 1;
|
||||
@@ -5517,83 +5572,137 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
#region Packet Handlers
|
||||
|
||||
public int TotalAgentUpdates { get; set; }
|
||||
|
||||
#region Scene/Avatar
|
||||
|
||||
private bool HandleAgentUpdate(IClientAPI sener, Packet packet)
|
||||
private const float QDELTA = 0.000001f;
|
||||
private const float VDELTA = 0.01f;
|
||||
|
||||
/// <summary>
|
||||
/// This checks the update significance against the last update made.
|
||||
/// </summary>
|
||||
/// <remarks>Can only be called by one thread at a time</remarks>
|
||||
/// <returns></returns>
|
||||
/// <param name='x'></param>
|
||||
public bool CheckAgentUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
|
||||
{
|
||||
if (OnAgentUpdate != null)
|
||||
// Compute these only once, when this function is called from down below
|
||||
qdelta1 = 1 - (float)Math.Pow(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation), 2);
|
||||
//qdelta2 = 1 - (float)Math.Pow(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation), 2);
|
||||
vdelta1 = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis);
|
||||
vdelta2 = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter);
|
||||
vdelta3 = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis);
|
||||
vdelta4 = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis);
|
||||
|
||||
return CheckAgentMovementUpdateSignificance(x) || CheckAgentCameraUpdateSignificance(x);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This checks the movement/state update significance against the last update made.
|
||||
/// </summary>
|
||||
/// <remarks>Can only be called by one thread at a time</remarks>
|
||||
/// <returns></returns>
|
||||
/// <param name='x'></param>
|
||||
private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
|
||||
{
|
||||
if (
|
||||
(qdelta1 > QDELTA) ||
|
||||
// Ignoring head rotation altogether, because it's not being used for anything interesting up the stack
|
||||
//(qdelta2 > QDELTA * 10) ||
|
||||
(x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) ||
|
||||
(x.Far != m_thisAgentUpdateArgs.Far) ||
|
||||
(x.Flags != m_thisAgentUpdateArgs.Flags) ||
|
||||
(x.State != m_thisAgentUpdateArgs.State)
|
||||
)
|
||||
{
|
||||
AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
|
||||
|
||||
#region Packet Session and User Check
|
||||
if (agentUpdate.AgentData.SessionID != SessionId || agentUpdate.AgentData.AgentID != AgentId)
|
||||
{
|
||||
PacketPool.Instance.ReturnPacket(packet);
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
bool update = false;
|
||||
AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData;
|
||||
|
||||
if (m_lastAgentUpdateArgs != null)
|
||||
{
|
||||
// These should be ordered from most-likely to
|
||||
// least likely to change. I've made an initial
|
||||
// guess at that.
|
||||
update =
|
||||
(
|
||||
(x.BodyRotation != m_lastAgentUpdateArgs.BodyRotation) ||
|
||||
(x.CameraAtAxis != m_lastAgentUpdateArgs.CameraAtAxis) ||
|
||||
(x.CameraCenter != m_lastAgentUpdateArgs.CameraCenter) ||
|
||||
(x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
|
||||
(x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
|
||||
(x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
|
||||
(x.Far != m_lastAgentUpdateArgs.Far) ||
|
||||
(x.Flags != m_lastAgentUpdateArgs.Flags) ||
|
||||
(x.State != m_lastAgentUpdateArgs.State) ||
|
||||
(x.HeadRotation != m_lastAgentUpdateArgs.HeadRotation) ||
|
||||
(x.SessionID != m_lastAgentUpdateArgs.SessionID) ||
|
||||
(x.AgentID != m_lastAgentUpdateArgs.AgentID)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_lastAgentUpdateArgs = new AgentUpdateArgs();
|
||||
update = true;
|
||||
}
|
||||
|
||||
if (update)
|
||||
{
|
||||
// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name);
|
||||
|
||||
m_lastAgentUpdateArgs.AgentID = x.AgentID;
|
||||
m_lastAgentUpdateArgs.BodyRotation = x.BodyRotation;
|
||||
m_lastAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis;
|
||||
m_lastAgentUpdateArgs.CameraCenter = x.CameraCenter;
|
||||
m_lastAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis;
|
||||
m_lastAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis;
|
||||
m_lastAgentUpdateArgs.ControlFlags = x.ControlFlags;
|
||||
m_lastAgentUpdateArgs.Far = x.Far;
|
||||
m_lastAgentUpdateArgs.Flags = x.Flags;
|
||||
m_lastAgentUpdateArgs.HeadRotation = x.HeadRotation;
|
||||
m_lastAgentUpdateArgs.SessionID = x.SessionID;
|
||||
m_lastAgentUpdateArgs.State = x.State;
|
||||
|
||||
UpdateAgent handlerAgentUpdate = OnAgentUpdate;
|
||||
UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate;
|
||||
|
||||
if (handlerPreAgentUpdate != null)
|
||||
OnPreAgentUpdate(this, m_lastAgentUpdateArgs);
|
||||
|
||||
if (handlerAgentUpdate != null)
|
||||
OnAgentUpdate(this, m_lastAgentUpdateArgs);
|
||||
|
||||
handlerAgentUpdate = null;
|
||||
handlerPreAgentUpdate = null;
|
||||
}
|
||||
//m_log.DebugFormat("[LLCLIENTVIEW]: Bod {0} {1}",
|
||||
// qdelta1, qdelta2);
|
||||
//m_log.DebugFormat("[LLCLIENTVIEW]: St {0} {1} {2} {3} (Thread {4})",
|
||||
// x.ControlFlags, x.Flags, x.Far, x.State, Thread.CurrentThread.Name);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This checks the camera update significance against the last update made.
|
||||
/// </summary>
|
||||
/// <remarks>Can only be called by one thread at a time</remarks>
|
||||
/// <returns></returns>
|
||||
/// <param name='x'></param>
|
||||
private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
|
||||
{
|
||||
if (
|
||||
/* These 4 are the worst offenders!
|
||||
* With Singularity, there is a bug where sometimes the spam on these doesn't stop */
|
||||
(vdelta1 > VDELTA) ||
|
||||
(vdelta2 > VDELTA) ||
|
||||
(vdelta3 > VDELTA) ||
|
||||
(vdelta4 > VDELTA)
|
||||
)
|
||||
{
|
||||
//m_log.DebugFormat("[LLCLIENTVIEW]: Cam1 {0} {1}",
|
||||
// x.CameraAtAxis, x.CameraCenter);
|
||||
//m_log.DebugFormat("[LLCLIENTVIEW]: Cam2 {0} {1}",
|
||||
// x.CameraLeftAxis, x.CameraUpAxis);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool HandleAgentUpdate(IClientAPI sener, Packet packet)
|
||||
{
|
||||
// We got here, which means that something in agent update was significant
|
||||
|
||||
AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
|
||||
AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData;
|
||||
|
||||
if (x.AgentID != AgentId || x.SessionID != SessionId)
|
||||
return false;
|
||||
|
||||
// Before we update the current m_thisAgentUpdateArgs, let's check this again
|
||||
// to see what exactly changed
|
||||
bool movement = CheckAgentMovementUpdateSignificance(x);
|
||||
bool camera = CheckAgentCameraUpdateSignificance(x);
|
||||
|
||||
m_thisAgentUpdateArgs.AgentID = x.AgentID;
|
||||
m_thisAgentUpdateArgs.BodyRotation = x.BodyRotation;
|
||||
m_thisAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis;
|
||||
m_thisAgentUpdateArgs.CameraCenter = x.CameraCenter;
|
||||
m_thisAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis;
|
||||
m_thisAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis;
|
||||
m_thisAgentUpdateArgs.ControlFlags = x.ControlFlags;
|
||||
m_thisAgentUpdateArgs.Far = x.Far;
|
||||
m_thisAgentUpdateArgs.Flags = x.Flags;
|
||||
m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation;
|
||||
m_thisAgentUpdateArgs.SessionID = x.SessionID;
|
||||
m_thisAgentUpdateArgs.State = x.State;
|
||||
|
||||
UpdateAgent handlerAgentUpdate = OnAgentUpdate;
|
||||
UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate;
|
||||
UpdateAgent handlerAgentCameraUpdate = OnAgentCameraUpdate;
|
||||
|
||||
// Was there a significant movement/state change?
|
||||
if (movement)
|
||||
{
|
||||
if (handlerPreAgentUpdate != null)
|
||||
OnPreAgentUpdate(this, m_thisAgentUpdateArgs);
|
||||
|
||||
if (handlerAgentUpdate != null)
|
||||
OnAgentUpdate(this, m_thisAgentUpdateArgs);
|
||||
}
|
||||
// Was there a significant camera(s) change?
|
||||
if (camera)
|
||||
if (handlerAgentCameraUpdate != null)
|
||||
handlerAgentCameraUpdate(this, m_thisAgentUpdateArgs);
|
||||
|
||||
handlerAgentUpdate = null;
|
||||
handlerPreAgentUpdate = null;
|
||||
handlerAgentCameraUpdate = null;
|
||||
|
||||
PacketPool.Instance.ReturnPacket(packet);
|
||||
|
||||
return true;
|
||||
@@ -12441,7 +12550,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
OutPacket(dialog, ThrottleOutPacketType.Task);
|
||||
}
|
||||
|
||||
public void StopFlying(ISceneEntity p)
|
||||
public void SendAgentTerseUpdate(ISceneEntity p)
|
||||
{
|
||||
if (p is ScenePresence)
|
||||
{
|
||||
@@ -12455,25 +12564,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
Vector3 pos = presence.AbsolutePosition;
|
||||
|
||||
if (presence.Appearance.AvatarHeight != 127.0f)
|
||||
pos += new Vector3(0f, 0f, (presence.Appearance.AvatarHeight/6f));
|
||||
else
|
||||
pos += new Vector3(0f, 0f, (1.56f/6f));
|
||||
|
||||
presence.AbsolutePosition = pos;
|
||||
|
||||
// attach a suitable collision plane regardless of the actual situation to force the LLClient to land.
|
||||
// Collision plane below the avatar's position a 6th of the avatar's height is suitable.
|
||||
// Mind you, that this method doesn't get called if the avatar's velocity magnitude is greater then a
|
||||
// certain amount.. because the LLClient wouldn't land in that situation anyway.
|
||||
|
||||
// why are we still testing for this really old height value default???
|
||||
if (presence.Appearance.AvatarHeight != 127.0f)
|
||||
presence.CollisionPlane = new Vector4(0, 0, 0, pos.Z - presence.Appearance.AvatarHeight/6f);
|
||||
else
|
||||
presence.CollisionPlane = new Vector4(0, 0, 0, pos.Z - (1.56f/6f));
|
||||
|
||||
|
||||
ImprovedTerseObjectUpdatePacket.ObjectDataBlock block =
|
||||
CreateImprovedTerseBlock(p, false);
|
||||
|
||||
|
||||
@@ -206,6 +206,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasUpdates()
|
||||
{
|
||||
J2KImage image = GetHighestPriorityImage();
|
||||
|
||||
return image != null && image.IsDecoded;
|
||||
}
|
||||
|
||||
public bool ProcessImageQueue(int packetsToSend)
|
||||
{
|
||||
int packetsSent = 0;
|
||||
|
||||
@@ -31,6 +31,7 @@ using System.Net;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Packets;
|
||||
|
||||
@@ -81,6 +82,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// hooked to put more data on the empty queue</summary>
|
||||
public event QueueEmpty OnQueueEmpty;
|
||||
|
||||
public event Func<ThrottleOutPacketTypeFlags, bool> HasUpdates;
|
||||
|
||||
/// <summary>AgentID for this client</summary>
|
||||
public readonly UUID AgentID;
|
||||
/// <summary>The remote address of the connected client</summary>
|
||||
@@ -613,15 +616,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// <param name="categories">Throttle categories to fire the callback for</param>
|
||||
private void BeginFireQueueEmpty(ThrottleOutPacketTypeFlags categories)
|
||||
{
|
||||
if (m_nextOnQueueEmpty != 0 && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty)
|
||||
// if (m_nextOnQueueEmpty != 0 && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty)
|
||||
if (!m_isQueueEmptyRunning && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty)
|
||||
{
|
||||
m_isQueueEmptyRunning = true;
|
||||
|
||||
int start = Environment.TickCount & Int32.MaxValue;
|
||||
const int MIN_CALLBACK_MS = 30;
|
||||
|
||||
m_nextOnQueueEmpty = start + MIN_CALLBACK_MS;
|
||||
if (m_nextOnQueueEmpty == 0)
|
||||
m_nextOnQueueEmpty = 1;
|
||||
|
||||
// Use a value of 0 to signal that FireQueueEmpty is running
|
||||
m_nextOnQueueEmpty = 0;
|
||||
// Asynchronously run the callback
|
||||
Util.FireAndForget(FireQueueEmpty, categories);
|
||||
// m_nextOnQueueEmpty = 0;
|
||||
|
||||
m_categories = categories;
|
||||
|
||||
if (HasUpdates(m_categories))
|
||||
{
|
||||
// Asynchronously run the callback
|
||||
Util.FireAndForget(FireQueueEmpty, categories);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_isQueueEmptyRunning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool m_isQueueEmptyRunning;
|
||||
private ThrottleOutPacketTypeFlags m_categories = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Fires the OnQueueEmpty callback and sets the minimum time that it
|
||||
/// can be called again
|
||||
@@ -631,22 +657,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// signature</param>
|
||||
private void FireQueueEmpty(object o)
|
||||
{
|
||||
const int MIN_CALLBACK_MS = 30;
|
||||
// int start = Environment.TickCount & Int32.MaxValue;
|
||||
// const int MIN_CALLBACK_MS = 30;
|
||||
|
||||
ThrottleOutPacketTypeFlags categories = (ThrottleOutPacketTypeFlags)o;
|
||||
QueueEmpty callback = OnQueueEmpty;
|
||||
|
||||
int start = Environment.TickCount & Int32.MaxValue;
|
||||
// if (m_udpServer.IsRunningOutbound)
|
||||
// {
|
||||
ThrottleOutPacketTypeFlags categories = (ThrottleOutPacketTypeFlags)o;
|
||||
QueueEmpty callback = OnQueueEmpty;
|
||||
|
||||
if (callback != null)
|
||||
{
|
||||
try { callback(categories); }
|
||||
catch (Exception e) { m_log.Error("[LLUDPCLIENT]: OnQueueEmpty(" + categories + ") threw an exception: " + e.Message, e); }
|
||||
}
|
||||
if (callback != null)
|
||||
{
|
||||
// if (m_udpServer.IsRunningOutbound)
|
||||
// {
|
||||
try { callback(categories); }
|
||||
catch (Exception e) { m_log.Error("[LLUDPCLIENT]: OnQueueEmpty(" + categories + ") threw an exception: " + e.Message, e); }
|
||||
// }
|
||||
}
|
||||
// }
|
||||
|
||||
m_nextOnQueueEmpty = start + MIN_CALLBACK_MS;
|
||||
if (m_nextOnQueueEmpty == 0)
|
||||
m_nextOnQueueEmpty = 1;
|
||||
// m_nextOnQueueEmpty = start + MIN_CALLBACK_MS;
|
||||
// if (m_nextOnQueueEmpty == 0)
|
||||
// m_nextOnQueueEmpty = 1;
|
||||
|
||||
// }
|
||||
|
||||
m_isQueueEmptyRunning = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -572,6 +572,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
"debug lludp status",
|
||||
"Return status of LLUDP packet processing.",
|
||||
HandleStatusCommand);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp toggle agentupdate",
|
||||
"debug lludp toggle agentupdate",
|
||||
"Toggle whether agentupdate packets are processed or simply discarded.",
|
||||
HandleAgentUpdateCommand);
|
||||
}
|
||||
|
||||
private void HandlePacketCommand(string module, string[] args)
|
||||
@@ -706,6 +714,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
}
|
||||
|
||||
bool m_discardAgentUpdates;
|
||||
|
||||
private void HandleAgentUpdateCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
return;
|
||||
|
||||
m_discardAgentUpdates = !m_discardAgentUpdates;
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Discard AgentUpdates now {0} for {1}", m_discardAgentUpdates, m_scene.Name);
|
||||
}
|
||||
|
||||
private void HandleStatusCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
@@ -806,8 +827,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>
|
||||
@@ -1282,6 +1307,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length);
|
||||
#endregion BinaryStats
|
||||
|
||||
if (packet.Type == PacketType.AgentUpdate)
|
||||
{
|
||||
if (m_discardAgentUpdates)
|
||||
return;
|
||||
|
||||
((LLClientView)client).TotalAgentUpdates++;
|
||||
|
||||
AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
|
||||
|
||||
if (agentUpdate.AgentData.SessionID != client.SessionId
|
||||
|| agentUpdate.AgentData.AgentID != client.AgentId
|
||||
|| !((LLClientView)client).CheckAgentUpdateSignificance(agentUpdate.AgentData))
|
||||
{
|
||||
PacketPool.Instance.ReturnPacket(packet);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#region Ping Check Handling
|
||||
|
||||
if (packet.Type == PacketType.StartPingCheck)
|
||||
@@ -1718,8 +1761,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();
|
||||
}
|
||||
|
||||
@@ -111,6 +111,8 @@ namespace OpenMetaverse
|
||||
|
||||
if (!IsRunningInbound)
|
||||
{
|
||||
m_log.DebugFormat("[UDPBASE]: Starting inbound UDP loop");
|
||||
|
||||
const int SIO_UDP_CONNRESET = -1744830452;
|
||||
|
||||
IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
|
||||
@@ -155,6 +157,8 @@ namespace OpenMetaverse
|
||||
/// </summary>
|
||||
public void StartOutbound()
|
||||
{
|
||||
m_log.DebugFormat("[UDPBASE]: Starting outbound UDP loop");
|
||||
|
||||
IsRunningOutbound = true;
|
||||
}
|
||||
|
||||
@@ -162,10 +166,8 @@ namespace OpenMetaverse
|
||||
{
|
||||
if (IsRunningInbound)
|
||||
{
|
||||
// wait indefinitely for a writer lock. Once this is called, the .NET runtime
|
||||
// will deny any more reader locks, in effect blocking all other send/receive
|
||||
// threads. Once we have the lock, we set IsRunningInbound = false to inform the other
|
||||
// threads that the socket is closed.
|
||||
m_log.DebugFormat("[UDPBASE]: Stopping inbound UDP loop");
|
||||
|
||||
IsRunningInbound = false;
|
||||
m_udpSocket.Close();
|
||||
}
|
||||
@@ -173,6 +175,8 @@ namespace OpenMetaverse
|
||||
|
||||
public void StopOutbound()
|
||||
{
|
||||
m_log.DebugFormat("[UDPBASE]: Stopping outbound UDP loop");
|
||||
|
||||
IsRunningOutbound = false;
|
||||
}
|
||||
|
||||
@@ -308,8 +312,8 @@ namespace OpenMetaverse
|
||||
|
||||
public void AsyncBeginSend(UDPPacketBuffer buf)
|
||||
{
|
||||
if (IsRunningOutbound)
|
||||
{
|
||||
// if (IsRunningOutbound)
|
||||
// {
|
||||
try
|
||||
{
|
||||
m_udpSocket.BeginSendTo(
|
||||
@@ -323,7 +327,7 @@ namespace OpenMetaverse
|
||||
}
|
||||
catch (SocketException) { }
|
||||
catch (ObjectDisposedException) { }
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
void AsyncEndSend(IAsyncResult result)
|
||||
|
||||
@@ -185,8 +185,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
|
||||
public void UploadInventoryItem(UUID avatarID, AssetType type, UUID assetID, string name, int userlevel)
|
||||
{
|
||||
if (type == AssetType.Link)
|
||||
return;
|
||||
|
||||
string userAssetServer = string.Empty;
|
||||
if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
|
||||
{
|
||||
@@ -221,7 +224,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
{
|
||||
UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data);
|
||||
|
||||
UploadInventoryItem(remoteClient.AgentId, newAssetID, "", 0);
|
||||
UploadInventoryItem(remoteClient.AgentId, AssetType.Unknown, newAssetID, "", 0);
|
||||
|
||||
return newAssetID;
|
||||
}
|
||||
@@ -232,7 +235,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
protected override void ExportAsset(UUID agentID, UUID assetID)
|
||||
{
|
||||
if (!assetID.Equals(UUID.Zero))
|
||||
UploadInventoryItem(agentID, assetID, "", 0);
|
||||
UploadInventoryItem(agentID, AssetType.Unknown, assetID, "", 0);
|
||||
else
|
||||
m_log.Debug("[HGScene]: Scene.Inventory did not create asset");
|
||||
}
|
||||
|
||||
@@ -244,8 +244,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||
if (inventoryURL != null && inventoryURL != string.Empty)
|
||||
{
|
||||
inventoryURL = inventoryURL.Trim(new char[] { '/' });
|
||||
m_InventoryURLs.Add(userID, inventoryURL);
|
||||
m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
|
||||
lock (m_InventoryURLs)
|
||||
if (!m_InventoryURLs.ContainsKey(userID))
|
||||
{
|
||||
m_InventoryURLs.Add(userID, inventoryURL);
|
||||
m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -742,7 +742,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public event OnIncomingSceneObjectDelegate OnIncomingSceneObject;
|
||||
public delegate void OnIncomingSceneObjectDelegate(SceneObjectGroup so);
|
||||
|
||||
public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel);
|
||||
public delegate void NewInventoryItemUploadComplete(UUID avatarID, AssetType type, UUID assetID, string name, int userlevel);
|
||||
|
||||
public event NewInventoryItemUploadComplete OnNewInventoryItemUploadComplete;
|
||||
|
||||
@@ -2146,7 +2146,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
public void TriggerOnNewInventoryItemUploadComplete(UUID agentID, UUID AssetID, String AssetName, int userlevel)
|
||||
public void TriggerOnNewInventoryItemUploadComplete(UUID agentID, AssetType type, UUID AssetID, String AssetName, int userlevel)
|
||||
{
|
||||
NewInventoryItemUploadComplete handlerNewInventoryItemUpdateComplete = OnNewInventoryItemUploadComplete;
|
||||
if (handlerNewInventoryItemUpdateComplete != null)
|
||||
@@ -2155,7 +2155,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
try
|
||||
{
|
||||
d(agentID, AssetID, AssetName, userlevel);
|
||||
d(agentID, type, AssetID, AssetName, userlevel);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
userlevel = 1;
|
||||
}
|
||||
EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, item.AssetID, item.Name, userlevel);
|
||||
EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, (AssetType)item.AssetType, item.AssetID, item.Name, userlevel);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -178,7 +178,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
userlevel = 1;
|
||||
}
|
||||
EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, item.AssetID, item.Name, userlevel);
|
||||
EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, (AssetType)item.AssetType, item.AssetID, item.Name, userlevel);
|
||||
|
||||
if (originalFolder != UUID.Zero)
|
||||
{
|
||||
|
||||
@@ -390,6 +390,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
void ProcessViewerEffect(IClientAPI remoteClient, List<ViewerEffectEventHandlerArg> args)
|
||||
{
|
||||
// TODO: don't create new blocks if recycling an old packet
|
||||
bool discardableEffects = true;
|
||||
ViewerEffectPacket.EffectBlock[] effectBlockArray = new ViewerEffectPacket.EffectBlock[args.Count];
|
||||
for (int i = 0; i < args.Count; i++)
|
||||
{
|
||||
@@ -401,17 +402,34 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
effect.Type = args[i].Type;
|
||||
effect.TypeData = args[i].TypeData;
|
||||
effectBlockArray[i] = effect;
|
||||
|
||||
if ((EffectType)effect.Type != EffectType.LookAt && (EffectType)effect.Type != EffectType.Beam)
|
||||
discardableEffects = false;
|
||||
|
||||
//m_log.DebugFormat("[YYY]: VE {0} {1} {2}", effect.AgentID, effect.Duration, (EffectType)effect.Type);
|
||||
}
|
||||
|
||||
ForEachClient(
|
||||
delegate(IClientAPI client)
|
||||
ForEachScenePresence(sp =>
|
||||
{
|
||||
if (client.AgentId != remoteClient.AgentId)
|
||||
client.SendViewerEffect(effectBlockArray);
|
||||
}
|
||||
);
|
||||
if (sp.ControllingClient.AgentId != remoteClient.AgentId)
|
||||
{
|
||||
if (!discardableEffects ||
|
||||
(discardableEffects && ShouldSendDiscardableEffect(remoteClient, sp)))
|
||||
{
|
||||
//m_log.DebugFormat("[YYY]: Sending to {0}", sp.UUID);
|
||||
sp.ControllingClient.SendViewerEffect(effectBlockArray);
|
||||
}
|
||||
//else
|
||||
// m_log.DebugFormat("[YYY]: Not sending to {0}", sp.UUID);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private bool ShouldSendDiscardableEffect(IClientAPI thisClient, ScenePresence other)
|
||||
{
|
||||
return Vector3.Distance(other.CameraPosition, thisClient.SceneAgent.AbsolutePosition) < 10;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tell the client about the various child items and folders contained in the requested folder.
|
||||
/// </summary>
|
||||
|
||||
@@ -4203,11 +4203,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
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);
|
||||
return true;
|
||||
|
||||
@@ -801,6 +801,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
|
||||
ControllingClient.OnAgentUpdate += HandleAgentUpdate;
|
||||
ControllingClient.OnAgentCameraUpdate += HandleAgentCamerasUpdate;
|
||||
ControllingClient.OnAgentRequestSit += HandleAgentRequestSit;
|
||||
ControllingClient.OnAgentSit += HandleAgentSit;
|
||||
ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
|
||||
@@ -1124,7 +1125,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public void StopFlying()
|
||||
{
|
||||
ControllingClient.StopFlying(this);
|
||||
ControllingClient.SendAgentTerseUpdate(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1438,9 +1439,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}",
|
||||
// Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
|
||||
//m_log.DebugFormat(
|
||||
// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}",
|
||||
// Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
|
||||
|
||||
if (IsChildAgent)
|
||||
{
|
||||
@@ -1448,10 +1449,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return;
|
||||
}
|
||||
|
||||
++m_movementUpdateCount;
|
||||
if (m_movementUpdateCount < 1)
|
||||
m_movementUpdateCount = 1;
|
||||
|
||||
#region Sanity Checking
|
||||
|
||||
// This is irritating. Really.
|
||||
@@ -1482,21 +1479,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
|
||||
|
||||
// Camera location in world. We'll need to raytrace
|
||||
// from this location from time to time.
|
||||
CameraPosition = agentData.CameraCenter;
|
||||
if (Vector3.Distance(m_lastCameraPosition, CameraPosition) >= Scene.RootReprioritizationDistance)
|
||||
{
|
||||
ReprioritizeUpdates();
|
||||
m_lastCameraPosition = CameraPosition;
|
||||
}
|
||||
|
||||
// Use these three vectors to figure out what the agent is looking at
|
||||
// Convert it to a Matrix and/or Quaternion
|
||||
CameraAtAxis = agentData.CameraAtAxis;
|
||||
CameraLeftAxis = agentData.CameraLeftAxis;
|
||||
CameraUpAxis = agentData.CameraUpAxis;
|
||||
|
||||
// The Agent's Draw distance setting
|
||||
// When we get to the point of re-computing neighbors everytime this
|
||||
// changes, then start using the agent's drawdistance rather than the
|
||||
@@ -1504,12 +1486,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// DrawDistance = agentData.Far;
|
||||
DrawDistance = Scene.DefaultDrawDistance;
|
||||
|
||||
// Check if Client has camera in 'follow cam' or 'build' mode.
|
||||
Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
|
||||
|
||||
m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f)
|
||||
&& (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
|
||||
|
||||
m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
|
||||
m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
|
||||
|
||||
@@ -1529,17 +1505,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
StandUp();
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
|
||||
// Raycast from the avatar's head to the camera to see if there's anything blocking the view
|
||||
if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast())
|
||||
{
|
||||
if (m_followCamAuto)
|
||||
{
|
||||
Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
|
||||
m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback);
|
||||
}
|
||||
}
|
||||
|
||||
uint flagsForScripts = (uint)flags;
|
||||
flags = RemoveIgnoredControls(flags, IgnoredControls);
|
||||
|
||||
@@ -1763,10 +1728,79 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
SendControlsToScripts(flagsForScripts);
|
||||
}
|
||||
|
||||
// We need to send this back to the client in order to see the edit beams
|
||||
if ((State & (uint)AgentState.Editing) != 0)
|
||||
ControllingClient.SendAgentTerseUpdate(this);
|
||||
|
||||
m_scene.EventManager.TriggerOnClientMovement(this);
|
||||
TriggerScenePresenceUpdated();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This is the event handler for client cameras. If a client is moving, or moving the camera, this event is triggering.
|
||||
/// </summary>
|
||||
private void HandleAgentCamerasUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
|
||||
{
|
||||
//m_log.DebugFormat(
|
||||
// "[SCENE PRESENCE]: In {0} received agent camera update from {1}, flags {2}",
|
||||
// Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
|
||||
|
||||
if (IsChildAgent)
|
||||
{
|
||||
// // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
|
||||
return;
|
||||
}
|
||||
|
||||
++m_movementUpdateCount;
|
||||
if (m_movementUpdateCount < 1)
|
||||
m_movementUpdateCount = 1;
|
||||
|
||||
|
||||
AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
|
||||
|
||||
// Camera location in world. We'll need to raytrace
|
||||
// from this location from time to time.
|
||||
CameraPosition = agentData.CameraCenter;
|
||||
if (Vector3.Distance(m_lastCameraPosition, CameraPosition) >= Scene.RootReprioritizationDistance)
|
||||
{
|
||||
ReprioritizeUpdates();
|
||||
m_lastCameraPosition = CameraPosition;
|
||||
}
|
||||
|
||||
// Use these three vectors to figure out what the agent is looking at
|
||||
// Convert it to a Matrix and/or Quaternion
|
||||
CameraAtAxis = agentData.CameraAtAxis;
|
||||
CameraLeftAxis = agentData.CameraLeftAxis;
|
||||
CameraUpAxis = agentData.CameraUpAxis;
|
||||
|
||||
// The Agent's Draw distance setting
|
||||
// When we get to the point of re-computing neighbors everytime this
|
||||
// changes, then start using the agent's drawdistance rather than the
|
||||
// region's draw distance.
|
||||
// DrawDistance = agentData.Far;
|
||||
DrawDistance = Scene.DefaultDrawDistance;
|
||||
|
||||
// Check if Client has camera in 'follow cam' or 'build' mode.
|
||||
Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
|
||||
|
||||
m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f)
|
||||
&& (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
|
||||
|
||||
|
||||
//m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
|
||||
// Raycast from the avatar's head to the camera to see if there's anything blocking the view
|
||||
if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast())
|
||||
{
|
||||
if (m_followCamAuto)
|
||||
{
|
||||
Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
|
||||
m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback);
|
||||
}
|
||||
}
|
||||
|
||||
TriggerScenePresenceUpdated();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate an update to move the presence to the set target.
|
||||
/// </summary>
|
||||
@@ -3335,8 +3369,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()",
|
||||
// Name, m_scene.RegionInfo.RegionName, m_callbackURI);
|
||||
|
||||
// Don't copy the agent position
|
||||
|
||||
m_pos = cAgent.Position;
|
||||
m_velocity = cAgent.Velocity;
|
||||
CameraPosition = cAgent.Center;
|
||||
CameraAtAxis = cAgent.AtAxis;
|
||||
|
||||
@@ -687,6 +687,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||
public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
|
||||
public event UpdateAgent OnPreAgentUpdate;
|
||||
public event UpdateAgent OnAgentUpdate;
|
||||
public event UpdateAgent OnAgentCameraUpdate;
|
||||
public event AgentRequestSit OnAgentRequestSit;
|
||||
public event AgentSit OnAgentSit;
|
||||
public event AvatarPickerRequest OnAvatarPickerRequest;
|
||||
@@ -1672,7 +1673,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||
{
|
||||
}
|
||||
|
||||
public void StopFlying(ISceneEntity presence)
|
||||
public void SendAgentTerseUpdate(ISceneEntity presence)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -611,7 +611,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||
//
|
||||
if (showParams.Length <= 4)
|
||||
{
|
||||
m_log.InfoFormat("[INFO]: {0,-12} {1,20} {2,6} {3,11} {4, 10}", "Region", "Name", "Root", "Time", "Reqs/min");
|
||||
m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}", "Region", "Name", "Root", "Time", "Reqs/min", "AgentUpdates");
|
||||
foreach (Scene scene in m_scenes.Values)
|
||||
{
|
||||
scene.ForEachClient(
|
||||
@@ -624,9 +624,15 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||
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}",
|
||||
m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}",
|
||||
scene.RegionInfo.RegionName, llClient.Name,
|
||||
(llClient.SceneAgent.IsChildAgent ? "N" : "Y"), (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs);
|
||||
llClient.SceneAgent.IsChildAgent ? "N" : "Y",
|
||||
(DateTime.Now - cinfo.StartedTime).Minutes,
|
||||
avg_reqs,
|
||||
string.Format(
|
||||
"{0} ({1:0.00}%)",
|
||||
llClient.TotalAgentUpdates,
|
||||
(float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -258,6 +258,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
|
||||
public event UpdateAgent OnPreAgentUpdate;
|
||||
public event UpdateAgent OnAgentUpdate;
|
||||
public event UpdateAgent OnAgentCameraUpdate;
|
||||
public event AgentRequestSit OnAgentRequestSit;
|
||||
public event AgentSit OnAgentSit;
|
||||
public event AvatarPickerRequest OnAvatarPickerRequest;
|
||||
@@ -1228,7 +1229,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
{
|
||||
}
|
||||
|
||||
public void StopFlying(ISceneEntity presence)
|
||||
public void SendAgentTerseUpdate(ISceneEntity presence)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -493,6 +493,22 @@ namespace OpenSim.Services.HypergridService
|
||||
return null;
|
||||
}
|
||||
|
||||
private XInventoryFolder GetCurrentOutfitXFolder(UUID userID)
|
||||
{
|
||||
XInventoryFolder root = GetRootXFolder(userID);
|
||||
if (root == null)
|
||||
return null;
|
||||
|
||||
XInventoryFolder[] folders = m_Database.GetFolders(
|
||||
new string[] { "agentID", "type", "parentFolderID" },
|
||||
new string[] { userID.ToString(), ((int)AssetType.CurrentOutfitFolder).ToString(), root.folderID.ToString() });
|
||||
|
||||
if (folders.Length == 0)
|
||||
return null;
|
||||
|
||||
return folders[0];
|
||||
}
|
||||
|
||||
private XInventoryFolder GetSuitcaseXFolder(UUID principalID)
|
||||
{
|
||||
// Warp! Root folder for travelers
|
||||
@@ -531,6 +547,7 @@ namespace OpenSim.Services.HypergridService
|
||||
if (m_SuitcaseTrees.TryGetValue(principalID, out t))
|
||||
return t;
|
||||
|
||||
// Get the tree of the suitcase folder
|
||||
t = GetFolderTreeRecursive(folder);
|
||||
m_SuitcaseTrees.AddOrUpdate(principalID, t, 5*60); // 5minutes
|
||||
return t;
|
||||
@@ -577,6 +594,9 @@ namespace OpenSim.Services.HypergridService
|
||||
List<XInventoryFolder> tree = new List<XInventoryFolder>();
|
||||
tree.Add(suitcase); // Warp! the tree is the real root folder plus the children of the suitcase folder
|
||||
tree.AddRange(GetFolderTree(principalID, suitcase.folderID));
|
||||
// Also add the Current Outfit folder to the list of available folders
|
||||
tree.Add(GetCurrentOutfitXFolder(principalID));
|
||||
|
||||
XInventoryFolder f = tree.Find(delegate(XInventoryFolder fl)
|
||||
{
|
||||
if (fl.folderID == folderID) return true;
|
||||
|
||||
@@ -106,6 +106,7 @@ namespace OpenSim.Tests.Common.Mock
|
||||
public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
|
||||
public event UpdateAgent OnPreAgentUpdate;
|
||||
public event UpdateAgent OnAgentUpdate;
|
||||
public event UpdateAgent OnAgentCameraUpdate;
|
||||
public event AgentRequestSit OnAgentRequestSit;
|
||||
public event AgentSit OnAgentSit;
|
||||
public event AvatarPickerRequest OnAvatarPickerRequest;
|
||||
@@ -1255,7 +1256,7 @@ namespace OpenSim.Tests.Common.Mock
|
||||
{
|
||||
}
|
||||
|
||||
public void StopFlying(ISceneEntity presence)
|
||||
public void SendAgentTerseUpdate(ISceneEntity presence)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user