Merge branch 'master' of /home/opensim/src/OpenSim/Core

bulletsim
BlueWall 2011-02-12 20:42:11 -05:00
commit c0e1742d47
59 changed files with 1164 additions and 2164 deletions

View File

@ -122,9 +122,11 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " +
Thread.CurrentThread.ManagedThreadId.ToString() + Thread.CurrentThread.ManagedThreadId.ToString() +
")"); ")");
m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]); m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]);
m_openSim.CreateRegion(regionsToLoad[i], true, out scene); m_openSim.CreateRegion(regionsToLoad[i], true, out scene);
regionsToLoad[i].EstateSettings.Save(); regionsToLoad[i].EstateSettings.Save();
if (scene != null) if (scene != null)
{ {
m_newRegionCreatedHandler = OnNewRegionCreated; m_newRegionCreatedHandler = OnNewRegionCreated;

View File

@ -44,7 +44,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// private static readonly int PARM_PATH = 1; // private static readonly int PARM_PATH = 1;
private bool enabled = false; // private bool enabled = false;
private string qPrefix = "appearance"; private string qPrefix = "appearance";
/// <summary> /// <summary>
@ -74,7 +74,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// Activate if everything went OK // Activate if everything went OK
enabled = true; // enabled = true;
Rest.Log.InfoFormat("{0} User appearance services initialization complete", MsgId); Rest.Log.InfoFormat("{0} User appearance services initialization complete", MsgId);
} }
@ -95,7 +95,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
public void Close() public void Close()
{ {
enabled = false; // enabled = false;
Rest.Log.InfoFormat("{0} User appearance services closing down", MsgId); Rest.Log.InfoFormat("{0} User appearance services closing down", MsgId);
} }

View File

@ -46,12 +46,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
public class RestInventoryServices : IRest public class RestInventoryServices : IRest
{ {
// private static readonly int PARM_USERID = 0; // private static readonly int PARM_USERID = 0;
private static readonly int PARM_PATH = 1; // private static readonly int PARM_PATH = 1;
// private bool enabled = false; // private bool enabled = false;
private string qPrefix = "inventory"; private string qPrefix = "inventory";
private static readonly string PRIVATE_ROOT_NAME = "My Inventory"; // private static readonly string PRIVATE_ROOT_NAME = "My Inventory";
/// <summary> /// <summary>
/// The constructor makes sure that the service prefix is absolute /// The constructor makes sure that the service prefix is absolute

View File

@ -669,10 +669,6 @@ namespace OpenSim.Data.SQLite
} }
} }
/// <summary>
///
/// </summary>
/// <param name="globalID"></param>
public void RemoveLandObject(UUID globalID) public void RemoveLandObject(UUID globalID)
{ {
lock (ds) lock (ds)
@ -698,7 +694,6 @@ namespace OpenSim.Data.SQLite
if (landRow != null) if (landRow != null)
{ {
landRow.Delete(); landRow.Delete();
land.Rows.Remove(landRow);
} }
List<DataRow> rowsToDelete = new List<DataRow>(); List<DataRow> rowsToDelete = new List<DataRow>();
foreach (DataRow rowToCheck in landaccesslist.Rows) foreach (DataRow rowToCheck in landaccesslist.Rows)
@ -709,7 +704,6 @@ namespace OpenSim.Data.SQLite
for (int iter = 0; iter < rowsToDelete.Count; iter++) for (int iter = 0; iter < rowsToDelete.Count; iter++)
{ {
rowsToDelete[iter].Delete(); rowsToDelete[iter].Delete();
landaccesslist.Rows.Remove(rowsToDelete[iter]);
} }
} }
Commit(); Commit();

View File

@ -220,6 +220,8 @@ namespace OpenSim.Framework
args["packed_appearance"] = appmap; args["packed_appearance"] = appmap;
} }
// Old, bad way. Keeping it fow now for backwards compatibility
// OBSOLETE -- soon to be deleted
if (ServiceURLs != null && ServiceURLs.Count > 0) if (ServiceURLs != null && ServiceURLs.Count > 0)
{ {
OSDArray urls = new OSDArray(ServiceURLs.Count * 2); OSDArray urls = new OSDArray(ServiceURLs.Count * 2);
@ -232,6 +234,19 @@ namespace OpenSim.Framework
args["service_urls"] = urls; args["service_urls"] = urls;
} }
// again, this time the right way
if (ServiceURLs != null && ServiceURLs.Count > 0)
{
OSDMap urls = new OSDMap();
foreach (KeyValuePair<string, object> kvp in ServiceURLs)
{
//System.Console.WriteLine("XXX " + kvp.Key + "=" + kvp.Value);
urls[kvp.Key] = OSD.FromString((kvp.Value == null) ? string.Empty : kvp.Value.ToString());
}
args["serviceurls"] = urls;
}
return args; return args;
} }
@ -327,7 +342,20 @@ namespace OpenSim.Framework
} }
ServiceURLs = new Dictionary<string, object>(); ServiceURLs = new Dictionary<string, object>();
if (args.ContainsKey("service_urls") && args["service_urls"] != null && (args["service_urls"]).Type == OSDType.Array) // Try parse the new way, OSDMap
if (args.ContainsKey("serviceurls") && args["serviceurls"] != null && (args["serviceurls"]).Type == OSDType.Map)
{
OSDMap urls = (OSDMap)(args["serviceurls"]);
foreach (KeyValuePair<String, OSD> kvp in urls)
{
ServiceURLs[kvp.Key] = kvp.Value.AsString();
//System.Console.WriteLine("XXX " + kvp.Key + "=" + ServiceURLs[kvp.Key]);
}
}
// else try the old way, OSDArray
// OBSOLETE -- soon to be deleted
else if (args.ContainsKey("service_urls") && args["service_urls"] != null && (args["service_urls"]).Type == OSDType.Array)
{ {
OSDArray urls = (OSDArray)(args["service_urls"]); OSDArray urls = (OSDArray)(args["service_urls"]);
for (int i = 0; i < urls.Count / 2; i++) for (int i = 0; i < urls.Count / 2; i++)

View File

@ -88,8 +88,8 @@ namespace OpenSim.Framework.Capabilities
/// handler to be removed</param> /// handler to be removed</param>
public void Remove(string capsName) public void Remove(string capsName)
{ {
// This line must be here, or caps will break!
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path); m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
m_capsHandlers.Remove(capsName); m_capsHandlers.Remove(capsName);
} }

View File

@ -303,7 +303,7 @@ namespace OpenSim.Framework.Serialization.External
writer.WriteStartElement("GroupOwned"); writer.WriteStartElement("GroupOwned");
writer.WriteString(inventoryItem.GroupOwned.ToString()); writer.WriteString(inventoryItem.GroupOwned.ToString());
writer.WriteEndElement(); writer.WriteEndElement();
if (inventoryItem.CreatorData != null && inventoryItem.CreatorData != string.Empty) if (options.ContainsKey("creators") && inventoryItem.CreatorData != null && inventoryItem.CreatorData != string.Empty)
writer.WriteElementString("CreatorData", inventoryItem.CreatorData); writer.WriteElementString("CreatorData", inventoryItem.CreatorData);
else if (options.ContainsKey("profile")) else if (options.ContainsKey("profile"))
{ {

View File

@ -319,18 +319,21 @@ namespace OpenSim.Framework.Servers
return; return;
} }
string rawLevel = cmd[3]; if (cmd.Length > 3)
{
ILoggerRepository repository = LogManager.GetRepository(); string rawLevel = cmd[3];
Level consoleLevel = repository.LevelMap[rawLevel];
ILoggerRepository repository = LogManager.GetRepository();
if (consoleLevel != null) Level consoleLevel = repository.LevelMap[rawLevel];
m_consoleAppender.Threshold = consoleLevel;
else if (consoleLevel != null)
Notice( m_consoleAppender.Threshold = consoleLevel;
String.Format( else
"{0} is not a valid logging level. Valid logging levels are ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF", Notice(
rawLevel)); String.Format(
"{0} is not a valid logging level. Valid logging levels are ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF",
rawLevel));
}
Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
} }

View File

@ -143,6 +143,11 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
} }
public List<string> GetStreamHandlerKeys()
{
return new List<string>(m_streamHandlers.Keys);
}
private static string GetHandlerKey(string httpMethod, string path) private static string GetHandlerKey(string httpMethod, string path)
{ {
return httpMethod + ":" + path; return httpMethod + ":" + path;
@ -179,6 +184,11 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
} }
public List<string> GetXmlRpcHandlerKeys()
{
return new List<string>(m_rpcHandlers.Keys);
}
public bool AddHTTPHandler(string methodName, GenericHTTPMethod handler) public bool AddHTTPHandler(string methodName, GenericHTTPMethod handler)
{ {
//m_log.DebugFormat("[BASE HTTP SERVER]: Registering {0}", methodName); //m_log.DebugFormat("[BASE HTTP SERVER]: Registering {0}", methodName);
@ -196,6 +206,12 @@ namespace OpenSim.Framework.Servers.HttpServer
return false; return false;
} }
public List<string> GetHTTPHandlerKeys()
{
return new List<string>(m_HTTPHandlers.Keys);
}
public bool AddPollServiceHTTPHandler(string methodName, GenericHTTPMethod handler, PollServiceEventArgs args) public bool AddPollServiceHTTPHandler(string methodName, GenericHTTPMethod handler, PollServiceEventArgs args)
{ {
bool pollHandlerResult = false; bool pollHandlerResult = false;
@ -214,6 +230,12 @@ namespace OpenSim.Framework.Servers.HttpServer
return false; return false;
} }
public List<string> GetPollServiceHandlerKeys()
{
return new List<string>(m_pollHandlers.Keys);
}
// Note that the agent string is provided simply to differentiate // Note that the agent string is provided simply to differentiate
// the handlers - it is NOT required to be an actual agent header // the handlers - it is NOT required to be an actual agent header
// value. // value.
@ -232,6 +254,11 @@ namespace OpenSim.Framework.Servers.HttpServer
return false; return false;
} }
public List<string> GetAgentHandlerKeys()
{
return new List<string>(m_agentHandlers.Keys);
}
public bool AddLLSDHandler(string path, LLSDMethod handler) public bool AddLLSDHandler(string path, LLSDMethod handler)
{ {
lock (m_llsdHandlers) lock (m_llsdHandlers)
@ -245,6 +272,11 @@ namespace OpenSim.Framework.Servers.HttpServer
return false; return false;
} }
public List<string> GetLLSDHandlerKeys()
{
return new List<string>(m_llsdHandlers.Keys);
}
public bool SetDefaultLLSDHandler(DefaultLLSDMethod handler) public bool SetDefaultLLSDHandler(DefaultLLSDMethod handler)
{ {
m_defaultLlsdHandler = handler; m_defaultLlsdHandler = handler;

View File

@ -1334,6 +1334,11 @@ namespace OpenSim.Framework
return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri; return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri;
} }
public static byte[] StringToBytes256(string str, params object[] args)
{
return StringToBytes256(string.Format(str, args));
}
public static byte[] StringToBytes256(string str) public static byte[] StringToBytes256(string str)
{ {
if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; } if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; }
@ -1352,6 +1357,11 @@ namespace OpenSim.Framework
return data; return data;
} }
public static byte[] StringToBytes1024(string str, params object[] args)
{
return StringToBytes1024(string.Format(str, args));
}
public static byte[] StringToBytes1024(string str) public static byte[] StringToBytes1024(string str)
{ {
if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; } if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; }

View File

@ -294,6 +294,18 @@ namespace OpenSim
"show connections", "show connections",
"Show connection data", HandleShow); "Show connection data", HandleShow);
m_console.Commands.AddCommand("region", false, "show circuits",
"show circuits",
"Show agent circuit data", HandleShow);
m_console.Commands.AddCommand("region", false, "show http-handlers",
"show http-handlers",
"Show all registered http handlers", HandleShow);
m_console.Commands.AddCommand("region", false, "show pending-objects",
"show pending-objects",
"Show # of objects on the pending queues of all scene viewers", HandleShow);
m_console.Commands.AddCommand("region", false, "show modules", m_console.Commands.AddCommand("region", false, "show modules",
"show modules", "show modules",
"Show module data", HandleShow); "Show module data", HandleShow);
@ -943,6 +955,66 @@ namespace OpenSim
MainConsole.Instance.Output(connections.ToString()); MainConsole.Instance.Output(connections.ToString());
break; break;
case "circuits":
System.Text.StringBuilder acd = new System.Text.StringBuilder("Agent Circuits:\n");
m_sceneManager.ForEachScene(
delegate(Scene scene)
{
//this.HttpServer.
acd.AppendFormat("{0}:\n", scene.RegionInfo.RegionName);
foreach (AgentCircuitData aCircuit in scene.AuthenticateHandler.AgentCircuits.Values)
acd.AppendFormat("\t{0} {1} ({2})\n", aCircuit.firstname, aCircuit.lastname, (aCircuit.child ? "Child" : "Root"));
}
);
MainConsole.Instance.Output(acd.ToString());
break;
case "http-handlers":
System.Text.StringBuilder handlers = new System.Text.StringBuilder("Registered HTTP Handlers:\n");
handlers.AppendFormat("* XMLRPC:\n");
foreach (String s in HttpServer.GetXmlRpcHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
handlers.AppendFormat("* HTTP:\n");
List<String> poll = HttpServer.GetPollServiceHandlerKeys();
foreach (String s in HttpServer.GetHTTPHandlerKeys())
handlers.AppendFormat("\t{0} {1}\n", s, (poll.Contains(s) ? "(poll service)" : string.Empty));
handlers.AppendFormat("* Agent:\n");
foreach (String s in HttpServer.GetAgentHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
handlers.AppendFormat("* LLSD:\n");
foreach (String s in HttpServer.GetLLSDHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
handlers.AppendFormat("* StreamHandlers ({0}):\n", HttpServer.GetStreamHandlerKeys().Count);
foreach (String s in HttpServer.GetStreamHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
MainConsole.Instance.Output(handlers.ToString());
break;
case "pending-objects":
System.Text.StringBuilder pending = new System.Text.StringBuilder("Pending objects:\n");
m_sceneManager.ForEachScene(
delegate(Scene scene)
{
scene.ForEachScenePresence(
delegate(ScenePresence sp)
{
pending.AppendFormat("{0}: {1} {2} pending\n",
scene.RegionInfo.RegionName, sp.Name, sp.SceneViewer.GetPendingObjectsCount());
}
);
}
);
MainConsole.Instance.Output(pending.ToString());
break;
case "modules": case "modules":
MainConsole.Instance.Output("The currently loaded shared modules are:"); MainConsole.Instance.Output("The currently loaded shared modules are:");
foreach (IRegionModule module in m_moduleLoader.GetLoadedSharedModules) foreach (IRegionModule module in m_moduleLoader.GetLoadedSharedModules)
@ -958,11 +1030,12 @@ namespace OpenSim
delegate(Scene scene) delegate(Scene scene)
{ {
MainConsole.Instance.Output(String.Format( MainConsole.Instance.Output(String.Format(
"Region Name: {0}, Region XLoc: {1}, Region YLoc: {2}, Region Port: {3}", "Region Name: {0}, Region XLoc: {1}, Region YLoc: {2}, Region Port: {3}, Estate Name: {4}",
scene.RegionInfo.RegionName, scene.RegionInfo.RegionName,
scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocX,
scene.RegionInfo.RegionLocY, scene.RegionInfo.RegionLocY,
scene.RegionInfo.InternalEndPoint.Port)); scene.RegionInfo.InternalEndPoint.Port,
scene.RegionInfo.EstateSettings.EstateName));
}); });
break; break;

View File

@ -795,9 +795,7 @@ namespace OpenSim
/// <summary> /// <summary>
/// Load the estate information for the provided RegionInfo object. /// Load the estate information for the provided RegionInfo object.
/// </summary> /// </summary>
/// <param name="regInfo"> /// <param name="regInfo"></param>
/// A <see cref="RegionInfo"/>
/// </param>
public void PopulateRegionEstateInfo(RegionInfo regInfo) public void PopulateRegionEstateInfo(RegionInfo regInfo)
{ {
IEstateDataService estateDataService = EstateDataService; IEstateDataService estateDataService = EstateDataService;
@ -819,7 +817,13 @@ namespace OpenSim
regInfo.EstateSettings = estateDataService.LoadEstateSettings(regInfo.RegionID, true); regInfo.EstateSettings = estateDataService.LoadEstateSettings(regInfo.RegionID, true);
regInfo.EstateSettings.EstateName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName); regInfo.EstateSettings.EstateName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName);
//regInfo.EstateSettings.Save();
// FIXME: Later on, the scene constructor will reload the estate settings no matter what.
// Therefore, we need to do an initial save here otherwise the new estate name will be reset
// back to the default. The reloading of estate settings by scene could be eliminated if it
// knows that the passed in settings in RegionInfo are already valid. Also, it might be
// possible to eliminate some additional later saves made by callers of this method.
regInfo.EstateSettings.Save();
break; break;
} }
else else

View File

@ -122,6 +122,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public int PacketsReceived; public int PacketsReceived;
/// <summary>Number of packets sent to this client</summary> /// <summary>Number of packets sent to this client</summary>
public int PacketsSent; public int PacketsSent;
/// <summary>Number of packets resent to this client</summary>
public int PacketsResent;
/// <summary>Total byte count of unacked packets sent to this client</summary> /// <summary>Total byte count of unacked packets sent to this client</summary>
public int UnackedBytes; public int UnackedBytes;
@ -256,9 +258,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public string GetStats() public string GetStats()
{ {
return string.Format( return string.Format(
"{0,7} {1,7} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}", "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}",
PacketsReceived,
PacketsSent, PacketsSent,
PacketsReceived, PacketsResent,
UnackedBytes, UnackedBytes,
m_packetOutboxes[(int)ThrottleOutPacketType.Resend].Count, m_packetOutboxes[(int)ThrottleOutPacketType.Resend].Count,
m_packetOutboxes[(int)ThrottleOutPacketType.Land].Count, m_packetOutboxes[(int)ThrottleOutPacketType.Land].Count,
@ -441,13 +444,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// an outgoing packet from each, obeying the throttling bucket limits /// an outgoing packet from each, obeying the throttling bucket limits
/// </summary> /// </summary>
/// ///
/// <remarks>
/// Packet queues are inspected in ascending numerical order starting from 0. Therefore, queues with a lower /// Packet queues are inspected in ascending numerical order starting from 0. Therefore, queues with a lower
/// ThrottleOutPacketType number will see their packet get sent first (e.g. if both Land and Wind queues have /// ThrottleOutPacketType number will see their packet get sent first (e.g. if both Land and Wind queues have
/// packets, then the packet at the front of the Land queue will be sent before the packet at the front of the /// packets, then the packet at the front of the Land queue will be sent before the packet at the front of the
/// wind queue). /// wind queue).
/// ///
/// <remarks>This function is only called from a synchronous loop in the /// This function is only called from a synchronous loop in the
/// UDPServer so we don't need to bother making this thread safe</remarks> /// UDPServer so we don't need to bother making this thread safe
/// </remarks>
///
/// <returns>True if any packets were sent, otherwise false</returns> /// <returns>True if any packets were sent, otherwise false</returns>
public bool DequeueOutgoing() public bool DequeueOutgoing()
{ {
@ -476,7 +482,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_udpServer.SendPacketFinal(nextPacket); m_udpServer.SendPacketFinal(nextPacket);
m_nextPackets[i] = null; m_nextPackets[i] = null;
packetSent = true; packetSent = true;
this.PacketsSent++;
} }
} }
else else
@ -493,7 +498,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Send the packet // Send the packet
m_udpServer.SendPacketFinal(packet); m_udpServer.SendPacketFinal(packet);
packetSent = true; packetSent = true;
this.PacketsSent++;
} }
else else
{ {

View File

@ -27,6 +27,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
@ -506,7 +507,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Bump up the resend count on this packet // Bump up the resend count on this packet
Interlocked.Increment(ref outgoingPacket.ResendCount); Interlocked.Increment(ref outgoingPacket.ResendCount);
//Interlocked.Increment(ref Stats.ResentPackets);
// Requeue or resend the packet // Requeue or resend the packet
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, false)) if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, false))
@ -582,6 +582,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
udpClient.NeedAcks.Add(outgoingPacket); udpClient.NeedAcks.Add(outgoingPacket);
} }
} }
else
{
Interlocked.Increment(ref udpClient.PacketsResent);
}
#endregion Sequence Number Assignment #endregion Sequence Number Assignment
@ -636,10 +640,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
object[] array = new object[] { buffer, packet }; object[] array = new object[] { buffer, packet };
if (m_asyncPacketHandling) Util.FireAndForget(HandleUseCircuitCode, array);
Util.FireAndForget(HandleUseCircuitCode, array);
else
HandleUseCircuitCode(array);
return; return;
} }
@ -856,10 +857,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Begin the process of adding the client to the simulator // Begin the process of adding the client to the simulator
AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint); AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint);
// Acknowledge the UseCircuitCode packet // Send ack
SendAckImmediate(remoteEndPoint, packet.Header.Sequence); SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
// m_log.DebugFormat( // m_log.DebugFormat(
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms", // "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds); // buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
} }
@ -923,25 +924,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo) protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
{ {
// Create the LLUDPClient // In priciple there shouldn't be more than one thread here, ever.
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); // But in case that happens, we need to synchronize this piece of code
IClientAPI existingClient; // because it's too important
lock (this)
if (!m_scene.TryGetClient(agentID, out existingClient))
{ {
// Create the LLClientView IClientAPI existingClient;
LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client.OnLogout += LogoutHandler;
client.DisableFacelights = m_disableFacelights; if (!m_scene.TryGetClient(agentID, out existingClient))
{
// Create the LLUDPClient
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
// Create the LLClientView
LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client.OnLogout += LogoutHandler;
// Start the IClientAPI client.DisableFacelights = m_disableFacelights;
client.Start();
} // Start the IClientAPI
else client.Start();
{
m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}", }
udpClient.AgentID, remoteEndPoint, circuitCode); else
{
m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}",
existingClient.AgentId, remoteEndPoint, circuitCode);
}
} }
} }
@ -1050,6 +1058,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion Update Timers #endregion Update Timers
// Use this for emergency monitoring -- bug hunting
//if (m_scene.EmergencyMonitoring)
// clientPacketHandler = MonitoredClientOutgoingPacketHandler;
//else
// clientPacketHandler = ClientOutgoingPacketHandler;
// Handle outgoing packets, resends, acknowledgements, and pings for each // Handle outgoing packets, resends, acknowledgements, and pings for each
// client. m_packetSent will be set to true if a packet is sent // client. m_packetSent will be set to true if a packet is sent
m_scene.ForEachClient(clientPacketHandler); m_scene.ForEachClient(clientPacketHandler);
@ -1065,6 +1079,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex); m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex);
} }
} }
Watchdog.RemoveThread(); Watchdog.RemoveThread();
@ -1102,6 +1117,112 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
} }
#region Emergency Monitoring
// Alternative packet handler fuull of instrumentation
// Handy for hunting bugs
private Stopwatch watch1 = new Stopwatch();
private Stopwatch watch2 = new Stopwatch();
private float avgProcessingTicks = 0;
private float avgResendUnackedTicks = 0;
private float avgSendAcksTicks = 0;
private float avgSendPingTicks = 0;
private float avgDequeueTicks = 0;
private long nticks = 0;
private long nticksUnack = 0;
private long nticksAck = 0;
private long nticksPing = 0;
private int npacksSent = 0;
private int npackNotSent = 0;
private void MonitoredClientOutgoingPacketHandler(IClientAPI client)
{
nticks++;
watch1.Start();
try
{
if (client is LLClientView)
{
LLUDPClient udpClient = ((LLClientView)client).UDPClient;
if (udpClient.IsConnected)
{
if (m_resendUnacked)
{
nticksUnack++;
watch2.Start();
ResendUnacked(udpClient);
watch2.Stop();
avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
watch2.Reset();
}
if (m_sendAcks)
{
nticksAck++;
watch2.Start();
SendAcks(udpClient);
watch2.Stop();
avgSendAcksTicks = (nticksAck - 1) / (float)nticksAck * avgSendAcksTicks + (watch2.ElapsedTicks / (float)nticksAck);
watch2.Reset();
}
if (m_sendPing)
{
nticksPing++;
watch2.Start();
SendPing(udpClient);
watch2.Stop();
avgSendPingTicks = (nticksPing - 1) / (float)nticksPing * avgSendPingTicks + (watch2.ElapsedTicks / (float)nticksPing);
watch2.Reset();
}
watch2.Start();
// Dequeue any outgoing packets that are within the throttle limits
if (udpClient.DequeueOutgoing())
{
m_packetSent = true;
npacksSent++;
}
else
npackNotSent++;
watch2.Stop();
avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks);
watch2.Reset();
}
else
m_log.WarnFormat("[LLUDPSERVER]: Client is not connected");
}
}
catch (Exception ex)
{
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name +
" threw an exception: " + ex.Message, ex);
}
watch1.Stop();
avgProcessingTicks = (nticks - 1) / (float)nticks * avgProcessingTicks + (watch1.ElapsedTicks / (float)nticks);
watch1.Reset();
// reuse this -- it's every ~100ms
if (m_scene.EmergencyMonitoring && nticks % 100 == 0)
{
m_log.InfoFormat("[LLUDPSERVER]: avg processing ticks: {0} avg unacked: {1} avg acks: {2} avg ping: {3} avg dequeue: {4} (TickCountRes: {5} sent: {6} notsent: {7})",
avgProcessingTicks, avgResendUnackedTicks, avgSendAcksTicks, avgSendPingTicks, avgDequeueTicks, TickCountResolution, npacksSent, npackNotSent);
npackNotSent = npacksSent = 0;
}
}
#endregion
private void ProcessInPacket(object state) private void ProcessInPacket(object state)
{ {
IncomingPacket incomingPacket = (IncomingPacket)state; IncomingPacket incomingPacket = (IncomingPacket)state;

View File

@ -210,6 +210,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
content = Math.Min(content + dripAmount, maxBurst); content = Math.Min(content + dripAmount, maxBurst);
lastDrip = now; lastDrip = now;
if (dripAmount < 0 || content < 0)
// sim has been idle for too long, integer has overflown
// previous calculation is meaningless, let's put it at correct max
content = maxBurst;
return true; return true;
} }
} }

View File

@ -143,7 +143,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Process all the pending adds // Process all the pending adds
OutgoingPacket pendingAdd; OutgoingPacket pendingAdd;
while (m_pendingAdds.TryDequeue(out pendingAdd)) while (m_pendingAdds.TryDequeue(out pendingAdd))
m_packets[pendingAdd.SequenceNumber] = pendingAdd; if (pendingAdd != null)
m_packets[pendingAdd.SequenceNumber] = pendingAdd;
// Process all the pending removes, including updating statistics and round-trip times // Process all the pending removes, including updating statistics and round-trip times
PendingAck pendingRemove; PendingAck pendingRemove;
@ -152,17 +153,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket)) if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket))
{ {
m_packets.Remove(pendingRemove.SequenceNumber); if (ackedPacket != null)
// Update stats
Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength);
if (!pendingRemove.FromResend)
{ {
// Calculate the round-trip time for this packet and its ACK m_packets.Remove(pendingRemove.SequenceNumber);
int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount;
if (rtt > 0) // Update stats
ackedPacket.Client.UpdateRoundTrip(rtt); Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength);
if (!pendingRemove.FromResend)
{
// Calculate the round-trip time for this packet and its ACK
int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount;
if (rtt > 0)
ackedPacket.Client.UpdateRoundTrip(rtt);
}
} }
} }
} }

View File

@ -26,12 +26,14 @@
*/ */
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using Caps=OpenSim.Framework.Capabilities.Caps; using Caps=OpenSim.Framework.Capabilities.Caps;
@ -61,6 +63,9 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities
{ {
m_scene = scene; m_scene = scene;
m_scene.RegisterModuleInterface<ICapabilitiesModule>(this); m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps",
"show capabilities",
"Shows all registered capabilities", CapabilitiesCommand);
} }
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)
@ -72,7 +77,9 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities
m_scene.UnregisterModuleInterface<ICapabilitiesModule>(this); m_scene.UnregisterModuleInterface<ICapabilitiesModule>(this);
} }
public void PostInitialise() {} public void PostInitialise()
{
}
public void Close() {} public void Close() {}
@ -226,5 +233,23 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities
m_log.Info(" >> "+x+", "+y+": "+kvp.Value); m_log.Info(" >> "+x+", "+y+": "+kvp.Value);
} }
} }
private void CapabilitiesCommand(string module, string[] cmdparams)
{
System.Text.StringBuilder caps = new System.Text.StringBuilder();
caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
foreach (KeyValuePair<UUID, Caps> kvp in m_capsHandlers)
{
caps.AppendFormat("** User {0}:\n", kvp.Key);
for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.CapsDetails.GetEnumerator(); kvp2.MoveNext(); )
{
Uri uri = new Uri(kvp2.Value.ToString());
caps.AppendFormat(" {0} = {1}\n", kvp2.Key, uri.PathAndQuery);
}
}
MainConsole.Instance.Output(caps.ToString());
}
} }
} }

View File

@ -245,14 +245,12 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps
WriteTextureData(httpRequest, httpResponse, texture, format); WriteTextureData(httpRequest, httpResponse, texture, format);
return true; return true;
} }
} }
// not found // not found
m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); // m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return true; return true;
} }
private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format) private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format)

View File

@ -128,6 +128,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
+ "<last> is the user's last name." + Environment.NewLine + "<last> is the user's last name." + Environment.NewLine
+ "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine + "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine
+ "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine + "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
+ "-c|--creators preserves information about foreign creators." + Environment.NewLine
+ "-v|--verbose extra debug messages." + Environment.NewLine + "-v|--verbose extra debug messages." + Environment.NewLine
+ "<IAR path> is the filesystem path at which to save the IAR." + "<IAR path> is the filesystem path at which to save the IAR."
+ string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
@ -396,6 +397,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
//ops.Add("v|version=", delegate(string v) { options["version"] = v; }); //ops.Add("v|version=", delegate(string v) { options["version"] = v; });
ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; });
ops.Add("c|creators", delegate(string v) { options["creators"] = v; });
List<string> mainParams = ops.Parse(cmdparams); List<string> mainParams = ops.Parse(cmdparams);

View File

@ -243,7 +243,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
catch (Exception e) catch (Exception e)
{ {
m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Exception on teleport: {0}\n{1}", e.Message, e.StackTrace); m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Exception on teleport: {0} {1}", e.Message, e.StackTrace);
sp.ControllingClient.SendTeleportFailed("Internal error"); sp.ControllingClient.SendTeleportFailed("Internal error");
} }
} }
@ -983,7 +983,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// </summary> /// </summary>
public void EnableChildAgent(ScenePresence sp, GridRegion region) public void EnableChildAgent(ScenePresence sp, GridRegion region)
{ {
m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighour {0}", region.RegionName); m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName);
AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); AgentCircuitData agent = sp.ControllingClient.RequestClientInfo();

View File

@ -55,6 +55,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
} }
private string m_ProfileServerURI; private string m_ProfileServerURI;
private bool m_OutboundPermission;
// private bool m_Initialized = false; // private bool m_Initialized = false;
@ -78,7 +79,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"];
if (thisModuleConfig != null) if (thisModuleConfig != null)
{
m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty); m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
}
else else
m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
} }
@ -103,7 +107,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel) public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
{ {
string userAssetServer = string.Empty; string userAssetServer = string.Empty;
if (IsForeignUser(avatarID, out userAssetServer)) if (IsForeignUser(avatarID, out userAssetServer) && m_OutboundPermission)
{ {
Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); }); Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
} }
@ -197,7 +201,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (IsForeignUser(sender, out userAssetServer)) if (IsForeignUser(sender, out userAssetServer))
m_assMapper.Get(item.AssetID, sender, userAssetServer); m_assMapper.Get(item.AssetID, sender, userAssetServer);
if (IsForeignUser(receiver, out userAssetServer)) if (IsForeignUser(receiver, out userAssetServer) && m_OutboundPermission)
m_assMapper.Post(item.AssetID, receiver, userAssetServer); m_assMapper.Post(item.AssetID, receiver, userAssetServer);
} }

View File

@ -47,7 +47,6 @@
<RegionModule id="RemoteAuthorizationServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization.RemoteAuthorizationServicesConnector" /> <RegionModule id="RemoteAuthorizationServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization.RemoteAuthorizationServicesConnector" />
<RegionModule id="HGAssetBroker" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.HGAssetBroker" /> <RegionModule id="HGAssetBroker" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.HGAssetBroker" />
<RegionModule id="LocalInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.LocalInventoryServicesConnector" /> <RegionModule id="LocalInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.LocalInventoryServicesConnector" />
<RegionModule id="RemoteInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.RemoteInventoryServicesConnector" />
<RegionModule id="RemoteXInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.RemoteXInventoryServicesConnector" /> <RegionModule id="RemoteXInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.RemoteXInventoryServicesConnector" />
<RegionModule id="HGInventoryBroker" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.HGInventoryBroker" /> <RegionModule id="HGInventoryBroker" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.HGInventoryBroker" />
<RegionModule id="LocalNeighbourServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour.LocalNeighbourServicesConnector" /> <RegionModule id="LocalNeighbourServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour.LocalNeighbourServicesConnector" />

View File

@ -139,7 +139,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
if (scene != null) if (scene != null)
{ {
UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, userID); UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID));
isAuthorized = IsAuthorizedForRegion(userID, account.FirstName, account.LastName, isAuthorized = IsAuthorizedForRegion(userID, account.FirstName, account.LastName,
account.Email, scene.RegionInfo.RegionName, regionID, out message); account.Email, scene.RegionInfo.RegionName, regionID, out message);
} }

View File

@ -247,13 +247,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public void NeighboursCommand(string module, string[] cmdparams) public void NeighboursCommand(string module, string[] cmdparams)
{ {
System.Text.StringBuilder caps = new System.Text.StringBuilder();
foreach (KeyValuePair<UUID, RegionCache> kvp in m_LocalCache) foreach (KeyValuePair<UUID, RegionCache> kvp in m_LocalCache)
{ {
m_log.InfoFormat("*** Neighbours of {0} {1} ***", kvp.Key, kvp.Value.RegionName); caps.AppendFormat("*** Neighbours of {0} ({1}) ***\n", kvp.Value.RegionName, kvp.Key);
List<GridRegion> regions = kvp.Value.GetNeighbours(); List<GridRegion> regions = kvp.Value.GetNeighbours();
foreach (GridRegion r in regions) foreach (GridRegion r in regions)
m_log.InfoFormat(" {0} @ {1}={2}", r.RegionName, r.RegionLocX / Constants.RegionSize, r.RegionLocY / Constants.RegionSize); caps.AppendFormat(" {0} @ {1}-{2}\n", r.RegionName, r.RegionLocX / Constants.RegionSize, r.RegionLocY / Constants.RegionSize);
} }
MainConsole.Instance.Output(caps.ToString());
} }
} }

View File

@ -200,6 +200,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return; return;
} }
} }
else
{
m_log.DebugFormat("[HG INVENTORY CONNECTOR]: User {0} does not have InventoryServerURI. OH NOES!", userID);
return;
}
} }
} }
} }

View File

@ -1,362 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using log4net;
using System;
using System.Collections.Generic;
using System.Reflection;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Statistics;
using OpenSim.Services.Connectors;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
{
public class RemoteInventoryServicesConnector : BaseInventoryConnector, ISharedRegionModule, IInventoryService
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private bool m_Enabled = false;
private bool m_Initialized = false;
private Scene m_Scene;
private InventoryServicesConnector m_RemoteConnector;
private IUserManagement m_UserManager;
private IUserManagement UserManager
{
get
{
if (m_UserManager == null)
{
m_UserManager = m_Scene.RequestModuleInterface<IUserManagement>();
}
return m_UserManager;
}
}
public Type ReplaceableInterface
{
get { return null; }
}
public string Name
{
get { return "RemoteInventoryServicesConnector"; }
}
public RemoteInventoryServicesConnector()
{
}
public RemoteInventoryServicesConnector(IConfigSource source)
{
Init(source);
}
protected override void Init(IConfigSource source)
{
m_RemoteConnector = new InventoryServicesConnector(source);
base.Init(source);
}
#region ISharedRegionModule
public void Initialise(IConfigSource source)
{
IConfig moduleConfig = source.Configs["Modules"];
if (moduleConfig != null)
{
string name = moduleConfig.GetString("InventoryServices", "");
if (name == Name)
{
Init(source);
m_Enabled = true;
m_log.Info("[INVENTORY CONNECTOR]: Remote inventory enabled");
}
}
}
public void PostInitialise()
{
}
public void Close()
{
}
public void AddRegion(Scene scene)
{
// m_Scene = scene;
//m_log.Debug("[XXXX] Adding scene " + m_Scene.RegionInfo.RegionName);
if (!m_Enabled)
return;
if (!m_Initialized)
{
m_Initialized = true;
}
scene.RegisterModuleInterface<IInventoryService>(this);
m_cache.AddRegion(scene);
if (m_Scene == null)
m_Scene = scene;
}
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
m_cache.RemoveRegion(scene);
}
public void RegionLoaded(Scene scene)
{
if (!m_Enabled)
return;
m_log.InfoFormat("[INVENTORY CONNECTOR]: Enabled remote inventory for region {0}", scene.RegionInfo.RegionName);
}
#endregion ISharedRegionModule
#region IInventoryService
public override bool CreateUserInventory(UUID user)
{
return false;
}
public override List<InventoryFolderBase> GetInventorySkeleton(UUID userId)
{
return new List<InventoryFolderBase>();
}
public override InventoryCollection GetUserInventory(UUID userID)
{
return null;
}
public override void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
{
UUID sessionID = GetSessionID(userID);
try
{
m_RemoteConnector.GetUserInventory(userID.ToString(), sessionID, callback);
}
catch (Exception e)
{
if (StatsManager.SimExtraStats != null)
StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure();
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Request inventory operation failed, {0} {1}",
e.Source, e.Message);
}
}
// inherited. See base class
// public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
public override Dictionary<AssetType, InventoryFolderBase> GetSystemFolders(UUID userID)
{
UUID sessionID = GetSessionID(userID);
return m_RemoteConnector.GetSystemFolders(userID.ToString(), sessionID);
}
public override InventoryCollection GetFolderContent(UUID userID, UUID folderID)
{
UUID sessionID = GetSessionID(userID);
try
{
InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID.ToString(), folderID, sessionID);
foreach (InventoryItemBase item in invCol.Items)
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
return invCol;
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetFolderContent operation failed, {0} {1}",
e.Source, e.Message);
}
InventoryCollection nullCollection = new InventoryCollection();
nullCollection.Folders = new List<InventoryFolderBase>();
nullCollection.Items = new List<InventoryItemBase>();
nullCollection.UserID = userID;
return nullCollection;
}
public override List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
{
UUID sessionID = GetSessionID(userID);
return m_RemoteConnector.GetFolderItems(userID.ToString(), folderID, sessionID);
}
public override bool AddFolder(InventoryFolderBase folder)
{
if (folder == null)
return false;
UUID sessionID = GetSessionID(folder.Owner);
return m_RemoteConnector.AddFolder(folder.Owner.ToString(), folder, sessionID);
}
public override bool UpdateFolder(InventoryFolderBase folder)
{
if (folder == null)
return false;
UUID sessionID = GetSessionID(folder.Owner);
return m_RemoteConnector.UpdateFolder(folder.Owner.ToString(), folder, sessionID);
}
public override bool MoveFolder(InventoryFolderBase folder)
{
if (folder == null)
return false;
UUID sessionID = GetSessionID(folder.Owner);
return m_RemoteConnector.MoveFolder(folder.Owner.ToString(), folder, sessionID);
}
public override bool DeleteFolders(UUID ownerID, List<UUID> folderIDs)
{
if (folderIDs == null)
return false;
if (folderIDs.Count == 0)
return false;
UUID sessionID = GetSessionID(ownerID);
return m_RemoteConnector.DeleteFolders(ownerID.ToString(), folderIDs, sessionID);
}
public override bool PurgeFolder(InventoryFolderBase folder)
{
if (folder == null)
return false;
UUID sessionID = GetSessionID(folder.Owner);
return m_RemoteConnector.PurgeFolder(folder.Owner.ToString(), folder, sessionID);
}
// public bool AddItem(InventoryItemBase item) inherited
// Uses AddItemPlain
protected override bool AddItemPlain(InventoryItemBase item)
{
if (item == null)
return false;
UUID sessionID = GetSessionID(item.Owner);
return m_RemoteConnector.AddItem(item.Owner.ToString(), item, sessionID);
}
public override bool UpdateItem(InventoryItemBase item)
{
if (item == null)
return false;
UUID sessionID = GetSessionID(item.Owner);
return m_RemoteConnector.UpdateItem(item.Owner.ToString(), item, sessionID);
}
public override bool MoveItems(UUID ownerID, List<InventoryItemBase> items)
{
if (items == null)
return false;
UUID sessionID = GetSessionID(ownerID);
return m_RemoteConnector.MoveItems(ownerID.ToString(), items, sessionID);
}
public override bool DeleteItems(UUID ownerID, List<UUID> itemIDs)
{
if (itemIDs == null)
return false;
if (itemIDs.Count == 0)
return true;
UUID sessionID = GetSessionID(ownerID);
return m_RemoteConnector.DeleteItems(ownerID.ToString(), itemIDs, sessionID);
}
public override InventoryItemBase GetItem(InventoryItemBase item)
{
if (item == null)
return null;
UUID sessionID = GetSessionID(item.Owner);
return m_RemoteConnector.QueryItem(item.Owner.ToString(), item, sessionID);
}
public override InventoryFolderBase GetFolder(InventoryFolderBase folder)
{
if (folder == null)
return null;
UUID sessionID = GetSessionID(folder.Owner);
return m_RemoteConnector.QueryFolder(folder.Owner.ToString(), folder, sessionID);
}
public override bool HasInventoryForUser(UUID userID)
{
return false;
}
public override List<InventoryItemBase> GetActiveGestures(UUID userId)
{
return new List<InventoryItemBase>();
}
public override int GetAssetPermissions(UUID userID, UUID assetID)
{
UUID sessionID = GetSessionID(userID);
return m_RemoteConnector.GetAssetPermissions(userID.ToString(), assetID, sessionID);
}
#endregion
private UUID GetSessionID(UUID userID)
{
return UUID.Zero;
}
}
}

View File

@ -225,17 +225,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
if (destination == null) if (destination == null)
return false; return false;
// We limit the number of messages sent for a position change to just one per
// simulator so when we receive the update we need to hand it to each of the
// scenes; scenes each check to see if the is a scene presence for the avatar
// note that we really don't need the GridRegion for this call
foreach (Scene s in m_sceneList) foreach (Scene s in m_sceneList)
{ {
if (s.RegionInfo.RegionHandle == destination.RegionHandle) //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
{ s.IncomingChildAgentDataUpdate(cAgentData);
//m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
s.IncomingChildAgentDataUpdate(cAgentData);
return true;
}
} }
//m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate");
return false; return true;
} }
public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent) public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent)

View File

@ -0,0 +1,224 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Security;
using System.Text;
using log4net;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.CoreModules.World.Estate
{
/// <summary>
/// Estate management console commands.
/// </summary>
public class EstateManagementCommands
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected EstateManagementModule m_module;
protected Commander m_commander = new Commander("estate");
public EstateManagementCommands(EstateManagementModule module)
{
m_module = module;
}
public void Initialise()
{
m_log.DebugFormat("[ESTATE MODULE]: Setting up estate commands for region {0}", m_module.Scene.RegionInfo.RegionName);
m_module.Scene.AddCommand(m_module, "set terrain texture",
"set terrain texture <number> <uuid> [<x>] [<y>]",
"Sets the terrain <number> to <uuid>, if <x> or <y> are specified, it will only " +
"set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" +
" that coordinate.",
consoleSetTerrainTexture);
m_module.Scene.AddCommand(m_module, "set terrain heights",
"set terrain heights <corner> <min> <max> [<x>] [<y>]",
"Sets the terrain texture heights on corner #<corner> to <min>/<max>, if <x> or <y> are specified, it will only " +
"set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" +
" that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3.",
consoleSetTerrainHeights);
Command showCommand
= new Command("show", CommandIntentions.COMMAND_STATISTICAL, ShowEstatesCommand, "Shows all estates on the simulator.");
m_commander.RegisterCommand("show", showCommand);
m_module.Scene.RegisterModuleCommander(m_commander);
m_module.Scene.EventManager.OnPluginConsole += EventManagerOnPluginConsole;
}
public void Close()
{
m_module.Scene.EventManager.OnPluginConsole -= EventManagerOnPluginConsole;
m_module.Scene.UnregisterModuleCommander(m_commander.Name);
}
/// <summary>
/// Processes commandline input. Do not call directly.
/// </summary>
/// <param name="args">Commandline arguments</param>
protected void EventManagerOnPluginConsole(string[] args)
{
if (args[0] == "estate")
{
if (args.Length == 1)
{
m_commander.ProcessConsoleCommand("help", new string[0]);
return;
}
string[] tmpArgs = new string[args.Length - 2];
int i;
for (i = 2; i < args.Length; i++)
tmpArgs[i - 2] = args[i];
m_commander.ProcessConsoleCommand(args[1], tmpArgs);
}
}
protected void consoleSetTerrainTexture(string module, string[] args)
{
string num = args[3];
string uuid = args[4];
int x = (args.Length > 5 ? int.Parse(args[5]) : -1);
int y = (args.Length > 6 ? int.Parse(args[6]) : -1);
if (x == -1 || m_module.Scene.RegionInfo.RegionLocX == x)
{
if (y == -1 || m_module.Scene.RegionInfo.RegionLocY == y)
{
int corner = int.Parse(num);
UUID texture = UUID.Parse(uuid);
m_log.Debug("[ESTATEMODULE]: Setting terrain textures for " + m_module.Scene.RegionInfo.RegionName +
string.Format(" (C#{0} = {1})", corner, texture));
switch (corner)
{
case 0:
m_module.Scene.RegionInfo.RegionSettings.TerrainTexture1 = texture;
break;
case 1:
m_module.Scene.RegionInfo.RegionSettings.TerrainTexture2 = texture;
break;
case 2:
m_module.Scene.RegionInfo.RegionSettings.TerrainTexture3 = texture;
break;
case 3:
m_module.Scene.RegionInfo.RegionSettings.TerrainTexture4 = texture;
break;
}
m_module.Scene.RegionInfo.RegionSettings.Save();
m_module.TriggerRegionInfoChange();
m_module.sendRegionInfoPacketToAll();
}
}
}
protected void consoleSetTerrainHeights(string module, string[] args)
{
string num = args[3];
string min = args[4];
string max = args[5];
int x = (args.Length > 6 ? int.Parse(args[6]) : -1);
int y = (args.Length > 7 ? int.Parse(args[7]) : -1);
if (x == -1 || m_module.Scene.RegionInfo.RegionLocX == x)
{
if (y == -1 || m_module.Scene.RegionInfo.RegionLocY == y)
{
int corner = int.Parse(num);
float lowValue = float.Parse(min, Culture.NumberFormatInfo);
float highValue = float.Parse(max, Culture.NumberFormatInfo);
m_log.Debug("[ESTATEMODULE]: Setting terrain heights " + m_module.Scene.RegionInfo.RegionName +
string.Format(" (C{0}, {1}-{2}", corner, lowValue, highValue));
switch (corner)
{
case 0:
m_module.Scene.RegionInfo.RegionSettings.Elevation1SW = lowValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation2SW = highValue;
break;
case 1:
m_module.Scene.RegionInfo.RegionSettings.Elevation1NW = lowValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation2NW = highValue;
break;
case 2:
m_module.Scene.RegionInfo.RegionSettings.Elevation1SE = lowValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation2SE = highValue;
break;
case 3:
m_module.Scene.RegionInfo.RegionSettings.Elevation1NE = lowValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation2NE = highValue;
break;
}
m_module.Scene.RegionInfo.RegionSettings.Save();
m_module.TriggerRegionInfoChange();
m_module.sendRegionHandshakeToAll();
}
}
}
protected void ShowEstatesCommand(Object[] args)
{
StringBuilder report = new StringBuilder();
RegionInfo ri = m_module.Scene.RegionInfo;
EstateSettings es = ri.EstateSettings;
report.AppendFormat("Estate information for region {0}\n", ri.RegionName);
report.AppendFormat(
"{0,-20} {1,-7} {2,-20}\n",
"Estate Name",
"ID",
"Owner");
report.AppendFormat(
"{0,-20} {1,-7} {2,-20}\n",
es.EstateName, es.EstateID, m_module.UserManager.GetUserName(es.EstateOwner));
MainConsole.Instance.Output(report.ToString());
}
}
}

View File

@ -764,10 +764,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
if (!responseMap.ContainsKey(itemtype.ToString())) // remote sim doesnt have the stated region handle if (!responseMap.ContainsKey(itemtype.ToString())) // remote sim doesnt have the stated region handle
{ {
if (!m_blacklistedregions.ContainsKey(regionhandle)) m_log.DebugFormat("[WORLD MAP]: Remote sim does not have the stated region. Blacklisting.");
lock (m_blacklistedregions)
{ {
m_log.DebugFormat("[WORLD MAP]: Remote sim does not have the stated region. Blacklisting."); if (!m_blacklistedregions.ContainsKey(regionhandle))
m_blacklistedregions.Add(regionhandle, Environment.TickCount); m_blacklistedregions.Add(regionhandle, Environment.TickCount);
} }
} }

View File

@ -32,7 +32,7 @@ namespace OpenSim.Region.Framework.Interfaces
public delegate void ChangeDelegate(UUID regionID); public delegate void ChangeDelegate(UUID regionID);
public delegate void MessageDelegate(UUID regionID, UUID fromID, string fromName, string message); public delegate void MessageDelegate(UUID regionID, UUID fromID, string fromName, string message);
public interface IEstateModule : IRegionModule public interface IEstateModule
{ {
event ChangeDelegate OnRegionInfoChange; event ChangeDelegate OnRegionInfoChange;
event ChangeDelegate OnEstateInfoChange; event ChangeDelegate OnEstateInfoChange;

View File

@ -36,5 +36,6 @@ namespace OpenSim.Region.Framework.Interfaces
void Close(); void Close();
void QueuePartForUpdate(SceneObjectPart part); void QueuePartForUpdate(SceneObjectPart part);
void SendPrimUpdates(); void SendPrimUpdates();
int GetPendingObjectsCount();
} }
} }

View File

@ -64,6 +64,8 @@ namespace OpenSim.Region.Framework.Scenes
#region Fields #region Fields
public bool EmergencyMonitoring = false;
public SynchronizeSceneHandler SynchronizeScene; public SynchronizeSceneHandler SynchronizeScene;
public SimStatsReporter StatsReporter; public SimStatsReporter StatsReporter;
public List<Border> NorthBorders = new List<Border>(); public List<Border> NorthBorders = new List<Border>();

View File

@ -193,7 +193,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public delegate void SendChildAgentDataUpdateDelegate(AgentPosition cAgentData, UUID scopeID, ulong regionHandle); public delegate void SendChildAgentDataUpdateDelegate(AgentPosition cAgentData, UUID scopeID, GridRegion dest);
/// <summary> /// <summary>
/// This informs all neighboring regions about the settings of it's child agent. /// This informs all neighboring regions about the settings of it's child agent.
@ -202,31 +203,17 @@ namespace OpenSim.Region.Framework.Scenes
/// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc. /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc.
/// ///
/// </summary> /// </summary>
private void SendChildAgentDataUpdateAsync(AgentPosition cAgentData, UUID scopeID, ulong regionHandle) private void SendChildAgentDataUpdateAsync(AgentPosition cAgentData, UUID scopeID, GridRegion dest)
{ {
//m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName); //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName);
try try
{ {
//m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); m_scene.SimulationService.UpdateAgent(dest, cAgentData);
uint x = 0, y = 0;
Utils.LongToUInts(regionHandle, out x, out y);
GridRegion destination = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
m_scene.SimulationService.UpdateAgent(destination, cAgentData);
} }
catch catch
{ {
// Ignore; we did our best // Ignore; we did our best
} }
//if (regionAccepted)
//{
// //m_log.Info("[INTERGRID]: Completed sending a neighbor an update about my agent");
//}
//else
//{
// //m_log.Info("[INTERGRID]: Failed sending a neighbor an update about my agent");
//}
} }
private void SendChildAgentDataUpdateCompleted(IAsyncResult iar) private void SendChildAgentDataUpdateCompleted(IAsyncResult iar)
@ -240,14 +227,28 @@ namespace OpenSim.Region.Framework.Scenes
// This assumes that we know what our neighbors are. // This assumes that we know what our neighbors are.
try try
{ {
uint x = 0, y = 0;
List<string> simulatorList = new List<string>();
foreach (ulong regionHandle in presence.KnownChildRegionHandles) foreach (ulong regionHandle in presence.KnownChildRegionHandles)
{ {
if (regionHandle != m_regionInfo.RegionHandle) if (regionHandle != m_regionInfo.RegionHandle)
{ {
SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync; // we only want to send one update to each simulator; the simulator will
d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, regionHandle, // hand it off to the regions where a child agent exists, this does assume
SendChildAgentDataUpdateCompleted, // that the region position is cached or performance will degrade
d); Utils.LongToUInts(regionHandle, out x, out y);
GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
if (! simulatorList.Contains(dest.ServerURI))
{
// we havent seen this simulator before, add it to the list
// and send it an update
simulatorList.Add(dest.ServerURI);
SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync;
d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, dest,
SendChildAgentDataUpdateCompleted,
d);
}
} }
} }
} }

View File

@ -2055,8 +2055,9 @@ namespace OpenSim.Region.Framework.Scenes
public void GetProperties(IClientAPI client) public void GetProperties(IClientAPI client)
{ {
//Viewer wants date in microseconds so multiply it by 1,000,000.
client.SendObjectPropertiesReply( client.SendObjectPropertiesReply(
m_fromUserInventoryItemID, (ulong)_creationDate, _creatorID, UUID.Zero, UUID.Zero, m_fromUserInventoryItemID, (ulong)_creationDate*(ulong)1e6, _creatorID, UUID.Zero, UUID.Zero,
_groupID, (short)InventorySerial, _lastOwnerID, UUID, _ownerID, _groupID, (short)InventorySerial, _lastOwnerID, UUID, _ownerID,
ParentGroup.RootPart.TouchName, new byte[0], ParentGroup.RootPart.SitName, Name, Description, ParentGroup.RootPart.TouchName, new byte[0], ParentGroup.RootPart.SitName, Name, Description,
ParentGroup.RootPart._ownerMask, ParentGroup.RootPart._nextOwnerMask, ParentGroup.RootPart._groupMask, ParentGroup.RootPart._everyoneMask, ParentGroup.RootPart._ownerMask, ParentGroup.RootPart._nextOwnerMask, ParentGroup.RootPart._groupMask, ParentGroup.RootPart._everyoneMask,

View File

@ -205,6 +205,14 @@ namespace OpenSim.Region.Framework.Scenes
Reset(); Reset();
} }
public int GetPendingObjectsCount()
{
if (m_pendingObjects != null)
return m_pendingObjects.Count;
return 0;
}
public class ScenePartUpdate public class ScenePartUpdate
{ {
public UUID FullID; public UUID FullID;

View File

@ -95,7 +95,15 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
"Show throttle settings for each client and for the server overall", "Show throttle settings for each client and for the server overall",
"Without the 'full' option, only root agents are shown." "Without the 'full' option, only root agents are shown."
+ " With the 'full' option child agents are also shown.", + " With the 'full' option child agents are also shown.",
ShowThrottlesReport); ShowThrottlesReport);
scene.AddCommand(
this, "emergency-monitoring",
"Go on/off emergency monitoring mode",
"Go on/off emergency monitoring mode",
"Go on/off emergency monitoring mode",
EmergencyMonitoring);
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
@ -120,7 +128,25 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
{ {
MainConsole.Instance.Output(GetThrottlesReport(cmd)); MainConsole.Instance.Output(GetThrottlesReport(cmd));
} }
protected void EmergencyMonitoring(string module, string[] cmd)
{
bool mode = true;
if (cmd.Length == 1 || (cmd.Length > 1 && cmd[1] == "on"))
{
mode = true;
MainConsole.Instance.Output("Emergency Monitoring ON");
}
else
{
mode = false;
MainConsole.Instance.Output("Emergency Monitoring OFF");
}
foreach (Scene s in m_scenes.Values)
s.EmergencyMonitoring = mode;
}
protected string GetColumnEntry(string entry, int maxLength, int columnPadding) protected string GetColumnEntry(string entry, int maxLength, int columnPadding)
{ {
return string.Format( return string.Format(
@ -154,24 +180,26 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding)); report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding));
report.AppendFormat( report.AppendFormat(
"{0,7} {1,7} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}\n", "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}\n",
"Pkts", "Pkts",
"Pkts", "Pkts",
"Pkts",
"Bytes", "Bytes",
"Pkts", "Q Pkts",
"Pkts", "Q Pkts",
"Pkts", "Q Pkts",
"Pkts", "Q Pkts",
"Pkts", "Q Pkts",
"Pkts", "Q Pkts",
"Pkts", "Q Pkts",
"Pkts"); "Q Pkts");
report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", ""); report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", "");
report.AppendFormat( report.AppendFormat(
"{0,7} {1,7} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}\n", "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}\n",
"Out",
"In", "In",
"Out",
"Resent",
"Unacked", "Unacked",
"Resend", "Resend",
"Land", "Land",
@ -333,7 +361,7 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
ThrottleRates throttleRates = udpServer.ThrottleRates; ThrottleRates throttleRates = udpServer.ThrottleRates;
report.AppendFormat( report.AppendFormat(
"{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}", "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}",
"n/a", (throttleRates.Total * 8) / 1000,
(throttleRates.ResendLimit * 8) / 1000, (throttleRates.ResendLimit * 8) / 1000,
(throttleRates.LandLimit * 8) / 1000, (throttleRates.LandLimit * 8) / 1000,
(throttleRates.WindLimit * 8) / 1000, (throttleRates.WindLimit * 8) / 1000,

View File

@ -63,7 +63,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
void SetAgentActiveGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); void SetAgentActiveGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID);
void SetAgentGroupInfo(UUID RequestingAgentID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); void SetAgentGroupInfo(UUID RequestingAgentID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile);
/// <summary>
/// Get information about a specific group to which the user belongs.
/// </summary>
/// <param name="RequestingAgentID">The agent requesting the information.</param>
/// <param name="AgentID">The agent requested.</param>
/// <param name="GroupID">The group requested.</param>
/// <returns>
/// If the user is a member of the group then the data structure is returned. If not, then null is returned.
/// </returns>
GroupMembershipData GetAgentGroupMembership(UUID RequestingAgentID, UUID AgentID, UUID GroupID); GroupMembershipData GetAgentGroupMembership(UUID RequestingAgentID, UUID AgentID, UUID GroupID);
/// <summary>
/// Get information about the groups to which a user belongs.
/// </summary>
/// <param name="RequestingAgentID">The agent requesting the information.</param>
/// <param name="AgentID">The agent requested.</param>
/// <returns>
/// Information about the groups to which the user belongs. If the user belongs to no groups then an empty
/// list is returned.
/// </returns>
List<GroupMembershipData> GetAgentGroupMemberships(UUID RequestingAgentID, UUID AgentID); List<GroupMembershipData> GetAgentGroupMemberships(UUID RequestingAgentID, UUID AgentID);
void AddGroupNotice(UUID RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); void AddGroupNotice(UUID RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket);

View File

@ -704,7 +704,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
} }
} }
return findings; return findings;
} }
@ -712,54 +711,55 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
{ {
if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
GroupMembershipData data = new GroupMembershipData(); GroupMembershipData data = null;
bool foundData = false;
///////////////////////////////
// Agent Specific Information:
//
OSDMap UserActiveGroup;
if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup))
{
data.Active = UserActiveGroup["GroupID"].AsUUID().Equals(groupID);
}
OSDMap UserGroupMemberInfo; OSDMap UserGroupMemberInfo;
if (SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out UserGroupMemberInfo)) if (SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out UserGroupMemberInfo))
{ {
data = new GroupMembershipData();
data.AcceptNotices = UserGroupMemberInfo["AcceptNotices"].AsBoolean(); data.AcceptNotices = UserGroupMemberInfo["AcceptNotices"].AsBoolean();
data.Contribution = UserGroupMemberInfo["Contribution"].AsInteger(); data.Contribution = UserGroupMemberInfo["Contribution"].AsInteger();
data.ListInProfile = UserGroupMemberInfo["ListInProfile"].AsBoolean(); data.ListInProfile = UserGroupMemberInfo["ListInProfile"].AsBoolean();
data.ActiveRole = UserGroupMemberInfo["SelectedRoleID"].AsUUID(); data.ActiveRole = UserGroupMemberInfo["SelectedRoleID"].AsUUID();
///////////////////////////////
// Agent Specific Information:
//
OSDMap UserActiveGroup;
if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup))
{
data.Active = UserActiveGroup["GroupID"].AsUUID().Equals(groupID);
}
/////////////////////////////// ///////////////////////////////
// Role Specific Information: // Role Specific Information:
// //
OSDMap GroupRoleInfo; OSDMap GroupRoleInfo;
if (SimianGetGenericEntry(groupID, "GroupRole", data.ActiveRole.ToString(), out GroupRoleInfo)) if (SimianGetGenericEntry(groupID, "GroupRole", data.ActiveRole.ToString(), out GroupRoleInfo))
{ {
data.GroupTitle = GroupRoleInfo["Title"].AsString(); data.GroupTitle = GroupRoleInfo["Title"].AsString();
data.GroupPowers = GroupRoleInfo["Powers"].AsULong(); data.GroupPowers = GroupRoleInfo["Powers"].AsULong();
} }
}
///////////////////////////////
/////////////////////////////// // Group Specific Information:
// Group Specific Information: //
// OSDMap GroupInfo;
OSDMap GroupInfo; string GroupName;
string GroupName; if (SimianGetFirstGenericEntry(groupID, "Group", out GroupName, out GroupInfo))
if (SimianGetFirstGenericEntry(groupID, "Group", out GroupName, out GroupInfo)) {
{ data.GroupID = groupID;
data.GroupID = groupID; data.AllowPublish = GroupInfo["AllowPublish"].AsBoolean();
data.AllowPublish = GroupInfo["AllowPublish"].AsBoolean(); data.Charter = GroupInfo["Charter"].AsString();
data.Charter = GroupInfo["Charter"].AsString(); data.FounderID = GroupInfo["FounderID"].AsUUID();
data.FounderID = GroupInfo["FounderID"].AsUUID(); data.GroupName = GroupName;
data.GroupName = GroupName; data.GroupPicture = GroupInfo["InsigniaID"].AsUUID();
data.GroupPicture = GroupInfo["InsigniaID"].AsUUID(); data.MaturePublish = GroupInfo["MaturePublish"].AsBoolean();
data.MaturePublish = GroupInfo["MaturePublish"].AsBoolean(); data.MembershipFee = GroupInfo["MembershipFee"].AsInteger();
data.MembershipFee = GroupInfo["MembershipFee"].AsInteger(); data.OpenEnrollment = GroupInfo["OpenEnrollment"].AsBoolean();
data.OpenEnrollment = GroupInfo["OpenEnrollment"].AsBoolean(); data.ShowInList = GroupInfo["ShowInList"].AsBoolean();
data.ShowInList = GroupInfo["ShowInList"].AsBoolean(); }
} }
return data; return data;

View File

@ -71,6 +71,9 @@ namespace OpenSim.Region.OptionalModules.World.WorldView
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)
{ {
if (!m_Enabled)
return;
m_Generator = scene.RequestModuleInterface<IMapImageGenerator>(); m_Generator = scene.RequestModuleInterface<IMapImageGenerator>();
if (m_Generator == null) if (m_Generator == null)
{ {

View File

@ -1748,15 +1748,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
protected void SetTexture(SceneObjectPart part, string texture, int face) protected void SetTexture(SceneObjectPart part, string texture, int face)
{ {
UUID textureID=new UUID(); UUID textureID = new UUID();
if (!UUID.TryParse(texture, out textureID)) textureID = InventoryKey(texture, (int)AssetType.Texture);
{ if (textureID == UUID.Zero)
textureID=InventoryKey(texture, (int)AssetType.Texture); {
} if (!UUID.TryParse(texture, out textureID))
return;
if (textureID == UUID.Zero) }
return;
Primitive.TextureEntry tex = part.Shape.Textures; Primitive.TextureEntry tex = part.Shape.Textures;
@ -3062,14 +3061,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
msg.fromGroup = false;// fromGroup; msg.fromGroup = false;// fromGroup;
msg.offline = (byte)0; //offline; msg.offline = (byte)0; //offline;
msg.ParentEstateID = 0; //ParentEstateID; msg.ParentEstateID = 0; //ParentEstateID;
msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); msg.Position = new Vector3(m_host.AbsolutePosition);
msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
msg.binaryBucket = new byte[0];// binaryBucket; msg.binaryBucket
= Util.StringToBytes256(
"{0}/{1}/{2}/{3}",
World.RegionInfo.RegionName,
(int)Math.Floor(m_host.AbsolutePosition.X),
(int)Math.Floor(m_host.AbsolutePosition.Y),
(int)Math.Floor(m_host.AbsolutePosition.Z));
if (m_TransferModule != null) if (m_TransferModule != null)
{ {
m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
} }
ScriptSleep(2000); ScriptSleep(2000);
} }

View File

@ -702,7 +702,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// and convert the regionName to the target region // and convert the regionName to the target region
if (regionName.Contains(".") && regionName.Contains(":")) if (regionName.Contains(".") && regionName.Contains(":"))
{ {
// List<GridRegion> regions = World.GridService.GetRegionsByName(World.RegionInfo.ScopeID, regionName, 1); // Even though we use none of the results, we need to perform this call because it appears
// to have some the side effect of setting up hypergrid teleport locations.
World.GridService.GetRegionsByName(World.RegionInfo.ScopeID, regionName, 1);
// List<GridRegion> regions = World.GridService.GetRegionsByName(World.RegionInfo.ScopeID, regionName, 1);
string[] parts = regionName.Split(new char[] { ':' }); string[] parts = regionName.Split(new char[] { ':' });
if (parts.Length > 2) if (parts.Length > 2)
regionName = parts[0] + ':' + parts[1] + "/ " + parts[2]; regionName = parts[0] + ':' + parts[1] + "/ " + parts[2];

View File

@ -110,7 +110,7 @@ namespace OpenSim.Server.Handlers.Simulation
DoAgentDelete(request, responsedata, agentID, action, regionID); DoAgentDelete(request, responsedata, agentID, action, regionID);
return responsedata; return responsedata;
} }
else if (method.Equals("QUERYACCESSS")) else if (method.Equals("QUERYACCESS"))
{ {
DoQueryAccess(request, responsedata, agentID, regionID); DoQueryAccess(request, responsedata, agentID, regionID);
return responsedata; return responsedata;
@ -200,6 +200,11 @@ namespace OpenSim.Server.Handlers.Simulation
// We're behind a proxy // We're behind a proxy
Hashtable headers = (Hashtable)request["headers"]; Hashtable headers = (Hashtable)request["headers"];
//// DEBUG
//foreach (object o in headers.Keys)
// m_log.DebugFormat("XXX {0} = {1}", o.ToString(), (headers[o] == null? "null" : headers[o].ToString()));
string xff = "X-Forwarded-For"; string xff = "X-Forwarded-For";
if (headers.ContainsKey(xff.ToLower())) if (headers.ContainsKey(xff.ToLower()))
xff = xff.ToLower(); xff = xff.ToLower();

View File

@ -1,335 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using log4net;
using Nini.Config;
using System;
using System.Collections.Generic;
using System.Reflection;
using OpenSim.Framework;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
namespace OpenSim.Services.Connectors.Inventory
{
public class HGInventoryServiceConnector : ISessionAuthInventoryService
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private Dictionary<string, InventoryServicesConnector> m_connectors = new Dictionary<string, InventoryServicesConnector>();
public HGInventoryServiceConnector(IConfigSource source)
{
IConfig moduleConfig = source.Configs["Modules"];
if (moduleConfig != null)
{
IConfig inventoryConfig = source.Configs["InventoryService"];
if (inventoryConfig == null)
{
m_log.Error("[HG INVENTORY SERVICE]: InventoryService missing from OpenSim.ini");
return;
}
m_log.Info("[HG INVENTORY SERVICE]: HG inventory service enabled");
}
}
private bool StringToUrlAndUserID(string id, out string url, out string userID)
{
url = String.Empty;
userID = String.Empty;
Uri assetUri;
if (Uri.TryCreate(id, UriKind.Absolute, out assetUri) &&
assetUri.Scheme == Uri.UriSchemeHttp)
{
url = "http://" + assetUri.Authority;
userID = assetUri.LocalPath.Trim(new char[] { '/' });
return true;
}
return false;
}
private ISessionAuthInventoryService GetConnector(string url)
{
InventoryServicesConnector connector = null;
lock (m_connectors)
{
if (m_connectors.ContainsKey(url))
{
connector = m_connectors[url];
}
else
{
// We're instantiating this class explicitly, but this won't
// work in general, because the remote grid may be running
// an inventory server that has a different protocol.
// Eventually we will want a piece of protocol asking
// the remote server about its kind. Definitely cool thing to do!
connector = new InventoryServicesConnector(url);
m_connectors.Add(url, connector);
}
}
return connector;
}
public string Host
{
get { return string.Empty; }
}
public void GetUserInventory(string id, UUID sessionID, InventoryReceiptCallback callback)
{
m_log.Debug("[HGInventory]: GetUserInventory " + id);
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
connector.GetUserInventory(userID, sessionID, callback);
}
}
/// <summary>
/// Gets the user folder for the given folder-type
/// </summary>
/// <param name="userID"></param>
/// <param name="type"></param>
/// <returns></returns>
public Dictionary<AssetType, InventoryFolderBase> GetSystemFolders(string id, UUID sessionID)
{
m_log.Debug("[HGInventory]: GetSystemFolders " + id);
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
return connector.GetSystemFolders(userID, sessionID);
}
return new Dictionary<AssetType, InventoryFolderBase>();
}
/// <summary>
/// Gets everything (folders and items) inside a folder
/// </summary>
/// <param name="userId"></param>
/// <param name="folderID"></param>
/// <returns></returns>
public InventoryCollection GetFolderContent(string id, UUID folderID, UUID sessionID)
{
m_log.Debug("[HGInventory]: GetFolderContent " + id);
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
return connector.GetFolderContent(userID, folderID, sessionID);
}
return null;
}
public bool AddFolder(string id, InventoryFolderBase folder, UUID sessionID)
{
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
return connector.AddFolder(userID, folder, sessionID);
}
return false;
}
public bool UpdateFolder(string id, InventoryFolderBase folder, UUID sessionID)
{
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
return connector.UpdateFolder(userID, folder, sessionID);
}
return false;
}
public bool MoveFolder(string id, InventoryFolderBase folder, UUID sessionID)
{
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
return connector.MoveFolder(userID, folder, sessionID);
}
return false;
}
public bool DeleteFolders(string id, List<UUID> folders, UUID sessionID)
{
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
return connector.DeleteFolders(userID, folders, sessionID);
}
return false;
}
public bool PurgeFolder(string id, InventoryFolderBase folder, UUID sessionID)
{
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
return connector.PurgeFolder(userID, folder, sessionID);
}
return false;
}
public List<InventoryItemBase> GetFolderItems(string id, UUID folderID, UUID sessionID)
{
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
return connector.GetFolderItems(userID, folderID, sessionID);
}
return new List<InventoryItemBase>();
}
public bool AddItem(string id, InventoryItemBase item, UUID sessionID)
{
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
return connector.AddItem(userID, item, sessionID);
}
return false;
}
public bool UpdateItem(string id, InventoryItemBase item, UUID sessionID)
{
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
return connector.UpdateItem(userID, item, sessionID);
}
return false;
}
public bool MoveItems(string id, List<InventoryItemBase> items, UUID sessionID)
{
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
return connector.MoveItems(userID, items, sessionID);
}
return false;
}
public bool DeleteItems(string id, List<UUID> itemIDs, UUID sessionID)
{
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
return connector.DeleteItems(userID, itemIDs, sessionID);
}
return false;
}
public InventoryItemBase QueryItem(string id, InventoryItemBase item, UUID sessionID)
{
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
//m_log.DebugFormat("[HGInventory CONNECTOR]: calling {0}", url);
ISessionAuthInventoryService connector = GetConnector(url);
return connector.QueryItem(userID, item, sessionID);
}
return null;
}
public InventoryFolderBase QueryFolder(string id, InventoryFolderBase folder, UUID sessionID)
{
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
return connector.QueryFolder(userID, folder, sessionID);
}
return null;
}
public int GetAssetPermissions(string id, UUID assetID, UUID sessionID)
{
string url = string.Empty;
string userID = string.Empty;
if (StringToUrlAndUserID(id, out url, out userID))
{
ISessionAuthInventoryService connector = GetConnector(url);
return connector.GetAssetPermissions(userID, assetID, sessionID);
}
return 0;
}
}
}

View File

@ -1,140 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using OpenSim.Framework;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
namespace OpenSim.Services.Connectors
{
/// <summary>
/// Defines all operations to access a remote inventory service
/// using session authentication as a form of security.
/// </summary>
public interface ISessionAuthInventoryService
{
string Host
{
get;
}
/// <summary>
/// Request the inventory for a user. This is an asynchronous operation that will call the callback when the
/// inventory has been received
/// </summary>
/// <param name="userID"></param>
/// <param name="callback"></param>
void GetUserInventory(string userID, UUID session_id, InventoryReceiptCallback callback);
/// <summary>
/// Gets the user folder for the given folder-type
/// </summary>
/// <param name="userID"></param>
/// <param name="type"></param>
/// <returns></returns>
Dictionary<AssetType, InventoryFolderBase> GetSystemFolders(string userID, UUID session_id);
/// <summary>
/// Gets everything (folders and items) inside a folder
/// </summary>
/// <param name="userId"></param>
/// <param name="folderID"></param>
/// <returns></returns>
InventoryCollection GetFolderContent(string userID, UUID folderID, UUID session_id);
/// <summary>
/// Add a new folder to the user's inventory
/// </summary>
/// <param name="folder"></param>
/// <returns>true if the folder was successfully added</returns>
bool AddFolder(string userID, InventoryFolderBase folder, UUID session_id);
/// <summary>
/// Update a folder in the user's inventory
/// </summary>
/// <param name="folder"></param>
/// <returns>true if the folder was successfully updated</returns>
bool UpdateFolder(string userID, InventoryFolderBase folder, UUID session_id);
/// <summary>
/// Move an inventory folder to a new location
/// </summary>
/// <param name="folder">A folder containing the details of the new location</param>
/// <returns>true if the folder was successfully moved</returns>
bool MoveFolder(string userID, InventoryFolderBase folder, UUID session_id);
/// <summary>
/// Delete a list of inventory folders (from trash)
/// </summary>
bool DeleteFolders(string userID, List<UUID> folders, UUID session_id);
/// <summary>
/// Purge an inventory folder of all its items and subfolders.
/// </summary>
/// <param name="folder"></param>
/// <returns>true if the folder was successfully purged</returns>
bool PurgeFolder(string userID, InventoryFolderBase folder, UUID session_id);
/// <summary>
/// Get items from a folder.
/// </summary>
/// <param name="folder"></param>
/// <returns>true if the folder was successfully purged</returns>
List<InventoryItemBase> GetFolderItems(string userID, UUID folderID, UUID session_id);
/// <summary>
/// Add a new item to the user's inventory
/// </summary>
/// <param name="item"></param>
/// <returns>true if the item was successfully added</returns>
bool AddItem(string userID, InventoryItemBase item, UUID session_id);
/// <summary>
/// Update an item in the user's inventory
/// </summary>
/// <param name="item"></param>
/// <returns>true if the item was successfully updated</returns>
bool UpdateItem(string userID, InventoryItemBase item, UUID session_id);
bool MoveItems(string userID, List<InventoryItemBase> items, UUID session_id);
/// <summary>
/// Delete an item from the user's inventory
/// </summary>
/// <param name="item"></param>
/// <returns>true if the item was successfully deleted</returns>
bool DeleteItems(string userID, List<UUID> itemIDs, UUID session_id);
InventoryItemBase QueryItem(string userID, InventoryItemBase item, UUID session_id);
InventoryFolderBase QueryFolder(string userID, InventoryFolderBase item, UUID session_id);
int GetAssetPermissions(string userID, UUID assetID, UUID session_id);
}
}

View File

@ -1,582 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using log4net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
namespace OpenSim.Services.Connectors
{
public class InventoryServicesConnector : ISessionAuthInventoryService
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private string m_ServerURI = String.Empty;
private Dictionary<UUID, InventoryReceiptCallback> m_RequestingInventory = new Dictionary<UUID, InventoryReceiptCallback>();
private Dictionary<UUID, DateTime> m_RequestTime = new Dictionary<UUID, DateTime>();
public InventoryServicesConnector()
{
}
public InventoryServicesConnector(string serverURI)
{
m_ServerURI = serverURI.TrimEnd('/');
}
public InventoryServicesConnector(IConfigSource source)
{
Initialise(source);
}
public virtual void Initialise(IConfigSource source)
{
IConfig inventoryConfig = source.Configs["InventoryService"];
if (inventoryConfig == null)
{
m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
throw new Exception("InventoryService missing from OpenSim.ini");
}
string serviceURI = inventoryConfig.GetString("InventoryServerURI",
String.Empty);
if (serviceURI == String.Empty)
{
m_log.Error("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService");
throw new Exception("Unable to proceed. Please make sure your ini files in config-include are updated according to .example's");
}
m_ServerURI = serviceURI.TrimEnd('/');
}
#region ISessionAuthInventoryService
public string Host
{
get { return m_ServerURI; }
}
/// <summary>
/// Caller must catch eventual Exceptions.
/// </summary>
/// <param name="userID"></param>
/// <param name="sessionID"></param>
/// <param name="callback"></param>
public void GetUserInventory(string userIDStr, UUID sessionID, InventoryReceiptCallback callback)
{
UUID userID = UUID.Zero;
if (UUID.TryParse(userIDStr, out userID))
{
lock (m_RequestingInventory)
{
// *HACK ALERT*
// If an inventory request times out, it blocks any further requests from the
// same user, even after a relog. This is bad, and makes me sad.
// Really, we should detect a timeout and report a failure to the callback,
// BUT in my testing i found that it's hard to detect a timeout.. sometimes,
// a partial response is recieved, and sometimes a null response.
// So, for now, add a timer of ten seconds (which is the request timeout).
// This should basically have the same effect.
lock (m_RequestTime)
{
if (m_RequestTime.ContainsKey(userID))
{
TimeSpan interval = DateTime.Now - m_RequestTime[userID];
if (interval.TotalSeconds > 10)
{
m_RequestTime.Remove(userID);
if (m_RequestingInventory.ContainsKey(userID))
{
m_RequestingInventory.Remove(userID);
}
}
}
if (!m_RequestingInventory.ContainsKey(userID))
{
m_RequestTime.Add(userID, DateTime.Now);
m_RequestingInventory.Add(userID, callback);
}
else
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetUserInventory - ignoring repeated request for user {0}", userID);
return;
}
}
}
m_log.InfoFormat(
"[INVENTORY CONNECTOR]: Requesting inventory from {0}/GetInventory/ for user {1}",
m_ServerURI, userID);
RestSessionObjectPosterResponse<Guid, InventoryCollection> requester
= new RestSessionObjectPosterResponse<Guid, InventoryCollection>();
requester.ResponseCallback = InventoryResponse;
requester.BeginPostObject(m_ServerURI + "/GetInventory/", userID.Guid, sessionID.ToString(), userID.ToString());
}
}
/// <summary>
/// Gets the user folder for the given folder-type
/// </summary>
/// <param name="userID"></param>
/// <param name="type"></param>
/// <returns></returns>
public Dictionary<AssetType, InventoryFolderBase> GetSystemFolders(string userID, UUID sessionID)
{
List<InventoryFolderBase> folders = null;
Dictionary<AssetType, InventoryFolderBase> dFolders = new Dictionary<AssetType, InventoryFolderBase>();
try
{
folders = SynchronousRestSessionObjectPoster<Guid, List<InventoryFolderBase>>.BeginPostObject(
"POST", m_ServerURI + "/SystemFolders/", new Guid(userID), sessionID.ToString(), userID.ToString());
foreach (InventoryFolderBase f in folders)
dFolders[(AssetType)f.Type] = f;
return dFolders;
}
catch (Exception e)
{
// Maybe we're talking to an old inventory server. Try this other thing.
m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetSystemFolders operation failed, {0} {1} (old sever?). Trying GetInventory.",
e.Source, e.Message);
try
{
InventoryCollection inventory = SynchronousRestSessionObjectPoster<Guid, InventoryCollection>.BeginPostObject(
"POST", m_ServerURI + "/GetInventory/", new Guid(userID), sessionID.ToString(), userID.ToString());
folders = inventory.Folders;
}
catch (Exception ex)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetInventory operation also failed, {0} {1}. Giving up.",
e.Source, ex.Message);
}
if ((folders != null) && (folders.Count > 0))
{
m_log.DebugFormat("[INVENTORY CONNECTOR]: Received entire inventory ({0} folders) for user {1}",
folders.Count, userID);
foreach (InventoryFolderBase f in folders)
{
if ((f.Type != (short)AssetType.Folder) && (f.Type != (short)AssetType.Unknown))
dFolders[(AssetType)f.Type] = f;
}
UUID rootFolderID = dFolders[AssetType.Animation].ParentID;
InventoryFolderBase rootFolder = new InventoryFolderBase(rootFolderID, new UUID(userID));
rootFolder = QueryFolder(userID, rootFolder, sessionID);
dFolders[AssetType.Folder] = rootFolder;
m_log.DebugFormat("[INVENTORY CONNECTOR]: {0} system folders for user {1}", dFolders.Count, userID);
return dFolders;
}
}
return new Dictionary<AssetType, InventoryFolderBase>();
}
/// <summary>
/// Gets everything (folders and items) inside a folder
/// </summary>
/// <param name="userId"></param>
/// <param name="folderID"></param>
/// <returns></returns>
public InventoryCollection GetFolderContent(string userID, UUID folderID, UUID sessionID)
{
try
{
// normal case
return SynchronousRestSessionObjectPoster<Guid, InventoryCollection>.BeginPostObject(
"POST", m_ServerURI + "/GetFolderContent/", folderID.Guid, sessionID.ToString(), userID.ToString());
}
catch (TimeoutException e)
{
m_log.ErrorFormat(
"[INVENTORY CONNECTOR]: GetFolderContent operation to {0} for {1} timed out {2} {3}.",
m_ServerURI, folderID, e.Source, e.Message);
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetFolderContent operation failed for {0}, {1} {2} (old server?).",
folderID, e.Source, e.Message);
}
InventoryCollection nullCollection = new InventoryCollection();
nullCollection.Folders = new List<InventoryFolderBase>();
nullCollection.Items = new List<InventoryItemBase>();
nullCollection.UserID = new UUID(userID);
return nullCollection;
}
public bool AddFolder(string userID, InventoryFolderBase folder, UUID sessionID)
{
try
{
return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
"POST", m_ServerURI + "/NewFolder/", folder, sessionID.ToString(), folder.Owner.ToString());
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Add new inventory folder operation failed for {0} {1}, {2} {3}",
folder.Name, folder.ID, e.Source, e.Message);
}
return false;
}
public bool UpdateFolder(string userID, InventoryFolderBase folder, UUID sessionID)
{
try
{
return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
"POST", m_ServerURI + "/UpdateFolder/", folder, sessionID.ToString(), folder.Owner.ToString());
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Update inventory folder operation failed for {0} {1}, {2} {3}",
folder.Name, folder.ID, e.Source, e.Message);
}
return false;
}
public bool DeleteFolders(string userID, List<UUID> folderIDs, UUID sessionID)
{
try
{
List<Guid> guids = new List<Guid>();
foreach (UUID u in folderIDs)
guids.Add(u.Guid);
return SynchronousRestSessionObjectPoster<List<Guid>, bool>.BeginPostObject(
"POST", m_ServerURI + "/DeleteFolders/", guids, sessionID.ToString(), userID);
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Delete inventory folders operation failed, {0} {1}",
e.Source, e.Message);
}
return false;
}
public bool MoveFolder(string userID, InventoryFolderBase folder, UUID sessionID)
{
try
{
return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
"POST", m_ServerURI + "/MoveFolder/", folder, sessionID.ToString(), folder.Owner.ToString());
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Move inventory folder operation failed for {0} {1}, {2} {3}",
folder.Name, folder.ID, e.Source, e.Message);
}
return false;
}
public bool PurgeFolder(string userID, InventoryFolderBase folder, UUID sessionID)
{
try
{
return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
"POST", m_ServerURI + "/PurgeFolder/", folder, sessionID.ToString(), folder.Owner.ToString());
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Purge inventory folder operation failed for {0} {1}, {2} {3}",
folder.Name, folder.ID, e.Source, e.Message);
}
return false;
}
public List<InventoryItemBase> GetFolderItems(string userID, UUID folderID, UUID sessionID)
{
try
{
InventoryFolderBase folder = new InventoryFolderBase(folderID, new UUID(userID));
return SynchronousRestSessionObjectPoster<InventoryFolderBase, List<InventoryItemBase>>.BeginPostObject(
"POST", m_ServerURI + "/GetItems/", folder, sessionID.ToString(), userID);
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Get folder items operation failed for folder {0}, {1} {2}",
folderID, e.Source, e.Message);
}
return null;
}
public bool AddItem(string userID, InventoryItemBase item, UUID sessionID)
{
try
{
return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject(
"POST", m_ServerURI + "/NewItem/", item, sessionID.ToString(), item.Owner.ToString());
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Add new inventory item operation failed for {0} {1}, {2} {3}",
item.Name, item.ID, e.Source, e.Message);
}
return false;
}
public bool UpdateItem(string userID, InventoryItemBase item, UUID sessionID)
{
try
{
return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject(
"POST", m_ServerURI + "/NewItem/", item, sessionID.ToString(), item.Owner.ToString());
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Update new inventory item operation failed for {0} {1}, {2} {3}",
item.Name, item.ID, e.Source, e.Message);
}
return false;
}
/**
* MoveItems Async group
*/
delegate void MoveItemsDelegate(string userID, List<InventoryItemBase> items, UUID sessionID);
private void MoveItemsAsync(string userID, List<InventoryItemBase> items, UUID sessionID)
{
if (items == null)
{
m_log.WarnFormat("[INVENTORY CONNECTOR]: request to move items got a null list.");
return;
}
try
{
//SynchronousRestSessionObjectPoster<List<InventoryItemBase>, bool>.BeginPostObject(
// "POST", m_ServerURI + "/MoveItems/", items, sessionID.ToString(), userID.ToString());
//// Success
//return;
string uri = m_ServerURI + "/inventory/" + userID;
if (SynchronousRestObjectRequester.
MakeRequest<List<InventoryItemBase>, bool>("PUT", uri, items))
m_log.DebugFormat("[INVENTORY CONNECTOR]: move {0} items poster succeeded {1}", items.Count, uri);
else
m_log.DebugFormat("[INVENTORY CONNECTOR]: move {0} items poster failed {1}", items.Count, uri); ;
return;
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Move inventory items operation failed, {0} {1} (old server?). Trying slow way.",
e.Source, e.Message);
}
}
private void MoveItemsCompleted(IAsyncResult iar)
{
MoveItemsDelegate d = (MoveItemsDelegate)iar.AsyncState;
d.EndInvoke(iar);
}
public bool MoveItems(string userID, List<InventoryItemBase> items, UUID sessionID)
{
MoveItemsDelegate d = MoveItemsAsync;
d.BeginInvoke(userID, items, sessionID, MoveItemsCompleted, d);
return true;
}
public bool DeleteItems(string userID, List<UUID> items, UUID sessionID)
{
try
{
List<Guid> guids = new List<Guid>();
foreach (UUID u in items)
guids.Add(u.Guid);
return SynchronousRestSessionObjectPoster<List<Guid>, bool>.BeginPostObject(
"POST", m_ServerURI + "/DeleteItem/", guids, sessionID.ToString(), userID);
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Delete inventory items operation failed, {0} {1}",
e.Source, e.Message);
}
return false;
}
public InventoryItemBase QueryItem(string userID, InventoryItemBase item, UUID sessionID)
{
try
{
return SynchronousRestSessionObjectPoster<InventoryItemBase, InventoryItemBase>.BeginPostObject(
"POST", m_ServerURI + "/QueryItem/", item, sessionID.ToString(), item.Owner.ToString());
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Query inventory item operation failed, {0} {1}",
e.Source, e.Message);
}
return null;
}
public InventoryFolderBase QueryFolder(string userID, InventoryFolderBase folder, UUID sessionID)
{
try
{
return SynchronousRestSessionObjectPoster<InventoryFolderBase, InventoryFolderBase>.BeginPostObject(
"POST", m_ServerURI + "/QueryFolder/", folder, sessionID.ToString(), userID);
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Query inventory folder operation failed, {0} {1}",
e.Source, e.Message);
}
return null;
}
public int GetAssetPermissions(string userID, UUID assetID, UUID sessionID)
{
try
{
InventoryItemBase item = new InventoryItemBase();
item.Owner = new UUID(userID);
item.AssetID = assetID;
return SynchronousRestSessionObjectPoster<InventoryItemBase, int>.BeginPostObject(
"POST", m_ServerURI + "/AssetPermissions/", item, sessionID.ToString(), userID);
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: AssetPermissions operation failed, {0} {1}",
e.Source, e.Message);
}
return 0;
}
#endregion
/// <summary>
/// Callback used by the inventory server GetInventory request
/// </summary>
/// <param name="userID"></param>
private void InventoryResponse(InventoryCollection response)
{
UUID userID = response.UserID;
InventoryReceiptCallback callback = null;
lock (m_RequestingInventory)
{
if (m_RequestingInventory.ContainsKey(userID))
{
callback = m_RequestingInventory[userID];
m_RequestingInventory.Remove(userID);
lock (m_RequestTime)
{
if (m_RequestTime.ContainsKey(userID))
{
m_RequestTime.Remove(userID);
}
}
}
else
{
m_log.WarnFormat(
"[INVENTORY CONNECTOR]: " +
"Received inventory response for {0} for which we do not have a record of requesting!",
userID);
return;
}
}
m_log.InfoFormat("[INVENTORY CONNECTOR]: " +
"Received inventory response for user {0} containing {1} folders and {2} items",
userID, response.Folders.Count, response.Items.Count);
InventoryFolderImpl rootFolder = null;
ICollection<InventoryFolderImpl> folders = new List<InventoryFolderImpl>();
ICollection<InventoryItemBase> items = new List<InventoryItemBase>();
foreach (InventoryFolderBase folder in response.Folders)
{
if (folder.ParentID == UUID.Zero)
{
rootFolder = new InventoryFolderImpl(folder);
folders.Add(rootFolder);
break;
}
}
if (rootFolder != null)
{
foreach (InventoryFolderBase folder in response.Folders)
{
if (folder.ID != rootFolder.ID)
{
folders.Add(new InventoryFolderImpl(folder));
}
}
foreach (InventoryItemBase item in response.Items)
{
items.Add(item);
}
}
else
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Did not get back an inventory containing a root folder for user {0}", userID);
}
callback(folders, items);
}
}
}

View File

@ -1,196 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using log4net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
namespace OpenSim.Services.Connectors
{
/// <summary>
/// This connector is temporary. It's used by the user server, before that server is refactored.
/// </summary>
public class QuickAndDirtyInventoryServiceConnector : IInventoryService
{
// private static readonly ILog m_log =
// LogManager.GetLogger(
// MethodBase.GetCurrentMethod().DeclaringType);
private string m_ServerURI = String.Empty;
//private Dictionary<UUID, InventoryReceiptCallback> m_RequestingInventory = new Dictionary<UUID, InventoryReceiptCallback>();
public QuickAndDirtyInventoryServiceConnector()
{
}
public QuickAndDirtyInventoryServiceConnector(string serverURI)
{
m_ServerURI = serverURI.TrimEnd('/');
}
/// <summary>
/// <see cref="OpenSim.Framework.Communications.IInterServiceInventoryServices"/>
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public bool CreateUserInventory(UUID userId)
{
return SynchronousRestObjectPoster.BeginPostObject<Guid, bool>(
"POST", m_ServerURI + "CreateInventory/", userId.Guid);
}
/// <summary>
/// <see cref="OpenSim.Framework.Communications.IInterServiceInventoryServices"/>
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public List<InventoryFolderBase> GetInventorySkeleton(UUID userId)
{
return SynchronousRestObjectPoster.BeginPostObject<Guid, List<InventoryFolderBase>>(
"POST", m_ServerURI + "RootFolders/", userId.Guid);
}
/// <summary>
/// Returns a list of all the active gestures in a user's inventory.
/// </summary>
/// <param name="userId">
/// The <see cref="UUID"/> of the user
/// </param>
/// <returns>
/// A flat list of the gesture items.
/// </returns>
public List<InventoryItemBase> GetActiveGestures(UUID userId)
{
return SynchronousRestObjectPoster.BeginPostObject<Guid, List<InventoryItemBase>>(
"POST", m_ServerURI + "ActiveGestures/", userId.Guid);
}
public InventoryCollection GetUserInventory(UUID userID)
{
return null;
}
public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
{
}
public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
{
return null;
}
public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
{
return null;
}
public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
{
return null;
}
public bool AddFolder(InventoryFolderBase folder)
{
return false;
}
public bool UpdateFolder(InventoryFolderBase folder)
{
return false;
}
public bool MoveFolder(InventoryFolderBase folder)
{
return false;
}
public bool DeleteFolders(UUID ownerID, List<UUID> folderIDs)
{
return false;
}
public bool PurgeFolder(InventoryFolderBase folder)
{
return false;
}
public bool AddItem(InventoryItemBase item)
{
return false;
}
public bool UpdateItem(InventoryItemBase item)
{
return false;
}
public bool MoveItems(UUID ownerID, List<InventoryItemBase> items)
{
return false;
}
public bool DeleteItems(UUID owner, List<UUID> itemIDs)
{
return false;
}
public InventoryItemBase GetItem(InventoryItemBase item)
{
return null;
}
public InventoryFolderBase GetFolder(InventoryFolderBase folder)
{
return null;
}
public bool HasInventoryForUser(UUID userID)
{
return false;
}
public InventoryFolderBase GetRootFolder(UUID userID)
{
return null;
}
public int GetAssetPermissions(UUID userID, UUID assetID)
{
return 0;
}
}
}

View File

@ -87,16 +87,17 @@ namespace OpenSim.Region.OptionalModules.Simian
if (String.IsNullOrEmpty(m_serverUrl)) if (String.IsNullOrEmpty(m_serverUrl))
return; return;
m_refreshtime = Convert.ToInt32(config.GetString("RefreshTime")); int refreshseconds = Convert.ToInt32(config.GetString("RefreshTime"));
if (m_refreshtime <= 0) if (refreshseconds <= 0)
return; return;
m_refreshtime = refreshseconds * 1000; // convert from seconds to ms
m_log.InfoFormat("[SIMIAN MAPTILE] enabled with refresh timeout {0} and URL {1}", m_log.InfoFormat("[SIMIAN MAPTILE] enabled with refresh timeout {0} and URL {1}",
m_refreshtime,m_serverUrl); m_refreshtime,m_serverUrl);
m_enabled = true; m_enabled = true;
} }
///<summary> ///<summary>
/// ///
///</summary> ///</summary>
@ -106,7 +107,7 @@ namespace OpenSim.Region.OptionalModules.Simian
{ {
m_refreshTimer.Enabled = true; m_refreshTimer.Enabled = true;
m_refreshTimer.AutoReset = true; m_refreshTimer.AutoReset = true;
m_refreshTimer.Interval = 5 * 60 * 1000; // every 5 minutes m_refreshTimer.Interval = 5 * 60 * 1000; // every 5 minutes
m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh); m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh);
} }
} }
@ -120,12 +121,12 @@ namespace OpenSim.Region.OptionalModules.Simian
if (! m_enabled) if (! m_enabled)
return; return;
// Every shared region module has to maintain an indepedent list of // Every shared region module has to maintain an indepedent list of
// currently running regions // currently running regions
lock (m_scenes) lock (m_scenes)
m_scenes[scene.RegionInfo.RegionID] = scene; m_scenes[scene.RegionInfo.RegionID] = scene;
} }
///<summary> ///<summary>
/// ///
///</summary> ///</summary>
@ -150,7 +151,7 @@ namespace OpenSim.Region.OptionalModules.Simian
// loaded and initialized // loaded and initialized
if (m_lastrefresh > 0 && Util.EnvironmentTickCountSubtract(m_lastrefresh) < m_refreshtime) if (m_lastrefresh > 0 && Util.EnvironmentTickCountSubtract(m_lastrefresh) < m_refreshtime)
return; return;
m_log.DebugFormat("[SIMIAN MAPTILE] map refresh fired"); m_log.DebugFormat("[SIMIAN MAPTILE] map refresh fired");
lock (m_scenes) lock (m_scenes)
{ {
@ -169,7 +170,7 @@ namespace OpenSim.Region.OptionalModules.Simian
m_lastrefresh = Util.EnvironmentTickCount(); m_lastrefresh = Util.EnvironmentTickCount();
} }
///<summary> ///<summary>
/// ///
///</summary> ///</summary>
@ -211,7 +212,7 @@ namespace OpenSim.Region.OptionalModules.Simian
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl); HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl);
request.Timeout = 20000; request.Timeout = 20000;
request.ReadWriteTimeout = 5000; request.ReadWriteTimeout = 5000;
using (HttpWebResponse response = MultipartForm.Post(request, postParameters)) using (HttpWebResponse response = MultipartForm.Post(request, postParameters))
{ {
using (Stream responseStream = response.GetResponseStream()) using (Stream responseStream = response.GetResponseStream())

View File

@ -48,6 +48,9 @@ namespace OpenSim.Services.Connectors.Simulation
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// we use this dictionary to track the pending updateagent requests, maps URI --> position update
private Dictionary<string,AgentPosition> m_updateAgentQueue = new Dictionary<string,AgentPosition>();
//private GridRegion m_Region; //private GridRegion m_Region;
public SimulationServiceConnector() public SimulationServiceConnector()
@ -133,10 +136,56 @@ namespace OpenSim.Services.Connectors.Simulation
/// </summary> /// </summary>
public bool UpdateAgent(GridRegion destination, AgentPosition data) public bool UpdateAgent(GridRegion destination, AgentPosition data)
{ {
// we need a better throttle for these // The basic idea of this code is that the first thread that needs to
// return false; // send an update for a specific avatar becomes the worker for any subsequent
// requests until there are no more outstanding requests. Further, only send the most
// recent update; this *should* never be needed but some requests get
// slowed down and once that happens the problem with service end point
// limits kicks in and nothing proceeds
string uri = destination.ServerURI + AgentPath() + data.AgentID + "/";
lock (m_updateAgentQueue)
{
if (m_updateAgentQueue.ContainsKey(uri))
{
// Another thread is already handling
// updates for this simulator, just update
// the position and return, overwrites are
// not a problem since we only care about the
// last update anyway
m_updateAgentQueue[uri] = data;
return true;
}
// Otherwise update the reference and start processing
m_updateAgentQueue[uri] = data;
}
return UpdateAgent(destination, (IAgentData)data); AgentPosition pos = null;
while (true)
{
lock (m_updateAgentQueue)
{
// save the position
AgentPosition lastpos = pos;
pos = m_updateAgentQueue[uri];
// this is true if no one put a new
// update in the map since the last
// one we processed, if thats the
// case then we are done
if (pos == lastpos)
{
m_updateAgentQueue.Remove(uri);
return true;
}
}
UpdateAgent(destination,(IAgentData)pos);
}
// unreachable
return true;
} }
/// <summary> /// <summary>

View File

@ -286,7 +286,7 @@ namespace OpenSim.Services.GridService
} }
} }
m_log.DebugFormat("[GRID SERVICE]: region {0} has {1} neighours", region.RegionName, rinfos.Count); m_log.DebugFormat("[GRID SERVICE]: region {0} has {1} neighbours", region.RegionName, rinfos.Count);
return rinfos; return rinfos;
} }

View File

@ -220,9 +220,15 @@ namespace OpenSim.Services.GridService
string[] parts = mapName.Split(new char[] {' '}); string[] parts = mapName.Split(new char[] {' '});
string regionName = String.Empty; string regionName = String.Empty;
if (parts.Length > 1) if (parts.Length > 1)
regionName = parts[1]; {
regionName = mapName.Substring(parts[0].Length + 1);
regionName = regionName.Trim(new char[] {'"'});
}
if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, parts[0], ownerID, out regInfo, out reason)) if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, parts[0], ownerID, out regInfo, out reason))
{
regInfo.RegionName = mapName;
return regInfo; return regInfo;
}
} }
return null; return null;
@ -317,9 +323,9 @@ namespace OpenSim.Services.GridService
regInfo.RegionID = regionID; regInfo.RegionID = regionID;
if ( externalName == string.Empty ) if (externalName == string.Empty)
regInfo.RegionName = regInfo.ServerURI; regInfo.RegionName = regInfo.ServerURI;
else else
regInfo.RegionName = externalName; regInfo.RegionName = externalName;
m_log.Debug("[HYPERGRID LINKER]: naming linked region " + regInfo.RegionName); m_log.Debug("[HYPERGRID LINKER]: naming linked region " + regInfo.RegionName);

Binary file not shown.

Binary file not shown.

View File

@ -306,6 +306,9 @@
[ODEPhysicsSettings] [ODEPhysicsSettings]
;# {mesh_sculpted_prim} {[Startup]physics:OpenDynamicsEngine} {Mesh sculpties so they collide as they look?} {true false} true ;# {mesh_sculpted_prim} {[Startup]physics:OpenDynamicsEngine} {Mesh sculpties so they collide as they look?} {true false} true
;; Do we want to mesh sculpted prim to collide like they look? ;; Do we want to mesh sculpted prim to collide like they look?
;; If you are seeing sculpt texture decode problems
;; (messages such as "Decoded image with unhandled number of components: 0 shortly followed by a physcs exception")
;; then you might want to try setting this to false.
; mesh_sculpted_prim = true ; mesh_sculpted_prim = true
;# {use_NINJA_physics_joints} {[Startup]physics:OpenDynamicsEngine} {Use jointed (NINJA) physics?} {true false} false ;# {use_NINJA_physics_joints} {[Startup]physics:OpenDynamicsEngine} {Use jointed (NINJA) physics?} {true false} false

View File

@ -413,6 +413,15 @@
<Key Name="assetType" Value="0" /> <Key Name="assetType" Value="0" />
<Key Name="fileName" Value="default_clear.jp2" /> <Key Name="fileName" Value="default_clear.jp2" />
</Section> </Section>
<!-- 3a367d1c-bef1-6d43-7595-e88c1e3aadb3 is a UUID that viewers assume exists in the asset server -->
<!-- See http://opensimulator.org/mantis/bug_view_advanced_page.php?bug_id=4751 for more details -->
<Section Name="Default Alpha Layer Texture">
<Key Name="assetID" Value="3a367d1c-bef1-6d43-7595-e88c1e3aadb3"/>
<Key Name="name" Value="Default Alpha Layer Texture"/>
<Key Name="assetType" Value="0" />
<Key Name="fileName" Value="default_clear.jp2" />
</Section>
<Section Name="Default Avatar"> <Section Name="Default Avatar">
<Key Name="assetID" Value="c228d1cf-4b5d-4ba8-84f4-899a0796aa97"/> <Key Name="assetID" Value="c228d1cf-4b5d-4ba8-84f4-899a0796aa97"/>

View File

@ -88,6 +88,10 @@
; accessible from other grids ; accessible from other grids
; ;
ProfileServerURI = "http://mygridserver.com:8002/user" ProfileServerURI = "http://mygridserver.com:8002/user"
;; If you want to protect your assets from being copied by foreign visitors
;; uncomment the next line. You may want to do this on sims that have licensed content.
; OutboundPermission = False
[Modules] [Modules]
;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists. ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists.

View File

@ -82,3 +82,14 @@
[Profiles] [Profiles]
Module = "SimianProfiles" Module = "SimianProfiles"
[HGInventoryAccessModule]
;
; === HG ONLY ===
; Change this to your profile server
; accessible from other grids
;
ProfileServerURI = "http://mygridserver.com:8002/user"
;; If you want to protect your assets from being copied by foreign visitors
;; uncomment the next line. You may want to do this on sims that have licensed content.
; OutboundPermission = False

View File

@ -33,6 +33,10 @@
[HGInventoryAccessModule] [HGInventoryAccessModule]
ProfileServerURI = "http://127.0.0.1:9000/profiles" ProfileServerURI = "http://127.0.0.1:9000/profiles"
;; If you want to protect your assets from being copied by foreign visitors
;; uncomment the next line. You may want to do this on sims that have licensed content.
; OutboundPermission = False
[Modules] [Modules]
;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists. ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists.

Binary file not shown.