diff --git a/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs b/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs
index 6ba022cd93..6731923c3b 100644
--- a/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs
+++ b/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs
@@ -46,7 +46,7 @@ namespace OpenSim.OfflineIM
{
public class OfflineIMService : OfflineIMServiceBase, IOfflineIMService
{
- private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private const int MAX_IM = 25;
private XmlSerializer m_serializer;
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2Handler.cs b/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2Handler.cs
index c0ca1e1896..2c91328e56 100644
--- a/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2Handler.cs
+++ b/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2Handler.cs
@@ -46,7 +46,7 @@ namespace OpenSim.Capabilities.Handlers
{
public class FetchInventory2Handler
{
- private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IInventoryService m_inventoryService;
@@ -121,4 +121,4 @@ namespace OpenSim.Capabilities.Handlers
return llsdItem;
}
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Framework/Monitoring/BaseStatsCollector.cs b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs
index be1d02bd10..20495f6e95 100644
--- a/OpenSim/Framework/Monitoring/BaseStatsCollector.cs
+++ b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -45,16 +45,16 @@ namespace OpenSim.Framework.Monitoring
sb.Append(Environment.NewLine);
sb.AppendFormat(
- "Allocated to OpenSim objects: {0} MB\n",
+ "Heap allocated to OpenSim : {0} MB\n",
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0));
sb.AppendFormat(
- "OpenSim last object memory churn : {0} MB/s\n",
- Math.Round((MemoryWatchdog.LastMemoryChurn * 1000) / 1024.0 / 1024, 3));
+ "Last heap allocation rate : {0} MB/s\n",
+ Math.Round((MemoryWatchdog.LastHeapAllocationRate * 1000) / 1024.0 / 1024, 3));
sb.AppendFormat(
- "OpenSim average object memory churn : {0} MB/s\n",
- Math.Round((MemoryWatchdog.AverageMemoryChurn * 1000) / 1024.0 / 1024, 3));
+ "Average heap allocation rate: {0} MB/s\n",
+ Math.Round((MemoryWatchdog.AverageHeapAllocationRate * 1000) / 1024.0 / 1024, 3));
sb.AppendFormat(
"Process memory : {0} MB\n",
diff --git a/OpenSim/Framework/Monitoring/MemoryWatchdog.cs b/OpenSim/Framework/Monitoring/MemoryWatchdog.cs
index c6010cd092..c47462225b 100644
--- a/OpenSim/Framework/Monitoring/MemoryWatchdog.cs
+++ b/OpenSim/Framework/Monitoring/MemoryWatchdog.cs
@@ -60,17 +60,17 @@ namespace OpenSim.Framework.Monitoring
private static bool m_enabled;
///
- /// Last memory churn in bytes per millisecond.
+ /// Average heap allocation rate in bytes per millisecond.
///
- public static double AverageMemoryChurn
+ public static double AverageHeapAllocationRate
{
get { if (m_samples.Count > 0) return m_samples.Average(); else return 0; }
}
///
- /// Average memory churn in bytes per millisecond.
+ /// Last heap allocation in bytes
///
- public static double LastMemoryChurn
+ public static double LastHeapAllocationRate
{
get { if (m_samples.Count > 0) return m_samples.Last(); else return 0; }
}
diff --git a/OpenSim/Framework/Monitoring/ServerStatsCollector.cs b/OpenSim/Framework/Monitoring/ServerStatsCollector.cs
new file mode 100644
index 0000000000..ac0f0bc7be
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/ServerStatsCollector.cs
@@ -0,0 +1,349 @@
+/*
+ * 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.Diagnostics;
+using System.Linq;
+using System.Net.NetworkInformation;
+using System.Text;
+using System.Threading;
+using log4net;
+using Nini.Config;
+using OpenMetaverse.StructuredData;
+using OpenSim.Framework;
+
+namespace OpenSim.Framework.Monitoring
+{
+ public class ServerStatsCollector
+ {
+ private readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+ private readonly string LogHeader = "[SERVER STATS]";
+
+ public bool Enabled = false;
+ private static Dictionary RegisteredStats = new Dictionary();
+
+ public readonly string CategoryServer = "server";
+
+ public readonly string ContainerThreadpool = "threadpool";
+ public readonly string ContainerProcessor = "processor";
+ public readonly string ContainerMemory = "memory";
+ public readonly string ContainerNetwork = "network";
+ public readonly string ContainerProcess = "process";
+
+ public string NetworkInterfaceTypes = "Ethernet";
+
+ readonly int performanceCounterSampleInterval = 500;
+// int lastperformanceCounterSampleTime = 0;
+
+ private class PerfCounterControl
+ {
+ public PerformanceCounter perfCounter;
+ public int lastFetch;
+ public string name;
+ public PerfCounterControl(PerformanceCounter pPc)
+ : this(pPc, String.Empty)
+ {
+ }
+ public PerfCounterControl(PerformanceCounter pPc, string pName)
+ {
+ perfCounter = pPc;
+ lastFetch = 0;
+ name = pName;
+ }
+ }
+
+ PerfCounterControl processorPercentPerfCounter = null;
+
+ // IRegionModuleBase.Initialize
+ public void Initialise(IConfigSource source)
+ {
+ IConfig cfg = source.Configs["Monitoring"];
+
+ if (cfg != null)
+ Enabled = cfg.GetBoolean("ServerStatsEnabled", true);
+
+ if (Enabled)
+ {
+ NetworkInterfaceTypes = cfg.GetString("NetworkInterfaceTypes", "Ethernet");
+ }
+ }
+
+ public void Start()
+ {
+ if (RegisteredStats.Count == 0)
+ RegisterServerStats();
+ }
+
+ public void Close()
+ {
+ if (RegisteredStats.Count > 0)
+ {
+ foreach (Stat stat in RegisteredStats.Values)
+ {
+ StatsManager.DeregisterStat(stat);
+ stat.Dispose();
+ }
+ RegisteredStats.Clear();
+ }
+ }
+
+ private void MakeStat(string pName, string pDesc, string pUnit, string pContainer, Action act)
+ {
+ MakeStat(pName, pDesc, pUnit, pContainer, act, MeasuresOfInterest.None);
+ }
+
+ private void MakeStat(string pName, string pDesc, string pUnit, string pContainer, Action act, MeasuresOfInterest moi)
+ {
+ string desc = pDesc;
+ if (desc == null)
+ desc = pName;
+ Stat stat = new Stat(pName, pName, desc, pUnit, CategoryServer, pContainer, StatType.Pull, moi, act, StatVerbosity.Debug);
+ StatsManager.RegisterStat(stat);
+ RegisteredStats.Add(pName, stat);
+ }
+
+ public void RegisterServerStats()
+ {
+// lastperformanceCounterSampleTime = Util.EnvironmentTickCount();
+ PerformanceCounter tempPC;
+ Stat tempStat;
+ string tempName;
+
+ try
+ {
+ tempName = "CPUPercent";
+ tempPC = new PerformanceCounter("Processor", "% Processor Time", "_Total");
+ processorPercentPerfCounter = new PerfCounterControl(tempPC);
+ // A long time bug in mono is that CPU percent is reported as CPU percent idle. Windows reports CPU percent busy.
+ tempStat = new Stat(tempName, tempName, "", "percent", CategoryServer, ContainerProcessor,
+ StatType.Pull, (s) => { GetNextValue(s, processorPercentPerfCounter, Util.IsWindows() ? 1 : -1); },
+ StatVerbosity.Info);
+ StatsManager.RegisterStat(tempStat);
+ RegisteredStats.Add(tempName, tempStat);
+
+ MakeStat("TotalProcessorTime", null, "sec", ContainerProcessor,
+ (s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; });
+
+ MakeStat("UserProcessorTime", null, "sec", ContainerProcessor,
+ (s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; });
+
+ MakeStat("PrivilegedProcessorTime", null, "sec", ContainerProcessor,
+ (s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; });
+
+ MakeStat("Threads", null, "threads", ContainerProcessor,
+ (s) => { s.Value = Process.GetCurrentProcess().Threads.Count; });
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat("{0} Exception creating 'Process': {1}", LogHeader, e);
+ }
+
+ MakeStat("BuiltinThreadpoolWorkerThreadsAvailable", null, "threads", ContainerThreadpool,
+ s =>
+ {
+ int workerThreads, iocpThreads;
+ ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads);
+ s.Value = workerThreads;
+ });
+
+ MakeStat("BuiltinThreadpoolIOCPThreadsAvailable", null, "threads", ContainerThreadpool,
+ s =>
+ {
+ int workerThreads, iocpThreads;
+ ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads);
+ s.Value = iocpThreads;
+ });
+
+ if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool && Util.GetSmartThreadPoolInfo() != null)
+ {
+ MakeStat("STPMaxThreads", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().MaxThreads);
+ MakeStat("STPMinThreads", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().MinThreads);
+ MakeStat("STPConcurrency", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().MaxConcurrentWorkItems);
+ MakeStat("STPActiveThreads", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().ActiveThreads);
+ MakeStat("STPInUseThreads", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().InUseThreads);
+ MakeStat("STPWorkItemsWaiting", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().WaitingCallbacks);
+ }
+
+ MakeStat(
+ "HTTPRequestsMade",
+ "Number of outbound HTTP requests made",
+ "requests",
+ ContainerNetwork,
+ s => s.Value = WebUtil.RequestNumber,
+ MeasuresOfInterest.AverageChangeOverTime);
+
+ try
+ {
+ List okInterfaceTypes = new List(NetworkInterfaceTypes.Split(','));
+
+ IEnumerable nics = NetworkInterface.GetAllNetworkInterfaces();
+ foreach (NetworkInterface nic in nics)
+ {
+ if (nic.OperationalStatus != OperationalStatus.Up)
+ continue;
+
+ string nicInterfaceType = nic.NetworkInterfaceType.ToString();
+ if (!okInterfaceTypes.Contains(nicInterfaceType))
+ {
+ m_log.DebugFormat("{0} Not including stats for network interface '{1}' of type '{2}'.",
+ LogHeader, nic.Name, nicInterfaceType);
+ m_log.DebugFormat("{0} To include, add to comma separated list in [Monitoring]NetworkInterfaceTypes={1}",
+ LogHeader, NetworkInterfaceTypes);
+ continue;
+ }
+
+ if (nic.Supports(NetworkInterfaceComponent.IPv4))
+ {
+ IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics();
+ if (nicStats != null)
+ {
+ MakeStat("BytesRcvd/" + nic.Name, nic.Name, "KB", ContainerNetwork,
+ (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); });
+ MakeStat("BytesSent/" + nic.Name, nic.Name, "KB", ContainerNetwork,
+ (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); });
+ MakeStat("TotalBytes/" + nic.Name, nic.Name, "KB", ContainerNetwork,
+ (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); });
+ }
+ }
+ // TODO: add IPv6 (it may actually happen someday)
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e);
+ }
+
+ MakeStat("ProcessMemory", null, "MB", ContainerMemory,
+ (s) => { s.Value = Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d, 3); });
+ MakeStat("HeapMemory", null, "MB", ContainerMemory,
+ (s) => { s.Value = Math.Round(GC.GetTotalMemory(false) / 1024d / 1024d, 3); });
+ MakeStat("LastHeapAllocationRate", null, "MB/sec", ContainerMemory,
+ (s) => { s.Value = Math.Round(MemoryWatchdog.LastHeapAllocationRate * 1000d / 1024d / 1024d, 3); });
+ MakeStat("AverageHeapAllocationRate", null, "MB/sec", ContainerMemory,
+ (s) => { s.Value = Math.Round(MemoryWatchdog.AverageHeapAllocationRate * 1000d / 1024d / 1024d, 3); });
+ }
+
+ // Notes on performance counters:
+ // "How To Read Performance Counters": http://blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx
+ // "How to get the CPU Usage in C#": http://stackoverflow.com/questions/278071/how-to-get-the-cpu-usage-in-c
+ // "Mono Performance Counters": http://www.mono-project.com/Mono_Performance_Counters
+ private delegate double PerfCounterNextValue();
+ private void GetNextValue(Stat stat, PerfCounterControl perfControl)
+ {
+ GetNextValue(stat, perfControl, 1.0);
+ }
+ private void GetNextValue(Stat stat, PerfCounterControl perfControl, double factor)
+ {
+ if (Util.EnvironmentTickCountSubtract(perfControl.lastFetch) > performanceCounterSampleInterval)
+ {
+ if (perfControl != null && perfControl.perfCounter != null)
+ {
+ try
+ {
+ // Kludge for factor to run double duty. If -1, subtract the value from one
+ if (factor == -1)
+ stat.Value = 1 - perfControl.perfCounter.NextValue();
+ else
+ stat.Value = perfControl.perfCounter.NextValue() / factor;
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat("{0} Exception on NextValue fetching {1}: {2}", LogHeader, stat.Name, e);
+ }
+ perfControl.lastFetch = Util.EnvironmentTickCount();
+ }
+ }
+ }
+
+ // Lookup the nic that goes with this stat and set the value by using a fetch action.
+ // Not sure about closure with delegates inside delegates.
+ private delegate double GetIPv4StatValue(IPv4InterfaceStatistics interfaceStat);
+ private void LookupNic(Stat stat, GetIPv4StatValue getter, double factor)
+ {
+ // Get the one nic that has the name of this stat
+ IEnumerable nics = NetworkInterface.GetAllNetworkInterfaces().Where(
+ (network) => network.Name == stat.Description);
+ try
+ {
+ foreach (NetworkInterface nic in nics)
+ {
+ IPv4InterfaceStatistics intrStats = nic.GetIPv4Statistics();
+ if (intrStats != null)
+ {
+ double newVal = Math.Round(getter(intrStats) / factor, 3);
+ stat.Value = newVal;
+ }
+ break;
+ }
+ }
+ catch
+ {
+ // There are times interfaces go away so we just won't update the stat for this
+ m_log.ErrorFormat("{0} Exception fetching stat on interface '{1}'", LogHeader, stat.Description);
+ }
+ }
+ }
+
+ public class ServerStatsAggregator : Stat
+ {
+ public ServerStatsAggregator(
+ string shortName,
+ string name,
+ string description,
+ string unitName,
+ string category,
+ string container
+ )
+ : base(
+ shortName,
+ name,
+ description,
+ unitName,
+ category,
+ container,
+ StatType.Push,
+ MeasuresOfInterest.None,
+ null,
+ StatVerbosity.Info)
+ {
+ }
+ public override string ToConsoleString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ return sb.ToString();
+ }
+
+ public override OSDMap ToOSDMap()
+ {
+ OSDMap ret = new OSDMap();
+
+ return ret;
+ }
+ }
+}
diff --git a/OpenSim/Framework/Monitoring/Stats/Stat.cs b/OpenSim/Framework/Monitoring/Stats/Stat.cs
index 2e7665f5a1..c57ee0c3e8 100644
--- a/OpenSim/Framework/Monitoring/Stats/Stat.cs
+++ b/OpenSim/Framework/Monitoring/Stats/Stat.cs
@@ -27,8 +27,10 @@
using System;
using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
using System.Text;
-
+using log4net;
using OpenMetaverse.StructuredData;
namespace OpenSim.Framework.Monitoring
@@ -38,6 +40,10 @@ namespace OpenSim.Framework.Monitoring
///
public class Stat : IDisposable
{
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ public static readonly char[] DisallowedShortNameCharacters = { '.' };
+
///
/// Category of this stat (e.g. cache, scene, etc).
///
@@ -95,7 +101,7 @@ namespace OpenSim.Framework.Monitoring
///
/// Will be null if no measures of interest require samples.
///
- private static Queue m_samples;
+ private Queue m_samples;
///
/// Maximum number of statistical samples.
@@ -162,6 +168,12 @@ namespace OpenSim.Framework.Monitoring
throw new Exception(
string.Format("Stat cannot be in category '{0}' since this is reserved for a subcommand", category));
+ foreach (char c in DisallowedShortNameCharacters)
+ {
+ if (shortName.IndexOf(c) != -1)
+ throw new Exception(string.Format("Stat name {0} cannot contain character {1}", shortName, c));
+ }
+
ShortName = shortName;
Name = name;
Description = description;
@@ -204,6 +216,8 @@ namespace OpenSim.Framework.Monitoring
if (m_samples.Count >= m_maxSamples)
m_samples.Dequeue();
+// m_log.DebugFormat("[STAT]: Recording value {0} for {1}", newValue, Name);
+
m_samples.Enqueue(newValue);
}
}
@@ -242,6 +256,10 @@ namespace OpenSim.Framework.Monitoring
lock (m_samples)
{
+// m_log.DebugFormat(
+// "[STAT]: Samples for {0} are {1}",
+// Name, string.Join(",", m_samples.Select(s => s.ToString()).ToArray()));
+
foreach (double s in m_samples)
{
if (lastSample != null)
@@ -253,7 +271,7 @@ namespace OpenSim.Framework.Monitoring
int divisor = m_samples.Count <= 1 ? 1 : m_samples.Count - 1;
- sb.AppendFormat(", {0:0.##}{1}/s", totalChange / divisor / (Watchdog.WATCHDOG_INTERVAL_MS / 1000), UnitName);
+ sb.AppendFormat(", {0:0.##} {1}/s", totalChange / divisor / (Watchdog.WATCHDOG_INTERVAL_MS / 1000), UnitName);
}
}
}
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 24db6d44c0..12d3a75d50 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -27,6 +27,7 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Text;
namespace OpenSim.Framework.Monitoring
@@ -54,13 +55,13 @@ namespace OpenSim.Framework.Monitoring
public static SortedDictionary>> RegisteredStats
= new SortedDictionary>>();
- private static AssetStatsCollector assetStats;
- private static UserStatsCollector userStats;
- private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
+// private static AssetStatsCollector assetStats;
+// private static UserStatsCollector userStats;
+// private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
- public static AssetStatsCollector AssetStats { get { return assetStats; } }
- public static UserStatsCollector UserStats { get { return userStats; } }
- public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
+// public static AssetStatsCollector AssetStats { get { return assetStats; } }
+// public static UserStatsCollector UserStats { get { return userStats; } }
+ public static SimExtraStatsCollector SimExtraStats { get; set; }
public static void RegisterConsoleCommands(ICommandConsole console)
{
@@ -68,12 +69,14 @@ namespace OpenSim.Framework.Monitoring
"General",
false,
"show stats",
- "show stats [list|all|]",
+ "show stats [list|all|([.])+",
"Show statistical information for this server",
"If no final argument is specified then legacy statistics information is currently shown.\n"
- + "If list is specified then statistic categories are shown.\n"
- + "If all is specified then all registered statistics are shown.\n"
- + "If a category name is specified then only statistics from that category are shown.\n"
+ + "'list' argument will show statistic categories.\n"
+ + "'all' will show all statistics.\n"
+ + "A name will show statistics from that category.\n"
+ + "A . name will show statistics from that category in that container.\n"
+ + "More than one name can be given separated by spaces.\n"
+ "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS",
HandleShowStatsCommand);
}
@@ -84,43 +87,47 @@ namespace OpenSim.Framework.Monitoring
if (cmd.Length > 2)
{
- var categoryName = cmd[2];
- var containerName = cmd.Length > 3 ? cmd[3] : String.Empty;
+ foreach (string name in cmd.Skip(2))
+ {
+ string[] components = name.Split('.');
- if (categoryName == AllSubCommand)
- {
- foreach (var category in RegisteredStats.Values)
+ string categoryName = components[0];
+ string containerName = components.Length > 1 ? components[1] : null;
+
+ if (categoryName == AllSubCommand)
{
- OutputCategoryStatsToConsole(con, category);
+ OutputAllStatsToConsole(con);
}
- }
- else if (categoryName == ListSubCommand)
- {
- con.Output("Statistic categories available are:");
- foreach (string category in RegisteredStats.Keys)
- con.OutputFormat(" {0}", category);
- }
- else
- {
- SortedDictionary> category;
- if (!RegisteredStats.TryGetValue(categoryName, out category))
+ else if (categoryName == ListSubCommand)
{
- con.OutputFormat("No such category as {0}", categoryName);
+ con.Output("Statistic categories available are:");
+ foreach (string category in RegisteredStats.Keys)
+ con.OutputFormat(" {0}", category);
}
else
{
- if (String.IsNullOrEmpty(containerName))
- OutputCategoryStatsToConsole(con, category);
+ SortedDictionary> category;
+ if (!RegisteredStats.TryGetValue(categoryName, out category))
+ {
+ con.OutputFormat("No such category as {0}", categoryName);
+ }
else
{
- SortedDictionary container;
- if (category.TryGetValue(containerName, out container))
+ if (String.IsNullOrEmpty(containerName))
{
- OutputContainerStatsToConsole(con, container);
+ OutputCategoryStatsToConsole(con, category);
}
else
{
- con.OutputFormat("No such container {0} in category {1}", containerName, categoryName);
+ SortedDictionary container;
+ if (category.TryGetValue(containerName, out container))
+ {
+ OutputContainerStatsToConsole(con, container);
+ }
+ else
+ {
+ con.OutputFormat("No such container {0} in category {1}", containerName, categoryName);
+ }
}
}
}
@@ -129,7 +136,18 @@ namespace OpenSim.Framework.Monitoring
else
{
// Legacy
- con.Output(SimExtraStats.Report());
+ if (SimExtraStats != null)
+ con.Output(SimExtraStats.Report());
+ else
+ OutputAllStatsToConsole(con);
+ }
+ }
+
+ private static void OutputAllStatsToConsole(ICommandConsole con)
+ {
+ foreach (var category in RegisteredStats.Values)
+ {
+ OutputCategoryStatsToConsole(con, category);
}
}
@@ -150,27 +168,27 @@ namespace OpenSim.Framework.Monitoring
}
}
- ///
- /// Start collecting statistics related to assets.
- /// Should only be called once.
- ///
- public static AssetStatsCollector StartCollectingAssetStats()
- {
- assetStats = new AssetStatsCollector();
-
- return assetStats;
- }
-
- ///
- /// Start collecting statistics related to users.
- /// Should only be called once.
- ///
- public static UserStatsCollector StartCollectingUserStats()
- {
- userStats = new UserStatsCollector();
-
- return userStats;
- }
+// ///
+// /// Start collecting statistics related to assets.
+// /// Should only be called once.
+// ///
+// public static AssetStatsCollector StartCollectingAssetStats()
+// {
+// assetStats = new AssetStatsCollector();
+//
+// return assetStats;
+// }
+//
+// ///
+// /// Start collecting statistics related to users.
+// /// Should only be called once.
+// ///
+// public static UserStatsCollector StartCollectingUserStats()
+// {
+// userStats = new UserStatsCollector();
+//
+// return userStats;
+// }
///
/// Registers a statistic.
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index 035b3ad180..4ab6908e90 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -86,25 +86,22 @@ namespace OpenSim.Framework.Servers
///
protected virtual void StartupSpecific()
{
- if (m_console == null)
- return;
-
+ StatsManager.SimExtraStats = new SimExtraStatsCollector();
RegisterCommonCommands();
-
- m_console.Commands.AddCommand("General", false, "quit",
- "quit",
- "Quit the application", HandleQuit);
+ RegisterCommonComponents(Config);
+ }
- m_console.Commands.AddCommand("General", false, "shutdown",
- "shutdown",
- "Quit the application", HandleQuit);
+ protected override void ShutdownSpecific()
+ {
+ m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting...");
+
+ RemovePIDFile();
+
+ base.ShutdownSpecific();
+
+ Environment.Exit(0);
}
- ///
- /// Should be overriden and referenced by descendents if they need to perform extra shutdown processing
- ///
- public virtual void ShutdownSpecific() {}
-
///
/// Provides a list of help topics that are available. Overriding classes should append their topics to the
/// information returned when the base method is called.
@@ -143,25 +140,8 @@ namespace OpenSim.Framework.Servers
timeTaken.Minutes, timeTaken.Seconds);
}
- ///
- /// Should be overriden and referenced by descendents if they need to perform extra shutdown processing
- ///
- public virtual void Shutdown()
+ public string osSecret
{
- ShutdownSpecific();
-
- m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting...");
- RemovePIDFile();
-
- Environment.Exit(0);
- }
-
- private void HandleQuit(string module, string[] args)
- {
- Shutdown();
- }
-
- public string osSecret {
// Secret uuid for the simulator
get { return m_osSecret; }
}
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 96a030bba0..40b8c5c1ed 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -54,7 +54,6 @@ namespace OpenSim.Framework.Servers.HttpServer
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private HttpServerLogWriter httpserverlog = new HttpServerLogWriter();
-
///
/// This is a pending websocket request before it got an sucessful upgrade response.
/// The consumer must call handler.HandshakeAndUpgrade() to signal to the handler to
@@ -81,6 +80,11 @@ namespace OpenSim.Framework.Servers.HttpServer
///
public int RequestNumber { get; private set; }
+ ///
+ /// Statistic for holding number of requests processed.
+ ///
+ private Stat m_requestsProcessedStat;
+
private volatile int NotSocketErrors = 0;
public volatile bool HTTPDRunning = false;
@@ -436,9 +440,8 @@ namespace OpenSim.Framework.Servers.HttpServer
}
}
- public void OnHandleRequestIOThread(IHttpClientContext context, IHttpRequest request)
+ private void OnHandleRequestIOThread(IHttpClientContext context, IHttpRequest request)
{
-
OSHttpRequest req = new OSHttpRequest(context, request);
WebSocketRequestDelegate dWebSocketRequestDelegate = null;
lock (m_WebSocketHandlers)
@@ -454,8 +457,7 @@ namespace OpenSim.Framework.Servers.HttpServer
OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context);
resp.ReuseContext = true;
- HandleRequest(req, resp);
-
+ HandleRequest(req, resp);
// !!!HACK ALERT!!!
// There seems to be a bug in the underlying http code that makes subsequent requests
@@ -1824,6 +1826,21 @@ namespace OpenSim.Framework.Servers.HttpServer
// useful without inbound HTTP.
throw e;
}
+
+ m_requestsProcessedStat
+ = new Stat(
+ "HTTPRequestsServed",
+ "Number of inbound HTTP requests processed",
+ "",
+ "requests",
+ "httpserver",
+ Port.ToString(),
+ StatType.Pull,
+ MeasuresOfInterest.AverageChangeOverTime,
+ stat => stat.Value = RequestNumber,
+ StatVerbosity.Debug);
+
+ StatsManager.RegisterStat(m_requestsProcessedStat);
}
public void httpServerDisconnectMonitor(IHttpClientContext source, SocketError err)
@@ -1854,6 +1871,9 @@ namespace OpenSim.Framework.Servers.HttpServer
public void Stop()
{
HTTPDRunning = false;
+
+ StatsManager.DeregisterStat(m_requestsProcessedStat);
+
try
{
m_PollServiceManager.Stop();
diff --git a/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs b/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs
index ee96b47c69..de89e2e638 100644
--- a/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs
@@ -75,7 +75,7 @@ namespace OpenSim.Framework.Servers.HttpServer
///
/// This is a regular HTTP Request... This may be removed in the future.
///
- public event RegularHttpRequestDelegate OnRegularHttpRequest;
+// public event RegularHttpRequestDelegate OnRegularHttpRequest;
///
/// When the upgrade from a HTTP request to a Websocket is completed, this will be fired
@@ -304,15 +304,14 @@ namespace OpenSim.Framework.Servers.HttpServer
if (d != null)
d(this, new UpgradeCompletedEventArgs());
}
- catch (IOException fail)
+ catch (IOException)
{
Close(string.Empty);
}
- catch (ObjectDisposedException fail)
+ catch (ObjectDisposedException)
{
Close(string.Empty);
- }
-
+ }
}
///
@@ -414,8 +413,6 @@ namespace OpenSim.Framework.Servers.HttpServer
_socketState.Header = pheader;
}
-
-
if (_socketState.FrameComplete)
{
ProcessFrame(_socketState);
@@ -424,7 +421,6 @@ namespace OpenSim.Framework.Servers.HttpServer
_socketState.ExpectedBytes = 0;
}
-
}
}
else
@@ -457,8 +453,7 @@ namespace OpenSim.Framework.Servers.HttpServer
_socketState.ReceivedBytes.Clear();
_socketState.ExpectedBytes = 0;
// do some processing
- }
-
+ }
}
}
if (offset > 0)
@@ -477,13 +472,12 @@ namespace OpenSim.Framework.Servers.HttpServer
{
// We can't read the stream anymore...
}
-
}
- catch (IOException fail)
+ catch (IOException)
{
Close(string.Empty);
}
- catch (ObjectDisposedException fail)
+ catch (ObjectDisposedException)
{
Close(string.Empty);
}
diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs
index 2c4a687237..029b848946 100644
--- a/OpenSim/Framework/Servers/ServerBase.cs
+++ b/OpenSim/Framework/Servers/ServerBase.cs
@@ -62,6 +62,8 @@ namespace OpenSim.Framework.Servers
protected string m_pidFile = String.Empty;
+ protected ServerStatsCollector m_serverStatsCollector;
+
///
/// Server version information. Usually VersionInfo + information about git commit, operating system, etc.
///
@@ -259,6 +261,25 @@ namespace OpenSim.Framework.Servers
"force gc",
"Manually invoke runtime garbage collection. For debugging purposes",
HandleForceGc);
+
+ m_console.Commands.AddCommand(
+ "General", false, "quit",
+ "quit",
+ "Quit the application", (mod, args) => Shutdown());
+
+ m_console.Commands.AddCommand(
+ "General", false, "shutdown",
+ "shutdown",
+ "Quit the application", (mod, args) => Shutdown());
+
+ StatsManager.RegisterConsoleCommands(m_console);
+ }
+
+ public void RegisterCommonComponents(IConfigSource configSource)
+ {
+ m_serverStatsCollector = new ServerStatsCollector();
+ m_serverStatsCollector.Initialise(configSource);
+ m_serverStatsCollector.Start();
}
private void HandleForceGc(string module, string[] args)
@@ -646,7 +667,68 @@ namespace OpenSim.Framework.Servers
sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
sb.Append("Main threadpool (excluding script engine pools)\n");
- sb.Append(Util.GetThreadPoolReport());
+ sb.Append(GetThreadPoolReport());
+
+ return sb.ToString();
+ }
+
+ ///
+ /// Get a thread pool report.
+ ///
+ ///
+ public static string GetThreadPoolReport()
+ {
+ string threadPoolUsed = null;
+ int maxThreads = 0;
+ int minThreads = 0;
+ int allocatedThreads = 0;
+ int inUseThreads = 0;
+ int waitingCallbacks = 0;
+ int completionPortThreads = 0;
+
+ StringBuilder sb = new StringBuilder();
+ if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
+ {
+ STPInfo stpi = Util.GetSmartThreadPoolInfo();
+
+ // ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool.
+ if (stpi != null)
+ {
+ threadPoolUsed = "SmartThreadPool";
+ maxThreads = stpi.MaxThreads;
+ minThreads = stpi.MinThreads;
+ inUseThreads = stpi.InUseThreads;
+ allocatedThreads = stpi.ActiveThreads;
+ waitingCallbacks = stpi.WaitingCallbacks;
+ }
+ }
+ else if (
+ Util.FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem
+ || Util.FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
+ {
+ threadPoolUsed = "BuiltInThreadPool";
+ ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
+ ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
+ int availableThreads;
+ ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
+ inUseThreads = maxThreads - availableThreads;
+ allocatedThreads = -1;
+ waitingCallbacks = -1;
+ }
+
+ if (threadPoolUsed != null)
+ {
+ sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
+ sb.AppendFormat("Max threads : {0}\n", maxThreads);
+ sb.AppendFormat("Min threads : {0}\n", minThreads);
+ sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString());
+ sb.AppendFormat("In use threads : {0}\n", inUseThreads);
+ sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString());
+ }
+ else
+ {
+ sb.AppendFormat("Thread pool not used\n");
+ }
return sb.ToString();
}
@@ -698,5 +780,16 @@ namespace OpenSim.Framework.Servers
if (m_console != null)
m_console.OutputFormat(format, components);
}
+
+ public virtual void Shutdown()
+ {
+ m_serverStatsCollector.Close();
+ ShutdownSpecific();
+ }
+
+ ///
+ /// Should be overriden and referenced by descendents if they need to perform extra shutdown processing
+ ///
+ protected virtual void ShutdownSpecific() {}
}
}
\ No newline at end of file
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 7f0850fba0..ba6cc75e12 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -88,10 +88,31 @@ namespace OpenSim.Framework
Thread,
}
+ ///
+ /// Class for delivering SmartThreadPool statistical information
+ ///
+ ///
+ /// We do it this way so that we do not directly expose STP.
+ ///
+ public class STPInfo
+ {
+ public string Name { get; set; }
+ public STPStartInfo STPStartInfo { get; set; }
+ public WIGStartInfo WIGStartInfo { get; set; }
+ public bool IsIdle { get; set; }
+ public bool IsShuttingDown { get; set; }
+ public int MaxThreads { get; set; }
+ public int MinThreads { get; set; }
+ public int InUseThreads { get; set; }
+ public int ActiveThreads { get; set; }
+ public int WaitingCallbacks { get; set; }
+ public int MaxConcurrentWorkItems { get; set; }
+ }
+
///
/// Miscellaneous utility functions
///
- public class Util
+ public static class Util
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -1852,74 +1873,31 @@ namespace OpenSim.Framework
}
///
- /// Get a thread pool report.
+ /// Get information about the current state of the smart thread pool.
///
- ///
- public static string GetThreadPoolReport()
+ ///
+ /// null if this isn't the pool being used for non-scriptengine threads.
+ ///
+ public static STPInfo GetSmartThreadPoolInfo()
{
- string threadPoolUsed = null;
- int maxThreads = 0;
- int minThreads = 0;
- int allocatedThreads = 0;
- int inUseThreads = 0;
- int waitingCallbacks = 0;
- int completionPortThreads = 0;
+ if (m_ThreadPool == null)
+ return null;
- StringBuilder sb = new StringBuilder();
- if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
- {
- // ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool.
- if (m_ThreadPool != null)
- {
- threadPoolUsed = "SmartThreadPool";
- maxThreads = m_ThreadPool.MaxThreads;
- minThreads = m_ThreadPool.MinThreads;
- inUseThreads = m_ThreadPool.InUseThreads;
- allocatedThreads = m_ThreadPool.ActiveThreads;
- waitingCallbacks = m_ThreadPool.WaitingCallbacks;
- }
- }
- else if (
- FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem
- || FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
- {
- threadPoolUsed = "BuiltInThreadPool";
- ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
- ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
- int availableThreads;
- ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
- inUseThreads = maxThreads - availableThreads;
- allocatedThreads = -1;
- waitingCallbacks = -1;
- }
+ STPInfo stpi = new STPInfo();
+ stpi.Name = m_ThreadPool.Name;
+ stpi.STPStartInfo = m_ThreadPool.STPStartInfo;
+ stpi.IsIdle = m_ThreadPool.IsIdle;
+ stpi.IsShuttingDown = m_ThreadPool.IsShuttingdown;
+ stpi.MaxThreads = m_ThreadPool.MaxThreads;
+ stpi.MinThreads = m_ThreadPool.MinThreads;
+ stpi.InUseThreads = m_ThreadPool.InUseThreads;
+ stpi.ActiveThreads = m_ThreadPool.ActiveThreads;
+ stpi.WaitingCallbacks = m_ThreadPool.WaitingCallbacks;
+ stpi.MaxConcurrentWorkItems = m_ThreadPool.Concurrency;
- if (threadPoolUsed != null)
- {
- sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
- sb.AppendFormat("Max threads : {0}\n", maxThreads);
- sb.AppendFormat("Min threads : {0}\n", minThreads);
- sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString());
- sb.AppendFormat("In use threads : {0}\n", inUseThreads);
- sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString());
- }
- else
- {
- sb.AppendFormat("Thread pool not used\n");
- }
-
- return sb.ToString();
+ return stpi;
}
-// private static object SmartThreadPoolCallback(object o)
-// {
-// object[] array = (object[])o;
-// WaitCallback callback = (WaitCallback)array[0];
-// object obj = array[1];
-//
-// callback(obj);
-// return null;
-// }
-
#endregion FireAndForget Threading Pattern
///
diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs
index c3e7ec2e67..e451aa8148 100644
--- a/OpenSim/Region/Application/Application.cs
+++ b/OpenSim/Region/Application/Application.cs
@@ -124,6 +124,7 @@ namespace OpenSim
workerThreads = workerThreadsMax;
m_log.InfoFormat("[OPENSIM MAIN]: Limiting worker threads to {0}",workerThreads);
}
+
// Increase the number of IOCP threads available.
// Mono defaults to a tragically low number (24 on 6-core / 8GB Fedora 17)
if (iocpThreads < iocpThreadsMin)
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 11dd052a19..9325b12220 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -372,7 +372,7 @@ namespace OpenSim
"Unload a module", HandleModules);
}
- public override void ShutdownSpecific()
+ protected override void ShutdownSpecific()
{
if (m_shutdownCommandsFile != String.Empty)
{
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index f9e0cf1b49..7ca87a3134 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -231,10 +231,7 @@ namespace OpenSim
}
if (m_console != null)
- {
- StatsManager.RegisterConsoleCommands(m_console);
AddPluginCommands(m_console);
- }
}
protected virtual void AddPluginCommands(ICommandConsole console)
@@ -880,7 +877,7 @@ namespace OpenSim
///
/// Performs any last-minute sanity checking and shuts down the region server
///
- public override void ShutdownSpecific()
+ protected override void ShutdownSpecific()
{
if (proxyUrl.Length > 0)
{
@@ -900,6 +897,8 @@ namespace OpenSim
{
m_log.Error("[SHUTDOWN]: Ignoring failure during shutdown - ", e);
}
+
+ base.ShutdownSpecific();
}
///
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index 2024018aa3..0e3cd6b283 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -34,6 +34,7 @@ using log4net;
using Nini.Config;
using Mono.Addins;
using OpenMetaverse;
+using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers;
@@ -44,8 +45,6 @@ using OpenSim.Framework.Capabilities;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
using OpenSim.Capabilities.Handlers;
-using OpenMetaverse;
-using OpenMetaverse.StructuredData;
namespace OpenSim.Region.ClientStack.Linden
{
@@ -64,7 +63,7 @@ namespace OpenSim.Region.ClientStack.Linden
public List folders;
}
- private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
index 556df305ab..b47ff54efe 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
@@ -33,6 +33,7 @@ using NUnit.Framework;
using OpenMetaverse;
using OpenMetaverse.Packets;
using OpenSim.Framework;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
@@ -69,6 +70,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
{
base.SetUp();
m_scene = new SceneHelpers().SetupScene();
+ StatsManager.SimExtraStats = new SimExtraStatsCollector();
}
///
@@ -210,8 +212,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID);
Assert.That(spAfterAckTimeout, Is.Null);
-
-// TestHelpers.DisableLogging();
}
// ///
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index 7d763faf10..7f3d0a2584 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -182,7 +182,10 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
"POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
if (msglist == null)
+ {
m_log.WarnFormat("[OFFLINE MESSAGING]: WARNING null message list.");
+ return;
+ }
foreach (GridInstantMessage im in msglist)
{
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 02ed1a08e3..630d1c376f 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -53,8 +53,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private int m_levelHGTeleport = 0;
+ private string m_ThisHomeURI;
private GatekeeperServiceConnector m_GatekeeperConnector;
+ private IUserAgentService m_UAS;
protected bool m_RestrictAppearanceAbroad;
protected string m_AccountName;
@@ -143,6 +145,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name);
}
}
+
+ moduleConfig = source.Configs["Hypergrid"];
+ if (moduleConfig != null)
+ {
+ m_ThisHomeURI = moduleConfig.GetString("HomeURI", string.Empty);
+ if (m_ThisHomeURI != string.Empty && !m_ThisHomeURI.EndsWith("/"))
+ m_ThisHomeURI += '/';
+ }
}
public override void AddRegion(Scene scene)
@@ -194,7 +204,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
base.RegionLoaded(scene);
if (m_Enabled)
+ {
m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService);
+ m_UAS = scene.RequestModuleInterface();
+ }
}
public override void RemoveRegion(Scene scene)
@@ -272,8 +285,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (agentCircuit.ServiceURLs.ContainsKey("HomeURI"))
{
string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString();
- IUserAgentService connector = new UserAgentServiceConnector(userAgentDriver);
- bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason);
+ IUserAgentService connector;
+
+ if (userAgentDriver.Equals(m_ThisHomeURI) && m_UAS != null)
+ connector = m_UAS;
+ else
+ connector = new UserAgentServiceConnector(userAgentDriver);
+
+ bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, false, out reason);
logout = success; // flag for later logout from this grid; this is an HG TP
if (success)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
index b2a1b23279..d120e11c2c 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
@@ -194,7 +194,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return false;
// Try local first
- if (m_localBackend.IsLocalRegion(destination.RegionHandle))
+ if (m_localBackend.IsLocalRegion(destination.RegionID))
return m_localBackend.UpdateAgent(destination, cAgentData);
return m_remoteConnector.UpdateAgent(destination, cAgentData);
@@ -206,7 +206,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return false;
// Try local first
- if (m_localBackend.IsLocalRegion(destination.RegionHandle))
+ if (m_localBackend.IsLocalRegion(destination.RegionID))
return m_localBackend.UpdateAgent(destination, cAgentData);
return m_remoteConnector.UpdateAgent(destination, cAgentData);
@@ -224,7 +224,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return true;
// else do the remote thing
- if (!m_localBackend.IsLocalRegion(destination.RegionHandle))
+ if (!m_localBackend.IsLocalRegion(destination.RegionID))
return m_remoteConnector.RetrieveAgent(destination, id, out agent);
return false;
@@ -273,7 +273,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return true;
// else do the remote thing
- if (!m_localBackend.IsLocalRegion(destination.RegionHandle))
+ if (!m_localBackend.IsLocalRegion(destination.RegionID))
return m_remoteConnector.CloseAgent(destination, id);
return false;
@@ -296,7 +296,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
}
// else do the remote thing
- if (!m_localBackend.IsLocalRegion(destination.RegionHandle))
+ if (!m_localBackend.IsLocalRegion(destination.RegionID))
return m_remoteConnector.CreateObject(destination, newPosition, sog, isLocalCall);
return false;
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index 84064427e0..e55c9ed87f 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -81,14 +81,14 @@ namespace OpenSim.Region.CoreModules.World.Land
set { m_landData = value; }
}
-
+
public IPrimCounts PrimCounts { get; set; }
public UUID RegionUUID
{
get { return m_scene.RegionInfo.RegionID; }
}
-
+
public Vector3 StartPoint
{
get
@@ -101,11 +101,11 @@ namespace OpenSim.Region.CoreModules.World.Land
return new Vector3(x * 4, y * 4, 0);
}
}
-
+
return new Vector3(-1, -1, -1);
}
- }
-
+ }
+
public Vector3 EndPoint
{
get
@@ -116,15 +116,15 @@ namespace OpenSim.Region.CoreModules.World.Land
{
if (LandBitmap[x, y])
{
- return new Vector3(x * 4, y * 4, 0);
- }
+ return new Vector3(x * 4 + 4, y * 4 + 4, 0);
+ }
}
- }
-
+ }
+
return new Vector3(-1, -1, -1);
}
}
-
+
#region Constructors
public LandObject(UUID owner_id, bool is_group_owned, Scene scene)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 6c79b13e2e..1e4d558de5 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -326,7 +326,7 @@ namespace OpenSim.Region.Framework.Scenes
// Update item with new asset
item.AssetID = asset.FullID;
if (group.UpdateInventoryItem(item))
- remoteClient.SendAgentAlertMessage("Script saved", false);
+ remoteClient.SendAlertMessage("Script saved");
part.SendPropertiesToClient(remoteClient);
@@ -342,7 +342,7 @@ namespace OpenSim.Region.Framework.Scenes
}
else
{
- remoteClient.SendAgentAlertMessage("Script saved", false);
+ remoteClient.SendAlertMessage("Script saved");
}
// Tell anyone managing scripts that a script has been reloaded/changed
@@ -1616,11 +1616,11 @@ namespace OpenSim.Region.Framework.Scenes
remoteClient, part, transactionID, currentItem);
if ((InventoryType)itemInfo.InvType == InventoryType.Notecard)
- remoteClient.SendAgentAlertMessage("Notecard saved", false);
+ remoteClient.SendAlertMessage("Notecard saved");
else if ((InventoryType)itemInfo.InvType == InventoryType.LSL)
- remoteClient.SendAgentAlertMessage("Script saved", false);
+ remoteClient.SendAlertMessage("Script saved");
else
- remoteClient.SendAgentAlertMessage("Item saved", false);
+ remoteClient.SendAlertMessage("Item saved");
}
// Base ALWAYS has move
diff --git a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs
deleted file mode 100644
index 6e74ce0f50..0000000000
--- a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs
+++ /dev/null
@@ -1,339 +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;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Net.NetworkInformation;
-using System.Text;
-using System.Threading;
-
-using log4net;
-using Mono.Addins;
-using Nini.Config;
-
-using OpenSim.Framework;
-using OpenSim.Framework.Console;
-using OpenSim.Framework.Monitoring;
-using OpenSim.Region.Framework.Interfaces;
-using OpenSim.Region.Framework.Scenes;
-
-using OpenMetaverse.StructuredData;
-
-namespace OpenSim.Region.OptionalModules.Framework.Monitoring
-{
-[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ServerStatistics")]
-public class ServerStats : ISharedRegionModule
-{
- private readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
- private readonly string LogHeader = "[SERVER STATS]";
-
- public bool Enabled = false;
- private static Dictionary RegisteredStats = new Dictionary();
-
- public readonly string CategoryServer = "server";
-
- public readonly string ContainerProcessor = "processor";
- public readonly string ContainerMemory = "memory";
- public readonly string ContainerNetwork = "network";
- public readonly string ContainerProcess = "process";
-
- public string NetworkInterfaceTypes = "Ethernet";
-
- readonly int performanceCounterSampleInterval = 500;
- int lastperformanceCounterSampleTime = 0;
-
- private class PerfCounterControl
- {
- public PerformanceCounter perfCounter;
- public int lastFetch;
- public string name;
- public PerfCounterControl(PerformanceCounter pPc)
- : this(pPc, String.Empty)
- {
- }
- public PerfCounterControl(PerformanceCounter pPc, string pName)
- {
- perfCounter = pPc;
- lastFetch = 0;
- name = pName;
- }
- }
-
- PerfCounterControl processorPercentPerfCounter = null;
-
- #region ISharedRegionModule
- // IRegionModuleBase.Name
- public string Name { get { return "Server Stats"; } }
- // IRegionModuleBase.ReplaceableInterface
- public Type ReplaceableInterface { get { return null; } }
- // IRegionModuleBase.Initialize
- public void Initialise(IConfigSource source)
- {
- IConfig cfg = source.Configs["Monitoring"];
-
- if (cfg != null)
- Enabled = cfg.GetBoolean("ServerStatsEnabled", true);
-
- if (Enabled)
- {
- NetworkInterfaceTypes = cfg.GetString("NetworkInterfaceTypes", "Ethernet");
- }
- }
- // IRegionModuleBase.Close
- public void Close()
- {
- if (RegisteredStats.Count > 0)
- {
- foreach (Stat stat in RegisteredStats.Values)
- {
- StatsManager.DeregisterStat(stat);
- stat.Dispose();
- }
- RegisteredStats.Clear();
- }
- }
- // IRegionModuleBase.AddRegion
- public void AddRegion(Scene scene)
- {
- }
- // IRegionModuleBase.RemoveRegion
- public void RemoveRegion(Scene scene)
- {
- }
- // IRegionModuleBase.RegionLoaded
- public void RegionLoaded(Scene scene)
- {
- }
- // ISharedRegionModule.PostInitialize
- public void PostInitialise()
- {
- if (RegisteredStats.Count == 0)
- {
- RegisterServerStats();
- }
- }
- #endregion ISharedRegionModule
-
- private void MakeStat(string pName, string pDesc, string pUnit, string pContainer, Action act)
- {
- string desc = pDesc;
- if (desc == null)
- desc = pName;
- Stat stat = new Stat(pName, pName, desc, pUnit, CategoryServer, pContainer, StatType.Pull, act, StatVerbosity.Info);
- StatsManager.RegisterStat(stat);
- RegisteredStats.Add(pName, stat);
- }
-
- public void RegisterServerStats()
- {
- lastperformanceCounterSampleTime = Util.EnvironmentTickCount();
- PerformanceCounter tempPC;
- Stat tempStat;
- string tempName;
-
- try
- {
- tempName = "CPUPercent";
- tempPC = new PerformanceCounter("Processor", "% Processor Time", "_Total");
- processorPercentPerfCounter = new PerfCounterControl(tempPC);
- // A long time bug in mono is that CPU percent is reported as CPU percent idle. Windows reports CPU percent busy.
- tempStat = new Stat(tempName, tempName, "", "percent", CategoryServer, ContainerProcessor,
- StatType.Pull, (s) => { GetNextValue(s, processorPercentPerfCounter, Util.IsWindows() ? 1 : -1); },
- StatVerbosity.Info);
- StatsManager.RegisterStat(tempStat);
- RegisteredStats.Add(tempName, tempStat);
-
- MakeStat("TotalProcessorTime", null, "sec", ContainerProcessor,
- (s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; });
-
- MakeStat("UserProcessorTime", null, "sec", ContainerProcessor,
- (s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; });
-
- MakeStat("PrivilegedProcessorTime", null, "sec", ContainerProcessor,
- (s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; });
-
- MakeStat("Threads", null, "threads", ContainerProcessor,
- (s) => { s.Value = Process.GetCurrentProcess().Threads.Count; });
- }
- catch (Exception e)
- {
- m_log.ErrorFormat("{0} Exception creating 'Process': {1}", LogHeader, e);
- }
-
- try
- {
- List okInterfaceTypes = new List(NetworkInterfaceTypes.Split(','));
-
- IEnumerable nics = NetworkInterface.GetAllNetworkInterfaces();
- foreach (NetworkInterface nic in nics)
- {
- if (nic.OperationalStatus != OperationalStatus.Up)
- continue;
-
- string nicInterfaceType = nic.NetworkInterfaceType.ToString();
- if (!okInterfaceTypes.Contains(nicInterfaceType))
- {
- m_log.DebugFormat("{0} Not including stats for network interface '{1}' of type '{2}'.",
- LogHeader, nic.Name, nicInterfaceType);
- m_log.DebugFormat("{0} To include, add to comma separated list in [Monitoring]NetworkInterfaceTypes={1}",
- LogHeader, NetworkInterfaceTypes);
- continue;
- }
-
- if (nic.Supports(NetworkInterfaceComponent.IPv4))
- {
- IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics();
- if (nicStats != null)
- {
- MakeStat("BytesRcvd/" + nic.Name, nic.Name, "KB", ContainerNetwork,
- (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); });
- MakeStat("BytesSent/" + nic.Name, nic.Name, "KB", ContainerNetwork,
- (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); });
- MakeStat("TotalBytes/" + nic.Name, nic.Name, "KB", ContainerNetwork,
- (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); });
- }
- }
- // TODO: add IPv6 (it may actually happen someday)
- }
- }
- catch (Exception e)
- {
- m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e);
- }
-
- MakeStat("ProcessMemory", null, "MB", ContainerMemory,
- (s) => { s.Value = Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d; });
- MakeStat("ObjectMemory", null, "MB", ContainerMemory,
- (s) => { s.Value = GC.GetTotalMemory(false) / 1024d / 1024d; });
- MakeStat("LastMemoryChurn", null, "MB/sec", ContainerMemory,
- (s) => { s.Value = Math.Round(MemoryWatchdog.LastMemoryChurn * 1000d / 1024d / 1024d, 3); });
- MakeStat("AverageMemoryChurn", null, "MB/sec", ContainerMemory,
- (s) => { s.Value = Math.Round(MemoryWatchdog.AverageMemoryChurn * 1000d / 1024d / 1024d, 3); });
- }
-
- // Notes on performance counters:
- // "How To Read Performance Counters": http://blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx
- // "How to get the CPU Usage in C#": http://stackoverflow.com/questions/278071/how-to-get-the-cpu-usage-in-c
- // "Mono Performance Counters": http://www.mono-project.com/Mono_Performance_Counters
- private delegate double PerfCounterNextValue();
- private void GetNextValue(Stat stat, PerfCounterControl perfControl)
- {
- GetNextValue(stat, perfControl, 1.0);
- }
- private void GetNextValue(Stat stat, PerfCounterControl perfControl, double factor)
- {
- if (Util.EnvironmentTickCountSubtract(perfControl.lastFetch) > performanceCounterSampleInterval)
- {
- if (perfControl != null && perfControl.perfCounter != null)
- {
- try
- {
- // Kludge for factor to run double duty. If -1, subtract the value from one
- if (factor == -1)
- stat.Value = 1 - perfControl.perfCounter.NextValue();
- else
- stat.Value = perfControl.perfCounter.NextValue() / factor;
- }
- catch (Exception e)
- {
- m_log.ErrorFormat("{0} Exception on NextValue fetching {1}: {2}", LogHeader, stat.Name, e);
- }
- perfControl.lastFetch = Util.EnvironmentTickCount();
- }
- }
- }
-
- // Lookup the nic that goes with this stat and set the value by using a fetch action.
- // Not sure about closure with delegates inside delegates.
- private delegate double GetIPv4StatValue(IPv4InterfaceStatistics interfaceStat);
- private void LookupNic(Stat stat, GetIPv4StatValue getter, double factor)
- {
- // Get the one nic that has the name of this stat
- IEnumerable nics = NetworkInterface.GetAllNetworkInterfaces().Where(
- (network) => network.Name == stat.Description);
- try
- {
- foreach (NetworkInterface nic in nics)
- {
- IPv4InterfaceStatistics intrStats = nic.GetIPv4Statistics();
- if (intrStats != null)
- {
- double newVal = Math.Round(getter(intrStats) / factor, 3);
- stat.Value = newVal;
- }
- break;
- }
- }
- catch
- {
- // There are times interfaces go away so we just won't update the stat for this
- m_log.ErrorFormat("{0} Exception fetching stat on interface '{1}'", LogHeader, stat.Description);
- }
- }
-}
-
-public class ServerStatsAggregator : Stat
-{
- public ServerStatsAggregator(
- string shortName,
- string name,
- string description,
- string unitName,
- string category,
- string container
- )
- : base(
- shortName,
- name,
- description,
- unitName,
- category,
- container,
- StatType.Push,
- MeasuresOfInterest.None,
- null,
- StatVerbosity.Info)
- {
- }
- public override string ToConsoleString()
- {
- StringBuilder sb = new StringBuilder();
-
- return sb.ToString();
- }
-
- public override OSDMap ToOSDMap()
- {
- OSDMap ret = new OSDMap();
-
- return ret;
- }
-}
-
-}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
index ac8c30c9cd..928b350645 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
@@ -43,8 +43,14 @@ public class BSActorAvatarMove : BSActor
// Set to true if we think we're going up stairs.
// This state is remembered because collisions will turn on and off as we go up stairs.
int m_walkingUpStairs;
+ // The amount the step up is applying. Used to smooth stair walking.
float m_lastStepUp;
+ // Jumping happens over several frames. If use applies up force while colliding, start the
+ // jump and allow the jump to continue for this number of frames.
+ int m_jumpFrames = 0;
+ float m_jumpVelocity = 0f;
+
public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName)
: base(physicsScene, pObj, actorName)
{
@@ -206,17 +212,45 @@ public class BSActorAvatarMove : BSActor
if (m_controllingPrim.Friction != BSParam.AvatarFriction)
{
- // Probably starting up walking. Set friction to moving friction.
+ // Probably starting to walk. Set friction to moving friction.
m_controllingPrim.Friction = BSParam.AvatarFriction;
m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction);
}
- // If falling, we keep the world's downward vector no matter what the other axis specify.
- // The check for RawVelocity.Z < 0 makes jumping work (temporary upward force).
if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding)
{
- if (m_controllingPrim.RawVelocity.Z < 0)
+ stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
+ }
+
+
+ // Colliding and not flying with an upward force. The avatar must be trying to jump.
+ if (!m_controllingPrim.Flying && m_controllingPrim.IsColliding && stepVelocity.Z > 0)
+ {
+ // We allow the upward force to happen for this many frames.
+ m_jumpFrames = BSParam.AvatarJumpFrames;
+ m_jumpVelocity = stepVelocity.Z;
+ }
+
+ // The case where the avatar is not colliding and is not flying is special.
+ // The avatar is either falling or jumping and the user can be applying force to the avatar
+ // (force in some direction or force up or down).
+ // If the avatar has negative Z velocity and is not colliding, presume we're falling and keep the velocity.
+ // If the user is trying to apply upward force but we're not colliding, assume the avatar
+ // is trying to jump and don't apply the upward force if not touching the ground any more.
+ if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding)
+ {
+ // If upward velocity is being applied, this must be a jump and only allow that to go on so long
+ if (m_jumpFrames > 0)
+ {
+ // Since not touching the ground, only apply upward force for so long.
+ m_jumpFrames--;
+ stepVelocity.Z = m_jumpVelocity;
+ }
+ else
+ {
+ // Since we're not affected by anything, whatever vertical motion the avatar has, continue that.
stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
+ }
// DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
}
@@ -241,7 +275,7 @@ public class BSActorAvatarMove : BSActor
m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4},avHeight={5}",
m_controllingPrim.LocalID, m_controllingPrim.IsColliding, m_controllingPrim.Flying,
m_controllingPrim.TargetVelocitySpeed, m_controllingPrim.CollisionsLastTick.Count, m_controllingPrim.Size.Z);
- // This test is done if moving forward, not flying and is colliding with something.
+
// Check for stairs climbing if colliding, not flying and moving forward
if ( m_controllingPrim.IsColliding
&& !m_controllingPrim.Flying
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 311cf4f220..07e87d13eb 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -209,7 +209,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
m_VhoverTimescale = Math.Max(pValue, 0.01f);
break;
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
- m_linearDeflectionEfficiency = Math.Max(pValue, 0.01f);
+ m_linearDeflectionEfficiency = ClampInRange(0f, pValue, 1f);
break;
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
m_linearDeflectionTimescale = Math.Max(pValue, 0.01f);
@@ -707,7 +707,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
private Vector3 m_knownRotationalVelocity;
private Vector3 m_knownRotationalForce;
private Vector3 m_knownRotationalImpulse;
- private Vector3 m_knownForwardVelocity; // vehicle relative forward speed
private const int m_knownChangedPosition = 1 << 0;
private const int m_knownChangedVelocity = 1 << 1;
@@ -719,7 +718,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
private const int m_knownChangedRotationalImpulse = 1 << 7;
private const int m_knownChangedTerrainHeight = 1 << 8;
private const int m_knownChangedWaterLevel = 1 << 9;
- private const int m_knownChangedForwardVelocity = 1 <<10;
public void ForgetKnownVehicleProperties()
{
@@ -923,12 +921,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{
get
{
- if ((m_knownHas & m_knownChangedForwardVelocity) == 0)
- {
- m_knownForwardVelocity = VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation));
- m_knownHas |= m_knownChangedForwardVelocity;
- }
- return m_knownForwardVelocity;
+ return VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation));
}
}
private float VehicleForwardSpeed
@@ -981,6 +974,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{
ComputeLinearVelocity(pTimestep);
+ ComputeLinearDeflection(pTimestep);
+
ComputeLinearTerrainHeightCorrection(pTimestep);
ComputeLinearHover(pTimestep);
@@ -1026,12 +1021,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{
// Step the motor from the current value. Get the correction needed this step.
Vector3 origVelW = VehicleVelocity; // DEBUG
- Vector3 currentVelV = VehicleVelocity * Quaternion.Inverse(VehicleOrientation);
+ Vector3 currentVelV = VehicleForwardVelocity;
Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVelV);
- // Friction reduces vehicle motion
- Vector3 frictionFactorW = ComputeFrictionFactor(m_linearFrictionTimescale, pTimestep);
- linearMotorCorrectionV -= (currentVelV * frictionFactorW);
+ // Friction reduces vehicle motion based on absolute speed. Slow vehicle down by friction.
+ Vector3 frictionFactorV = ComputeFrictionFactor(m_linearFrictionTimescale, pTimestep);
+ linearMotorCorrectionV -= (currentVelV * frictionFactorV);
// Motor is vehicle coordinates. Rotate it to world coordinates
Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation;
@@ -1046,11 +1041,38 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Add this correction to the velocity to make it faster/slower.
VehicleVelocity += linearMotorVelocityW;
-
-
VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5},fricFact={6}",
ControllingPrim.LocalID, origVelW, currentVelV, linearMotorCorrectionV,
- linearMotorVelocityW, VehicleVelocity, frictionFactorW);
+ linearMotorVelocityW, VehicleVelocity, frictionFactorV);
+ }
+
+ //Given a Deflection Effiency and a Velocity, Returns a Velocity that is Partially Deflected onto the X Axis
+ //Clamped so that a DeflectionTimescale of less then 1 does not increase force over original velocity
+ private void ComputeLinearDeflection(float pTimestep)
+ {
+ Vector3 linearDeflectionV = Vector3.Zero;
+ Vector3 velocityV = VehicleForwardVelocity;
+
+ // Velocity in Y and Z dimensions is movement to the side or turning.
+ // Compute deflection factor from the to the side and rotational velocity
+ linearDeflectionV.Y = SortedClampInRange(0, (velocityV.Y * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Y);
+ linearDeflectionV.Z = SortedClampInRange(0, (velocityV.Z * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Z);
+
+ // Velocity to the side and around is corrected and moved into the forward direction
+ linearDeflectionV.X += Math.Abs(linearDeflectionV.Y);
+ linearDeflectionV.X += Math.Abs(linearDeflectionV.Z);
+
+ // Scale the deflection to the fractional simulation time
+ linearDeflectionV *= pTimestep;
+
+ // Subtract the sideways and rotational velocity deflection factors while adding the correction forward
+ linearDeflectionV *= new Vector3(1,-1,-1);
+
+ // Correciont is vehicle relative. Convert to world coordinates and add to the velocity
+ VehicleVelocity += linearDeflectionV * VehicleOrientation;
+
+ VDetailLog("{0}, MoveLinear,LinearDeflection,linDefEff={1},linDefTS={2},linDeflectionV={3}",
+ ControllingPrim.LocalID, m_linearDeflectionEfficiency, m_linearDeflectionTimescale, linearDeflectionV);
}
public void ComputeLinearTerrainHeightCorrection(float pTimestep)
@@ -1652,6 +1674,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
return frictionFactor;
}
+ private float SortedClampInRange(float clampa, float val, float clampb)
+ {
+ if (clampa > clampb)
+ {
+ float temp = clampa;
+ clampa = clampb;
+ clampb = temp;
+ }
+ return ClampInRange(clampa, val, clampb);
+
+ }
+
private float ClampInRange(float low, float val, float high)
{
return Math.Max(low, Math.Min(val, high));
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index aad1108cbc..6437b04896 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -134,6 +134,7 @@ public static class BSParam
public static float AvatarHeightMidFudge { get; private set; }
public static float AvatarHeightHighFudge { get; private set; }
public static float AvatarContactProcessingThreshold { get; private set; }
+ public static int AvatarJumpFrames { get; private set; }
public static float AvatarBelowGroundUpCorrectionMeters { get; private set; }
public static float AvatarStepHeight { get; private set; }
public static float AvatarStepApproachFactor { get; private set; }
@@ -567,6 +568,8 @@ public static class BSParam
0.1f ),
new ParameterDefn("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground",
1.0f ),
+ new ParameterDefn("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.",
+ 4 ),
new ParameterDefn("AvatarStepHeight", "Height of a step obstacle to consider step correction",
0.6f ) ,
new ParameterDefn("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)",
diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs
index b13c87d000..667cef80c5 100644
--- a/OpenSim/Server/Base/ServicesServerBase.cs
+++ b/OpenSim/Server/Base/ServicesServerBase.cs
@@ -34,6 +34,7 @@ using System.Text;
using System.Xml;
using OpenSim.Framework;
using OpenSim.Framework.Console;
+using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers;
using log4net;
using log4net.Config;
@@ -190,16 +191,7 @@ namespace OpenSim.Server.Base
}
RegisterCommonCommands();
-
- // Register the quit command
- //
- MainConsole.Instance.Commands.AddCommand("General", false, "quit",
- "quit",
- "Quit the application", HandleQuit);
-
- MainConsole.Instance.Commands.AddCommand("General", false, "shutdown",
- "shutdown",
- "Quit the application", HandleQuit);
+ RegisterCommonComponents(Config);
// Allow derived classes to perform initialization that
// needs to be done after the console has opened
@@ -214,6 +206,9 @@ namespace OpenSim.Server.Base
public virtual int Run()
{
+ Watchdog.Enabled = true;
+ MemoryWatchdog.Enabled = true;
+
while (m_Running)
{
try
@@ -231,11 +226,12 @@ namespace OpenSim.Server.Base
return 0;
}
- protected virtual void HandleQuit(string module, string[] args)
+ protected override void ShutdownSpecific()
{
m_Running = false;
m_log.Info("[CONSOLE] Quitting");
+ base.ShutdownSpecific();
}
protected virtual void ReadConfig()
@@ -246,4 +242,4 @@ namespace OpenSim.Server.Base
{
}
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs b/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs
index cf1af15a37..adc2fbc081 100644
--- a/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
m_Proxy = proxy;
}
- protected override bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, out string reason)
+ protected override bool CreateAgent(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, bool fromLogin, out string reason)
{
return m_GatekeeperService.LoginAgent(aCircuit, destination, out reason);
}
diff --git a/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs b/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs
index 968c1e64c3..df875af14d 100644
--- a/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs
@@ -49,191 +49,87 @@ using log4net;
namespace OpenSim.Server.Handlers.Hypergrid
{
- public class HomeAgentHandler
+ public class HomeAgentHandler : AgentPostHandler
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IUserAgentService m_UserAgentService;
private string m_LoginServerIP;
- private bool m_Proxy = false;
- public HomeAgentHandler(IUserAgentService userAgentService, string loginServerIP, bool proxy)
+ public HomeAgentHandler(IUserAgentService userAgentService, string loginServerIP, bool proxy) :
+ base("/homeagent")
{
m_UserAgentService = userAgentService;
m_LoginServerIP = loginServerIP;
m_Proxy = proxy;
}
- public Hashtable Handler(Hashtable request)
+ protected override AgentDestinationData CreateAgentDestinationData()
{
-// m_log.Debug("[CONNECTION DEBUGGING]: HomeAgentHandler Called");
-//
-// m_log.Debug("---------------------------");
-// m_log.Debug(" >> uri=" + request["uri"]);
-// m_log.Debug(" >> content-type=" + request["content-type"]);
-// m_log.Debug(" >> http-method=" + request["http-method"]);
-// m_log.Debug("---------------------------\n");
-
- Hashtable responsedata = new Hashtable();
- responsedata["content_type"] = "text/html";
- responsedata["keepalive"] = false;
-
-
- UUID agentID;
- UUID regionID;
- string action;
- if (!Utils.GetParams((string)request["uri"], out agentID, out regionID, out action))
- {
- m_log.InfoFormat("[HOME AGENT HANDLER]: Invalid parameters for agent message {0}", request["uri"]);
- responsedata["int_response_code"] = 404;
- responsedata["str_response_string"] = "false";
-
- return responsedata;
- }
-
- // Next, let's parse the verb
- string method = (string)request["http-method"];
- if (method.Equals("POST"))
- {
- DoAgentPost(request, responsedata, agentID);
- return responsedata;
- }
- else
- {
- m_log.InfoFormat("[HOME AGENT HANDLER]: method {0} not supported in agent message", method);
- responsedata["int_response_code"] = HttpStatusCode.MethodNotAllowed;
- responsedata["str_response_string"] = "Method not allowed";
-
- return responsedata;
- }
-
+ return new ExtendedAgentDestinationData();
}
-
- protected void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id)
+ protected override void UnpackData(OSDMap args, AgentDestinationData d, Hashtable request)
{
- OSDMap args = Utils.GetOSDMap((string)request["body"]);
- if (args == null)
- {
- responsedata["int_response_code"] = HttpStatusCode.BadRequest;
- responsedata["str_response_string"] = "Bad request";
- return;
- }
-
- // retrieve the input arguments
- int x = 0, y = 0;
- UUID uuid = UUID.Zero;
- string regionname = string.Empty;
- string gatekeeper_host = string.Empty;
- string gatekeeper_serveruri = string.Empty;
- string destination_serveruri = string.Empty;
- int gatekeeper_port = 0;
- IPEndPoint client_ipaddress = null;
-
- if (args.ContainsKey("gatekeeper_host") && args["gatekeeper_host"] != null)
- gatekeeper_host = args["gatekeeper_host"].AsString();
- if (args.ContainsKey("gatekeeper_port") && args["gatekeeper_port"] != null)
- Int32.TryParse(args["gatekeeper_port"].AsString(), out gatekeeper_port);
- if (args.ContainsKey("gatekeeper_serveruri") && args["gatekeeper_serveruri"] !=null)
- gatekeeper_serveruri = args["gatekeeper_serveruri"];
- if (args.ContainsKey("destination_serveruri") && args["destination_serveruri"] !=null)
- destination_serveruri = args["destination_serveruri"];
-
- GridRegion gatekeeper = new GridRegion();
- gatekeeper.ServerURI = gatekeeper_serveruri;
- gatekeeper.ExternalHostName = gatekeeper_host;
- gatekeeper.HttpPort = (uint)gatekeeper_port;
- gatekeeper.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
-
- if (args.ContainsKey("destination_x") && args["destination_x"] != null)
- Int32.TryParse(args["destination_x"].AsString(), out x);
- else
- m_log.WarnFormat(" -- request didn't have destination_x");
- if (args.ContainsKey("destination_y") && args["destination_y"] != null)
- Int32.TryParse(args["destination_y"].AsString(), out y);
- else
- m_log.WarnFormat(" -- request didn't have destination_y");
- if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null)
- UUID.TryParse(args["destination_uuid"].AsString(), out uuid);
- if (args.ContainsKey("destination_name") && args["destination_name"] != null)
- regionname = args["destination_name"].ToString();
-
- if (args.ContainsKey("client_ip") && args["client_ip"] != null)
- {
- string ip_str = args["client_ip"].ToString();
- try
- {
- string callerIP = GetCallerIP(request);
- // Verify if this caller has authority to send the client IP
- if (callerIP == m_LoginServerIP)
- client_ipaddress = new IPEndPoint(IPAddress.Parse(ip_str), 0);
- else // leaving this for now, but this warning should be removed
- m_log.WarnFormat("[HOME AGENT HANDLER]: Unauthorized machine {0} tried to set client ip to {1}", callerIP, ip_str);
- }
- catch
- {
- m_log.DebugFormat("[HOME AGENT HANDLER]: Exception parsing client ip address from {0}", ip_str);
- }
- }
-
- GridRegion destination = new GridRegion();
- destination.RegionID = uuid;
- destination.RegionLocX = x;
- destination.RegionLocY = y;
- destination.RegionName = regionname;
- destination.ServerURI = destination_serveruri;
-
- AgentCircuitData aCircuit = new AgentCircuitData();
+ base.UnpackData(args, d, request);
+ ExtendedAgentDestinationData data = (ExtendedAgentDestinationData)d;
try
{
- aCircuit.UnpackAgentCircuitData(args);
+ if (args.ContainsKey("gatekeeper_host") && args["gatekeeper_host"] != null)
+ data.host = args["gatekeeper_host"].AsString();
+ if (args.ContainsKey("gatekeeper_port") && args["gatekeeper_port"] != null)
+ Int32.TryParse(args["gatekeeper_port"].AsString(), out data.port);
+ if (args.ContainsKey("gatekeeper_serveruri") && args["gatekeeper_serveruri"] != null)
+ data.gatekeeperServerURI = args["gatekeeper_serveruri"];
+ if (args.ContainsKey("destination_serveruri") && args["destination_serveruri"] != null)
+ data.destinationServerURI = args["destination_serveruri"];
+
}
- catch (Exception ex)
+ catch (InvalidCastException e)
{
- m_log.InfoFormat("[HOME AGENT HANDLER]: exception on unpacking ChildCreate message {0}", ex.Message);
- responsedata["int_response_code"] = HttpStatusCode.BadRequest;
- responsedata["str_response_string"] = "Bad request";
- return;
+ m_log.ErrorFormat("[HOME AGENT HANDLER]: Bad cast in UnpackData");
}
- OSDMap resp = new OSDMap(2);
- string reason = String.Empty;
+ string callerIP = GetCallerIP(request);
+ // Verify if this call came from the login server
+ if (callerIP == m_LoginServerIP)
+ data.fromLogin = true;
- bool result = m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, client_ipaddress, out reason);
-
- resp["reason"] = OSD.FromString(reason);
- resp["success"] = OSD.FromBoolean(result);
-
- // TODO: add reason if not String.Empty?
- responsedata["int_response_code"] = HttpStatusCode.OK;
- responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp);
}
- private string GetCallerIP(Hashtable request)
+ protected override GridRegion ExtractGatekeeper(AgentDestinationData d)
{
- if (!m_Proxy)
- return Util.GetCallerIP(request);
-
- // We're behind a proxy
- Hashtable headers = (Hashtable)request["headers"];
- string xff = "X-Forwarded-For";
- if (headers.ContainsKey(xff.ToLower()))
- xff = xff.ToLower();
-
- if (!headers.ContainsKey(xff) || headers[xff] == null)
+ if (d is ExtendedAgentDestinationData)
{
- m_log.WarnFormat("[AGENT HANDLER]: No XFF header");
- return Util.GetCallerIP(request);
+ ExtendedAgentDestinationData data = (ExtendedAgentDestinationData)d;
+ GridRegion gatekeeper = new GridRegion();
+ gatekeeper.ServerURI = data.gatekeeperServerURI;
+ gatekeeper.ExternalHostName = data.host;
+ gatekeeper.HttpPort = (uint)data.port;
+ gatekeeper.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
+
+ return gatekeeper;
}
+ else
+ m_log.WarnFormat("[HOME AGENT HANDLER]: Wrong data type");
- m_log.DebugFormat("[AGENT HANDLER]: XFF is {0}", headers[xff]);
-
- IPEndPoint ep = Util.GetClientIPFromXFF((string)headers[xff]);
- if (ep != null)
- return ep.Address.ToString();
-
- // Oops
- return Util.GetCallerIP(request);
+ return null;
}
+
+
+ protected override bool CreateAgent(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, bool fromLogin, out string reason)
+ {
+ return m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, fromLogin, out reason);
+ }
+
+ }
+
+ public class ExtendedAgentDestinationData : AgentDestinationData
+ {
+ public string host;
+ public int port;
+ public string gatekeeperServerURI;
+ public string destinationServerURI;
+
}
}
diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
index b20f4672db..d9c1bd3d52 100644
--- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
@@ -108,7 +108,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
server.AddXmlRPCHandler("get_uui", GetUUI, false);
server.AddXmlRPCHandler("get_uuid", GetUUID, false);
- server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler);
+ server.AddStreamHandler(new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy));
}
public XmlRpcResponse GetHomeRegion(XmlRpcRequest request, IPEndPoint remoteClient)
diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs
index ae37ca7d23..71a9e6fa41 100644
--- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs
+++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs
@@ -328,31 +328,16 @@ namespace OpenSim.Server.Handlers.Simulation
return;
}
- // retrieve the input arguments
- int x = 0, y = 0;
- UUID uuid = UUID.Zero;
- string regionname = string.Empty;
- uint teleportFlags = 0;
- if (args.ContainsKey("destination_x") && args["destination_x"] != null)
- Int32.TryParse(args["destination_x"].AsString(), out x);
- else
- m_log.WarnFormat(" -- request didn't have destination_x");
- if (args.ContainsKey("destination_y") && args["destination_y"] != null)
- Int32.TryParse(args["destination_y"].AsString(), out y);
- else
- m_log.WarnFormat(" -- request didn't have destination_y");
- if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null)
- UUID.TryParse(args["destination_uuid"].AsString(), out uuid);
- if (args.ContainsKey("destination_name") && args["destination_name"] != null)
- regionname = args["destination_name"].ToString();
- if (args.ContainsKey("teleport_flags") && args["teleport_flags"] != null)
- teleportFlags = args["teleport_flags"].AsUInteger();
+ AgentDestinationData data = CreateAgentDestinationData();
+ UnpackData(args, data, request);
GridRegion destination = new GridRegion();
- destination.RegionID = uuid;
- destination.RegionLocX = x;
- destination.RegionLocY = y;
- destination.RegionName = regionname;
+ destination.RegionID = data.uuid;
+ destination.RegionLocX = data.x;
+ destination.RegionLocY = data.y;
+ destination.RegionName = data.name;
+
+ GridRegion gatekeeper = ExtractGatekeeper(data);
AgentCircuitData aCircuit = new AgentCircuitData();
try
@@ -373,7 +358,7 @@ namespace OpenSim.Server.Handlers.Simulation
// This is the meaning of POST agent
//m_regionClient.AdjustUserInformation(aCircuit);
//bool result = m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason);
- bool result = CreateAgent(destination, aCircuit, teleportFlags, out reason);
+ bool result = CreateAgent(gatekeeper, destination, aCircuit, data.flags, data.fromLogin, out reason);
resp["reason"] = OSD.FromString(reason);
resp["success"] = OSD.FromBoolean(result);
@@ -385,7 +370,36 @@ namespace OpenSim.Server.Handlers.Simulation
responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp);
}
- private string GetCallerIP(Hashtable request)
+ protected virtual AgentDestinationData CreateAgentDestinationData()
+ {
+ return new AgentDestinationData();
+ }
+
+ protected virtual void UnpackData(OSDMap args, AgentDestinationData data, Hashtable request)
+ {
+ // retrieve the input arguments
+ if (args.ContainsKey("destination_x") && args["destination_x"] != null)
+ Int32.TryParse(args["destination_x"].AsString(), out data.x);
+ else
+ m_log.WarnFormat(" -- request didn't have destination_x");
+ if (args.ContainsKey("destination_y") && args["destination_y"] != null)
+ Int32.TryParse(args["destination_y"].AsString(), out data.y);
+ else
+ m_log.WarnFormat(" -- request didn't have destination_y");
+ if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null)
+ UUID.TryParse(args["destination_uuid"].AsString(), out data.uuid);
+ if (args.ContainsKey("destination_name") && args["destination_name"] != null)
+ data.name = args["destination_name"].ToString();
+ if (args.ContainsKey("teleport_flags") && args["teleport_flags"] != null)
+ data.flags = args["teleport_flags"].AsUInteger();
+ }
+
+ protected virtual GridRegion ExtractGatekeeper(AgentDestinationData data)
+ {
+ return null;
+ }
+
+ protected string GetCallerIP(Hashtable request)
{
if (!m_Proxy)
return Util.GetCallerIP(request);
@@ -418,7 +432,7 @@ namespace OpenSim.Server.Handlers.Simulation
}
// subclasses can override this
- protected virtual bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, out string reason)
+ protected virtual bool CreateAgent(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, bool fromLogin, out string reason)
{
return m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason);
}
@@ -562,7 +576,6 @@ namespace OpenSim.Server.Handlers.Simulation
//agent.Dump();
// This is one of the meanings of PUT agent
result = UpdateAgent(destination, agent);
-
}
else if ("AgentPosition".Equals(messageType))
{
@@ -593,4 +606,14 @@ namespace OpenSim.Server.Handlers.Simulation
return m_SimulationService.UpdateAgent(destination, agent);
}
}
+
+ public class AgentDestinationData
+ {
+ public int x;
+ public int y;
+ public string name;
+ public UUID uuid;
+ public uint flags;
+ public bool fromLogin;
+ }
}
diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
index 5bcff4883d..c9c6c31158 100644
--- a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
@@ -53,7 +53,8 @@ namespace OpenSim.Services.Connectors.Hypergrid
private IAssetService m_AssetService;
- public GatekeeperServiceConnector() : base()
+ public GatekeeperServiceConnector()
+ : base()
{
}
@@ -123,11 +124,13 @@ namespace OpenSim.Services.Connectors.Hypergrid
realHandle = Convert.ToUInt64((string)hash["handle"]);
//m_log.Debug(">> HERE, realHandle: " + realHandle);
}
- if (hash["region_image"] != null) {
+ if (hash["region_image"] != null)
+ {
imageURL = (string)hash["region_image"];
//m_log.Debug(">> HERE, imageURL: " + imageURL);
}
- if (hash["external_name"] != null) {
+ if (hash["external_name"] != null)
+ {
externalName = (string)hash["external_name"];
//m_log.Debug(">> HERE, externalName: " + externalName);
}
@@ -178,7 +181,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
//m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width);
imageData = OpenJPEG.EncodeFromImage(bitmap, true);
}
-
+
AssetBase ass = new AssetBase(UUID.Random(), "region " + name, (sbyte)AssetType.Texture, regionID.ToString());
// !!! for now
@@ -257,7 +260,8 @@ namespace OpenSim.Services.Connectors.Hypergrid
region.RegionName = (string)hash["region_name"];
//m_log.Debug(">> HERE, region_name: " + region.RegionName);
}
- if (hash["hostname"] != null) {
+ if (hash["hostname"] != null)
+ {
region.ExternalHostName = (string)hash["hostname"];
//m_log.Debug(">> HERE, hostname: " + region.ExternalHostName);
}
@@ -275,10 +279,10 @@ namespace OpenSim.Services.Connectors.Hypergrid
region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p);
//m_log.Debug(">> HERE, internal_port: " + region.InternalEndPoint);
}
-
+
if (hash["server_uri"] != null)
{
- region.ServerURI = (string) hash["server_uri"];
+ region.ServerURI = (string)hash["server_uri"];
//m_log.Debug(">> HERE, server_uri: " + region.ServerURI);
}
@@ -295,55 +299,5 @@ namespace OpenSim.Services.Connectors.Hypergrid
return null;
}
-
- public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string myipaddress, out string reason)
- {
- // m_log.DebugFormat("[GATEKEEPER SERVICE CONNECTOR]: CreateAgent start");
-
- myipaddress = String.Empty;
- reason = String.Empty;
-
- if (destination == null)
- {
- m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: Given destination is null");
- return false;
- }
-
- string uri = destination.ServerURI + AgentPath() + aCircuit.AgentID + "/";
-
- try
- {
- OSDMap args = aCircuit.PackAgentCircuitData();
-
- args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
- args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
- args["destination_name"] = OSD.FromString(destination.RegionName);
- args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
- args["teleport_flags"] = OSD.FromString(flags.ToString());
-
- OSDMap result = WebUtil.PostToService(uri, args, 80000);
- if (result["Success"].AsBoolean())
- {
- OSDMap unpacked = (OSDMap)result["_Result"];
-
- if (unpacked != null)
- {
- reason = unpacked["reason"].AsString();
- myipaddress = unpacked["your_ip"].AsString();
- return unpacked["success"].AsBoolean();
- }
- }
-
- reason = result["Message"] != null ? result["Message"].AsString() : "error";
- return false;
- }
- catch (Exception e)
- {
- m_log.Warn("[REMOTE SIMULATION CONNECTOR]: CreateAgent failed with exception: " + e.ToString());
- reason = e.Message;
- }
-
- return false;
- }
}
}
diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
index 47d0cce7fd..d8a3184780 100644
--- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
@@ -44,13 +44,14 @@ using Nini.Config;
namespace OpenSim.Services.Connectors.Hypergrid
{
- public class UserAgentServiceConnector : IUserAgentService
+ public class UserAgentServiceConnector : SimulationServiceConnector, IUserAgentService
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
- string m_ServerURL;
+ private string m_ServerURL;
+ private GridRegion m_Gatekeeper;
public UserAgentServiceConnector(string url) : this(url, true)
{
@@ -104,9 +105,15 @@ namespace OpenSim.Services.Connectors.Hypergrid
m_log.DebugFormat("[USER AGENT CONNECTOR]: UserAgentServiceConnector started for {0}", m_ServerURL);
}
+ protected override string AgentPath()
+ {
+ return "homeagent/";
+ }
- // The Login service calls this interface with a non-null [client] ipaddress
- public bool LoginAgentToGrid(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, IPEndPoint ipaddress, out string reason)
+ // The Login service calls this interface with fromLogin=true
+ // Sims call it with fromLogin=false
+ // Either way, this is verified by the handler
+ public bool LoginAgentToGrid(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, bool fromLogin, out string reason)
{
reason = String.Empty;
@@ -117,119 +124,34 @@ namespace OpenSim.Services.Connectors.Hypergrid
return false;
}
- string uri = m_ServerURL + "homeagent/" + aCircuit.AgentID + "/";
+ GridRegion home = new GridRegion();
+ home.ServerURI = m_ServerURL;
+ home.RegionID = destination.RegionID;
+ home.RegionLocX = destination.RegionLocX;
+ home.RegionLocY = destination.RegionLocY;
- Console.WriteLine(" >>> LoginAgentToGrid <<< " + uri);
+ m_Gatekeeper = gatekeeper;
- HttpWebRequest AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri);
- AgentCreateRequest.Method = "POST";
- AgentCreateRequest.ContentType = "application/json";
- AgentCreateRequest.Timeout = 10000;
- //AgentCreateRequest.KeepAlive = false;
- //AgentCreateRequest.Headers.Add("Authorization", authKey);
-
- // Fill it in
- OSDMap args = PackCreateAgentArguments(aCircuit, gatekeeper, destination, ipaddress);
-
- string strBuffer = "";
- byte[] buffer = new byte[1];
- try
- {
- strBuffer = OSDParser.SerializeJsonString(args);
- Encoding str = Util.UTF8;
- buffer = str.GetBytes(strBuffer);
-
- }
- catch (Exception e)
- {
- m_log.WarnFormat("[USER AGENT CONNECTOR]: Exception thrown on serialization of ChildCreate: {0}", e.Message);
- // ignore. buffer will be empty, caller should check.
- }
-
- Stream os = null;
- try
- { // send the Post
- AgentCreateRequest.ContentLength = buffer.Length; //Count bytes to send
- os = AgentCreateRequest.GetRequestStream();
- os.Write(buffer, 0, strBuffer.Length); //Send it
- m_log.InfoFormat("[USER AGENT CONNECTOR]: Posted CreateAgent request to remote sim {0}, region {1}, x={2} y={3}",
- uri, destination.RegionName, destination.RegionLocX, destination.RegionLocY);
- }
- //catch (WebException ex)
- catch
- {
- //m_log.InfoFormat("[USER AGENT CONNECTOR]: Bad send on ChildAgentUpdate {0}", ex.Message);
- reason = "cannot contact remote region";
- return false;
- }
- finally
- {
- if (os != null)
- os.Close();
- }
-
- // Let's wait for the response
- //m_log.Info("[USER AGENT CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall");
-
- try
- {
- using (WebResponse webResponse = AgentCreateRequest.GetResponse())
- {
- if (webResponse == null)
- {
- m_log.Info("[USER AGENT CONNECTOR]: Null reply on DoCreateChildAgentCall post");
- }
- else
- {
- using (Stream s = webResponse.GetResponseStream())
- {
- using (StreamReader sr = new StreamReader(s))
- {
- string response = sr.ReadToEnd().Trim();
- m_log.InfoFormat("[USER AGENT CONNECTOR]: DoCreateChildAgentCall reply was {0} ", response);
-
- if (!String.IsNullOrEmpty(response))
- {
- try
- {
- // we assume we got an OSDMap back
- OSDMap r = Util.GetOSDMap(response);
- bool success = r["success"].AsBoolean();
- reason = r["reason"].AsString();
- return success;
- }
- catch (NullReferenceException e)
- {
- m_log.InfoFormat("[USER AGENT CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", e.Message);
-
- // check for old style response
- if (response.ToLower().StartsWith("true"))
- return true;
-
- return false;
- }
- }
- }
- }
- }
- }
- }
- catch (WebException ex)
- {
- m_log.InfoFormat("[USER AGENT CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", ex.Message);
- reason = "Destination did not reply";
- return false;
- }
-
- return true;
+ Console.WriteLine(" >>> LoginAgentToGrid <<< " + home.ServerURI);
+ uint flags = fromLogin ? (uint)TeleportFlags.ViaLogin : (uint)TeleportFlags.ViaHome;
+ return CreateAgent(home, aCircuit, flags, out reason);
}
// The simulators call this interface
public bool LoginAgentToGrid(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, out string reason)
{
- return LoginAgentToGrid(aCircuit, gatekeeper, destination, null, out reason);
+ return LoginAgentToGrid(aCircuit, gatekeeper, destination, false, out reason);
+ }
+
+ protected override void PackData(OSDMap args, AgentCircuitData aCircuit, GridRegion destination, uint flags)
+ {
+ base.PackData(args, aCircuit, destination, flags);
+ args["gatekeeper_serveruri"] = OSD.FromString(m_Gatekeeper.ServerURI);
+ args["gatekeeper_host"] = OSD.FromString(m_Gatekeeper.ExternalHostName);
+ args["gatekeeper_port"] = OSD.FromString(m_Gatekeeper.HttpPort.ToString());
+ args["destination_serveruri"] = OSD.FromString(destination.ServerURI);
}
protected OSDMap PackCreateAgentArguments(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, IPEndPoint ipaddress)
diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
index 57f2ffa2d4..f51c809413 100644
--- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
@@ -79,11 +79,27 @@ namespace OpenSim.Services.Connectors.Simulation
return "agent/";
}
+ protected virtual void PackData(OSDMap args, AgentCircuitData aCircuit, GridRegion destination, uint flags)
+ {
+ args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
+ args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
+ args["destination_name"] = OSD.FromString(destination.RegionName);
+ args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
+ args["teleport_flags"] = OSD.FromString(flags.ToString());
+ }
+
public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string reason)
{
- // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: CreateAgent start");
-
+ string tmp = String.Empty;
+ return CreateAgent(destination, aCircuit, flags, out tmp, out reason);
+ }
+
+ public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string myipaddress, out string reason)
+ {
+ m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: Creating agent at {0}", destination.ServerURI);
reason = String.Empty;
+ myipaddress = String.Empty;
+
if (destination == null)
{
m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Given destination is null");
@@ -95,12 +111,7 @@ namespace OpenSim.Services.Connectors.Simulation
try
{
OSDMap args = aCircuit.PackAgentCircuitData();
-
- args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
- args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
- args["destination_name"] = OSD.FromString(destination.RegionName);
- args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
- args["teleport_flags"] = OSD.FromString(flags.ToString());
+ PackData(args, aCircuit, destination, flags);
OSDMap result = WebUtil.PostToServiceCompressed(uri, args, 30000);
bool success = result["success"].AsBoolean();
@@ -110,6 +121,7 @@ namespace OpenSim.Services.Connectors.Simulation
reason = data["reason"].AsString();
success = data["success"].AsBoolean();
+ myipaddress = data["your_ip"].AsString();
return success;
}
@@ -124,6 +136,7 @@ namespace OpenSim.Services.Connectors.Simulation
reason = data["reason"].AsString();
success = data["success"].AsBoolean();
+ myipaddress = data["your_ip"].AsString();
m_log.WarnFormat(
"[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName);
return success;
@@ -228,7 +241,7 @@ namespace OpenSim.Services.Connectors.Simulation
///
private bool UpdateAgent(GridRegion destination, IAgentData cAgentData, int timeout)
{
- // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: UpdateAgent start");
+ // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: UpdateAgent in {0}", destination.ServerURI);
// Eventually, we want to use a caps url instead of the agentID
string uri = destination.ServerURI + AgentPath() + cAgentData.AgentID + "/";
diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs
index 737e9c91af..733993fb04 100644
--- a/OpenSim/Services/HypergridService/UserAgentService.cs
+++ b/OpenSim/Services/HypergridService/UserAgentService.cs
@@ -210,10 +210,10 @@ namespace OpenSim.Services.HypergridService
return home;
}
- public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, IPEndPoint clientIP, out string reason)
+ public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason)
{
m_log.DebugFormat("[USER AGENT SERVICE]: Request to login user {0} {1} (@{2}) to grid {3}",
- agentCircuit.firstname, agentCircuit.lastname, ((clientIP == null) ? "stored IP" : clientIP.Address.ToString()), gatekeeper.ServerURI);
+ agentCircuit.firstname, agentCircuit.lastname, (fromLogin ? agentCircuit.IPAddress : "stored IP"), gatekeeper.ServerURI);
string gridName = gatekeeper.ServerURI;
@@ -265,7 +265,7 @@ namespace OpenSim.Services.HypergridService
bool success = false;
string myExternalIP = string.Empty;
- m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}", m_GridName, gridName);
+ m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}, desired region: {2}", m_GridName, gridName, region.RegionID);
if (m_GridName == gridName)
success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason);
@@ -296,8 +296,8 @@ namespace OpenSim.Services.HypergridService
m_log.DebugFormat("[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP);
// else set the IP addresses associated with this client
- if (clientIP != null)
- m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = clientIP.Address.ToString();
+ if (fromLogin)
+ m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = agentCircuit.IPAddress;
m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP;
return true;
@@ -306,7 +306,7 @@ namespace OpenSim.Services.HypergridService
public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, out string reason)
{
reason = string.Empty;
- return LoginAgentToGrid(agentCircuit, gatekeeper, finalDestination, null, out reason);
+ return LoginAgentToGrid(agentCircuit, gatekeeper, finalDestination, false, out reason);
}
private void SetClientIP(UUID sessionID, string ip)
diff --git a/OpenSim/Services/Interfaces/IHypergridServices.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs
index 3dc877a870..f9e7f083b4 100644
--- a/OpenSim/Services/Interfaces/IHypergridServices.cs
+++ b/OpenSim/Services/Interfaces/IHypergridServices.cs
@@ -48,10 +48,7 @@ namespace OpenSim.Services.Interfaces
///
public interface IUserAgentService
{
- // called by login service only
- bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, IPEndPoint clientIP, out string reason);
- // called by simulators
- bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason);
+ bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason);
void LogoutAgent(UUID userID, UUID sessionID);
GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt);
Dictionary GetServerURLs(UUID userID);
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
index 10cf90f7c1..fe43582a89 100644
--- a/OpenSim/Services/LLLoginService/LLLoginService.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -933,7 +933,7 @@ namespace OpenSim.Services.LLLoginService
private bool LaunchAgentIndirectly(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, IPEndPoint clientIP, out string reason)
{
m_log.Debug("[LLOGIN SERVICE] Launching agent at " + destination.RegionName);
- if (m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, clientIP, out reason))
+ if (m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, true, out reason))
return true;
return false;
}
diff --git a/prebuild.xml b/prebuild.xml
index 88db6ede06..4cf3b8358b 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -157,6 +157,7 @@
+
@@ -744,6 +745,7 @@
+