Merge branch 'master' into bigmerge

Conflicts:
	OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
This commit is contained in:
Melanie
2011-11-28 11:06:38 +00:00
31 changed files with 706 additions and 455 deletions

View File

@@ -134,7 +134,6 @@ namespace OpenSim.Region.ClientStack.Linden
AddNewInventoryItem = m_Scene.AddUploadedInventoryItem;
ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset;
TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
CAPSFetchInventoryDescendents = m_Scene.HandleFetchInventoryDescendentsCAPS;
GetClient = m_Scene.SceneGraph.GetControllingClient;
}

View File

@@ -39,6 +39,7 @@ using OpenMetaverse.Messages.Linden;
using OpenMetaverse.Packets;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
@@ -58,9 +59,15 @@ namespace OpenSim.Region.ClientStack.Linden
public class EventQueueGetModule : IEventQueue, IRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected Scene m_scene = null;
/// <value>
/// Debug level.
/// </value>
public int DebugLevel { get; set; }
protected Scene m_scene;
private IConfigSource m_gConfig;
bool enabledYN = false;
bool enabledYN;
private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
@@ -97,6 +104,15 @@ namespace OpenSim.Region.ClientStack.Linden
scene.EventManager.OnClientClosed += ClientClosed;
scene.EventManager.OnMakeChildAgent += MakeChildAgent;
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
MainConsole.Instance.Commands.AddCommand(
"event queue",
false,
"debug eq",
"debug eq [0|1]",
"debug eq 1 will turn on event queue debugging. This will log all outgoing event queue messages to clients.\n"
+ "debug eq 1 will turn off event queue debugging.",
HandleDebugEq);
}
else
{
@@ -128,6 +144,22 @@ namespace OpenSim.Region.ClientStack.Linden
}
#endregion
protected void HandleDebugEq(string module, string[] args)
{
int debugLevel;
if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel)))
{
MainConsole.Instance.OutputFormat("Usage: debug eq [0|1]");
}
else
{
DebugLevel = debugLevel;
MainConsole.Instance.OutputFormat(
"Set event queue debug level to {0} in {1}", DebugLevel, m_scene.RegionInfo.RegionName);
}
}
/// <summary>
/// Always returns a valid queue
/// </summary>
@@ -314,16 +346,22 @@ namespace OpenSim.Region.ClientStack.Linden
}
// 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", capsBase + EventQueueGetUUID.ToString() + "/",
delegate(Hashtable m_dhttpMethod)
{
return ProcessQueue(m_dhttpMethod, agentID, caps);
}));
new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString() + "/", null));
// delegate(Hashtable m_dhttpMethod)
// {
// return ProcessQueue(m_dhttpMethod, agentID, caps);
// }));
// This will persist this beyond the expiry of the caps handlers
MainServer.Instance.AddPollServiceHTTPHandler(
capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePoll, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
capsBase + EventQueueGetUUID.ToString() + "/",
EventQueuePoll,
new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
Random rnd = new Random(Environment.TickCount);
lock (m_ids)
@@ -348,6 +386,8 @@ namespace OpenSim.Region.ClientStack.Linden
public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request)
{
// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Invoked GetEvents() for {0}", pAgentId);
Queue<OSD> queue = TryGetQueue(pAgentId);
OSD element;
lock (queue)
@@ -370,12 +410,31 @@ namespace OpenSim.Region.ClientStack.Linden
}
else
{
if (DebugLevel > 0 && element is OSDMap)
{
OSDMap ev = (OSDMap)element;
m_log.DebugFormat(
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
ev["message"], m_scene.GetScenePresence(pAgentId).Name);
}
array.Add(element);
lock (queue)
{
while (queue.Count > 0)
{
array.Add(queue.Dequeue());
element = queue.Dequeue();
if (DebugLevel > 0 && element is OSDMap)
{
OSDMap ev = (OSDMap)element;
m_log.DebugFormat(
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
ev["message"], m_scene.GetScenePresence(pAgentId).Name);
}
array.Add(element);
thisID++;
}
}
@@ -412,148 +471,166 @@ namespace OpenSim.Region.ClientStack.Linden
return responsedata;
}
public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps)
{
// TODO: this has to be redone to not busy-wait (and block the thread),
// TODO: as soon as we have a non-blocking way to handle HTTP-requests.
// if (m_log.IsDebugEnabled)
// {
// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ ";
// foreach (object key in request.Keys)
// public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps)
// {
// // TODO: this has to be redone to not busy-wait (and block the thread),
// // TODO: as soon as we have a non-blocking way to handle HTTP-requests.
//
//// if (m_log.IsDebugEnabled)
//// {
//// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ ";
//// foreach (object key in request.Keys)
//// {
//// debug += key.ToString() + "=" + request[key].ToString() + " ";
//// }
//// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name);
//// }
//
// Queue<OSD> queue = TryGetQueue(agentID);
// OSD element;
//
// lock (queue)
// element = queue.Dequeue(); // 15s timeout
//
// Hashtable responsedata = new Hashtable();
//
// int thisID = 0;
// lock (m_ids)
// thisID = m_ids[agentID];
//
// if (element == null)
// {
// //m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName);
// if (thisID == -1) // close-request
// {
// debug += key.ToString() + "=" + request[key].ToString() + " ";
// m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName);
// responsedata["int_response_code"] = 404; //501; //410; //404;
// responsedata["content_type"] = "text/plain";
// responsedata["keepalive"] = false;
// responsedata["str_response_string"] = "Closed EQG";
// return responsedata;
// }
// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name);
// responsedata["int_response_code"] = 502;
// responsedata["content_type"] = "text/plain";
// responsedata["keepalive"] = false;
// responsedata["str_response_string"] = "Upstream error: ";
// responsedata["error_status_text"] = "Upstream error:";
// responsedata["http_protocol_version"] = "HTTP/1.0";
// return responsedata;
// }
Queue<OSD> queue = TryGetQueue(agentID);
OSD element;
lock (queue)
element = queue.Dequeue(); // 15s timeout
Hashtable responsedata = new Hashtable();
int thisID = 0;
lock (m_ids)
thisID = m_ids[agentID];
if (element == null)
{
//m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName);
if (thisID == -1) // close-request
{
m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName);
responsedata["int_response_code"] = 404; //501; //410; //404;
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Closed EQG";
return responsedata;
}
responsedata["int_response_code"] = 502;
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Upstream error: ";
responsedata["error_status_text"] = "Upstream error:";
responsedata["http_protocol_version"] = "HTTP/1.0";
return responsedata;
}
OSDArray array = new OSDArray();
if (element == null) // didn't have an event in 15s
{
// Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
array.Add(EventQueueHelper.KeepAliveEvent());
//m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
}
else
{
array.Add(element);
lock (queue)
{
while (queue.Count > 0)
{
array.Add(queue.Dequeue());
thisID++;
}
}
}
OSDMap events = new OSDMap();
events.Add("events", array);
events.Add("id", new OSDInteger(thisID));
lock (m_ids)
{
m_ids[agentID] = thisID + 1;
}
responsedata["int_response_code"] = 200;
responsedata["content_type"] = "application/xml";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
//m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
return responsedata;
}
//
// OSDArray array = new OSDArray();
// if (element == null) // didn't have an event in 15s
// {
// // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
// array.Add(EventQueueHelper.KeepAliveEvent());
// //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
// }
// else
// {
// array.Add(element);
//
// if (element is OSDMap)
// {
// OSDMap ev = (OSDMap)element;
// m_log.DebugFormat(
// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
// ev["message"], m_scene.GetScenePresence(agentID).Name);
// }
//
// lock (queue)
// {
// while (queue.Count > 0)
// {
// element = queue.Dequeue();
//
// if (element is OSDMap)
// {
// OSDMap ev = (OSDMap)element;
// m_log.DebugFormat(
// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
// ev["message"], m_scene.GetScenePresence(agentID).Name);
// }
//
// array.Add(element);
// thisID++;
// }
// }
// }
//
// OSDMap events = new OSDMap();
// events.Add("events", array);
//
// events.Add("id", new OSDInteger(thisID));
// lock (m_ids)
// {
// m_ids[agentID] = thisID + 1;
// }
//
// responsedata["int_response_code"] = 200;
// responsedata["content_type"] = "application/xml";
// responsedata["keepalive"] = false;
// responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
//
// m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
//
// return responsedata;
// }
public Hashtable EventQueuePoll(Hashtable request)
{
return new Hashtable();
}
public Hashtable EventQueuePath2(Hashtable request)
{
string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/","");
// pull off the last "/" in the path.
Hashtable responsedata = new Hashtable();
capuuid = capuuid.Substring(0, capuuid.Length - 1);
capuuid = capuuid.Replace("/CAPS/EQG/", "");
UUID AvatarID = UUID.Zero;
UUID capUUID = UUID.Zero;
// parse the path and search for the avatar with it registered
if (UUID.TryParse(capuuid, out capUUID))
{
lock (m_QueueUUIDAvatarMapping)
{
if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
{
AvatarID = m_QueueUUIDAvatarMapping[capUUID];
}
}
if (AvatarID != UUID.Zero)
{
return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
}
else
{
responsedata["int_response_code"] = 404;
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Not Found";
responsedata["error_status_text"] = "Not Found";
responsedata["http_protocol_version"] = "HTTP/1.0";
return responsedata;
// return 404
}
}
else
{
responsedata["int_response_code"] = 404;
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Not Found";
responsedata["error_status_text"] = "Not Found";
responsedata["http_protocol_version"] = "HTTP/1.0";
return responsedata;
// return 404
}
}
// public Hashtable EventQueuePath2(Hashtable request)
// {
// string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/","");
// // pull off the last "/" in the path.
// Hashtable responsedata = new Hashtable();
// capuuid = capuuid.Substring(0, capuuid.Length - 1);
// capuuid = capuuid.Replace("/CAPS/EQG/", "");
// UUID AvatarID = UUID.Zero;
// UUID capUUID = UUID.Zero;
//
// // parse the path and search for the avatar with it registered
// if (UUID.TryParse(capuuid, out capUUID))
// {
// lock (m_QueueUUIDAvatarMapping)
// {
// if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
// {
// AvatarID = m_QueueUUIDAvatarMapping[capUUID];
// }
// }
//
// if (AvatarID != UUID.Zero)
// {
// return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
// }
// else
// {
// responsedata["int_response_code"] = 404;
// responsedata["content_type"] = "text/plain";
// responsedata["keepalive"] = false;
// responsedata["str_response_string"] = "Not Found";
// responsedata["error_status_text"] = "Not Found";
// responsedata["http_protocol_version"] = "HTTP/1.0";
// return responsedata;
// // return 404
// }
// }
// else
// {
// responsedata["int_response_code"] = 404;
// responsedata["content_type"] = "text/plain";
// responsedata["keepalive"] = false;
// responsedata["str_response_string"] = "Not Found";
// responsedata["error_status_text"] = "Not Found";
// responsedata["http_protocol_version"] = "HTTP/1.0";
// return responsedata;
// // return 404
// }
// }
public OSD EventQueueFallBack(string path, OSD request, string endpoint)
{
@@ -717,6 +794,7 @@ namespace OpenSim.Region.ClientStack.Linden
OSD item = EventQueueHelper.GroupMembership(groupUpdate);
Enqueue(item, avatarID);
}
public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID)
{
OSD item = EventQueueHelper.PlacesQuery(groupUpdate);

View File

@@ -42,18 +42,25 @@ using OpenSim.Capabilities.Handlers;
namespace OpenSim.Region.ClientStack.Linden
{
/// <summary>
/// This module implements both WebFetchInventoryDescendents and FetchInventoryDescendents2 capabilities.
/// </summary>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class WebFetchInvDescModule : INonSharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
private IInventoryService m_InventoryService;
private ILibraryService m_LibraryService;
private bool m_Enabled = false;
private string m_URL;
private bool m_Enabled;
private string m_fetchInventoryDescendents2Url;
private string m_webFetchInventoryDescendentsUrl;
private WebFetchInvDescHandler m_webFetchHandler;
#region ISharedRegionModule Members
@@ -63,10 +70,13 @@ namespace OpenSim.Region.ClientStack.Linden
if (config == null)
return;
m_URL = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty);
// Cap doesn't exist
if (m_URL != string.Empty)
m_fetchInventoryDescendents2Url = config.GetString("Cap_FetchInventoryDescendents2", string.Empty);
m_webFetchInventoryDescendentsUrl = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty);
if (m_fetchInventoryDescendents2Url != string.Empty || m_webFetchInventoryDescendentsUrl != string.Empty)
{
m_Enabled = true;
}
}
public void AddRegion(Scene s)
@@ -91,8 +101,13 @@ namespace OpenSim.Region.ClientStack.Linden
if (!m_Enabled)
return;
m_InventoryService = m_scene.InventoryService; ;
m_InventoryService = m_scene.InventoryService;
m_LibraryService = m_scene.LibraryService;
// We'll reuse the same handler for all requests.
if (m_fetchInventoryDescendents2Url == "localhost" || m_webFetchInventoryDescendentsUrl == "localhost")
m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
}
@@ -111,24 +126,38 @@ namespace OpenSim.Region.ClientStack.Linden
#endregion
public void RegisterCaps(UUID agentID, Caps caps)
private void RegisterCaps(UUID agentID, Caps caps)
{
UUID capID = UUID.Random();
if (m_webFetchInventoryDescendentsUrl != "")
RegisterFetchCap(agentID, caps, "WebFetchInventoryDescendents", m_webFetchInventoryDescendentsUrl);
//caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
if (m_URL == "localhost")
if (m_fetchInventoryDescendents2Url != "")
RegisterFetchCap(agentID, caps, "FetchInventoryDescendents2", m_fetchInventoryDescendents2Url);
}
private void RegisterFetchCap(UUID agentID, Caps caps, string capName, string url)
{
string capUrl;
if (url == "localhost")
{
m_log.InfoFormat("[WEBFETCHINVENTORYDESCENDANTS]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
IRequestHandler reqHandler = new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), webFetchHandler.FetchInventoryDescendentsRequest);
caps.RegisterHandler("WebFetchInventoryDescendents", reqHandler);
capUrl = "/CAPS/" + UUID.Random();
IRequestHandler reqHandler
= new RestStreamHandler("POST", capUrl, m_webFetchHandler.FetchInventoryDescendentsRequest);
caps.RegisterHandler(capName, reqHandler);
}
else
{
m_log.InfoFormat("[WEBFETCHINVENTORYDESCENDANTS]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
caps.RegisterHandler("WebFetchInventoryDescendents", m_URL);
}
}
capUrl = url;
caps.RegisterHandler(capName, capUrl);
}
// m_log.DebugFormat(
// "[WEB FETCH INV DESC MODULE]: Registered capability {0} at {1} in region {2} for {3}",
// capName, capUrl, m_scene.RegionInfo.RegionName, agentID);
}
}
}

View File

@@ -11730,7 +11730,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
logPacket = false;
if (logPacket)
m_log.DebugFormat("[CLIENT]: Packet OUT {0} to {1}", packet.Type, Name);
m_log.DebugFormat(
"[CLIENT]: PACKET OUT to {0} ({1}) in {2} - {3}",
Name, ChildAgentStatus() ? "child" : "root ", m_scene.RegionInfo.RegionName, packet.Type);
}
m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method);
@@ -11773,19 +11775,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
if (DebugPacketLevel > 0)
{
bool outputPacket = true;
bool logPacket = true;
if (DebugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
outputPacket = false;
logPacket = false;
if (DebugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
outputPacket = false;
logPacket = false;
if (DebugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
outputPacket = false;
logPacket = false;
if (outputPacket)
m_log.DebugFormat("[CLIENT]: Packet IN {0} from {1}", packet.Type, Name);
if (logPacket)
m_log.DebugFormat(
"[CLIENT]: PACKET IN from {0} ({1}) in {2} - {3}",
Name, ChildAgentStatus() ? "child" : "root ", m_scene.RegionInfo.RegionName, packet.Type);
}
if (!ProcessPacketMethod(packet))