diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs
index da8030c22b..830c6714c8 100644
--- a/OpenSim/Addons/Groups/GroupsModule.cs
+++ b/OpenSim/Addons/Groups/GroupsModule.cs
@@ -467,12 +467,12 @@ namespace OpenSim.Groups
}
// Send notice out to everyone that wants notices
- // Build notice IIM
- GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), GroupID))
{
if (member.AcceptNotices)
{
+ // Build notice IIM, one of reach, because the sending may be async
+ GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
msg.toAgentID = member.AgentID.Guid;
OutgoingInstantMessage(msg, member.AgentID);
}
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs
index 496262970c..2a8e67dd61 100644
--- a/OpenSim/Framework/ChildAgentDataUpdate.cs
+++ b/OpenSim/Framework/ChildAgentDataUpdate.cs
@@ -292,6 +292,12 @@ namespace OpenSim.Framework
public Vector3 AtAxis;
public Vector3 LeftAxis;
public Vector3 UpAxis;
+
+ ///
+ /// Signal on a V2 teleport that Scene.IncomingChildAgentDataUpdate(AgentData ad) should wait for the
+ /// scene presence to become root (triggered when the viewer sends a CompleteAgentMovement UDP packet after
+ /// establishing the connection triggered by it's receipt of a TeleportFinish EQ message).
+ ///
public bool SenderWantsToWaitForRoot;
public float Far;
diff --git a/OpenSim/Framework/Console/ConsoleUtil.cs b/OpenSim/Framework/Console/ConsoleUtil.cs
index 97a86a8099..c0ff454831 100644
--- a/OpenSim/Framework/Console/ConsoleUtil.cs
+++ b/OpenSim/Framework/Console/ConsoleUtil.cs
@@ -156,7 +156,27 @@ namespace OpenSim.Framework.Console
}
///
- /// Convert a minimum vector input from the console to an OpenMetaverse.Vector3
+ /// Convert a console integer to an int, automatically complaining if a console is given.
+ ///
+ /// Can be null if no console is available.
+ /// /param>
+ ///
+ ///
+ public static bool TryParseConsoleBool(ICommandConsole console, string rawConsoleString, out bool b)
+ {
+ if (!bool.TryParse(rawConsoleString, out b))
+ {
+ if (console != null)
+ console.OutputFormat("ERROR: {0} is not a true or false value", rawConsoleString);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Convert a console integer to an int, automatically complaining if a console is given.
///
/// Can be null if no console is available.
/// /param>
diff --git a/OpenSim/Framework/Monitoring/Checks/Check.cs b/OpenSim/Framework/Monitoring/Checks/Check.cs
new file mode 100644
index 0000000000..594386a93f
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/Checks/Check.cs
@@ -0,0 +1,118 @@
+/*
+ * 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.Text;
+
+namespace OpenSim.Framework.Monitoring
+{
+ public class Check
+ {
+// 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).
+ ///
+ public string Category { get; private set; }
+
+ ///
+ /// Containing name for this stat.
+ /// FIXME: In the case of a scene, this is currently the scene name (though this leaves
+ /// us with a to-be-resolved problem of non-unique region names).
+ ///
+ ///
+ /// The container.
+ ///
+ public string Container { get; private set; }
+
+ ///
+ /// Action used to check whether alert should go off.
+ ///
+ ///
+ /// Should return true if check passes. False otherwise.
+ ///
+ public Func CheckFunc { get; private set; }
+
+ ///
+ /// Message from the last failure, if any. If there is no message or no failure then will be null.
+ ///
+ ///
+ /// Should be set by the CheckFunc when applicable.
+ ///
+ public string LastFailureMessage { get; set; }
+
+ public StatVerbosity Verbosity { get; private set; }
+ public string ShortName { get; private set; }
+ public string Name { get; private set; }
+ public string Description { get; private set; }
+
+ public Check(
+ string shortName,
+ string name,
+ string description,
+ string category,
+ string container,
+ Func checkFunc,
+ StatVerbosity verbosity)
+ {
+ if (ChecksManager.SubCommands.Contains(category))
+ throw new Exception(
+ string.Format("Alert 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("Alert name {0} cannot contain character {1}", shortName, c));
+ }
+
+ ShortName = shortName;
+ Name = name;
+ Description = description;
+ Category = category;
+ Container = container;
+ CheckFunc = checkFunc;
+ Verbosity = verbosity;
+ }
+
+ public bool CheckIt()
+ {
+ return CheckFunc(this);
+ }
+
+ public virtual string ToConsoleString()
+ {
+ return string.Format(
+ "{0}.{1}.{2} - {3}",
+ Category,
+ Container,
+ ShortName,
+ Description);
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Framework/Monitoring/ChecksManager.cs b/OpenSim/Framework/Monitoring/ChecksManager.cs
new file mode 100644
index 0000000000..e4a7f8ca2f
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/ChecksManager.cs
@@ -0,0 +1,262 @@
+/*
+ * 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.Linq;
+using System.Reflection;
+using System.Text;
+using log4net;
+
+namespace OpenSim.Framework.Monitoring
+{
+ ///
+ /// Static class used to register/deregister checks on runtime conditions.
+ ///
+ public static class ChecksManager
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ // Subcommand used to list other stats.
+ public const string ListSubCommand = "list";
+
+ // All subcommands
+ public static HashSet SubCommands = new HashSet { ListSubCommand };
+
+ ///
+ /// Checks categorized by category/container/shortname
+ ///
+ ///
+ /// Do not add or remove directly from this dictionary.
+ ///
+ public static SortedDictionary>> RegisteredChecks
+ = new SortedDictionary>>();
+
+ public static void RegisterConsoleCommands(ICommandConsole console)
+ {
+ console.Commands.AddCommand(
+ "General",
+ false,
+ "show checks",
+ "show checks",
+ "Show checks configured for this server",
+ "If no argument is specified then info on all checks will be shown.\n"
+ + "'list' argument will show check categories.\n"
+ + "THIS FACILITY IS EXPERIMENTAL",
+ HandleShowchecksCommand);
+ }
+
+ public static void HandleShowchecksCommand(string module, string[] cmd)
+ {
+ ICommandConsole con = MainConsole.Instance;
+
+ if (cmd.Length > 2)
+ {
+ foreach (string name in cmd.Skip(2))
+ {
+ string[] components = name.Split('.');
+
+ string categoryName = components[0];
+// string containerName = components.Length > 1 ? components[1] : null;
+
+ if (categoryName == ListSubCommand)
+ {
+ con.Output("check categories available are:");
+
+ foreach (string category in RegisteredChecks.Keys)
+ con.OutputFormat(" {0}", category);
+ }
+// else
+// {
+// SortedDictionary> category;
+// if (!Registeredchecks.TryGetValue(categoryName, out category))
+// {
+// con.OutputFormat("No such category as {0}", categoryName);
+// }
+// else
+// {
+// if (String.IsNullOrEmpty(containerName))
+// {
+// OutputConfiguredToConsole(con, category);
+// }
+// else
+// {
+// SortedDictionary container;
+// if (category.TryGetValue(containerName, out container))
+// {
+// OutputContainerChecksToConsole(con, container);
+// }
+// else
+// {
+// con.OutputFormat("No such container {0} in category {1}", containerName, categoryName);
+// }
+// }
+// }
+// }
+ }
+ }
+ else
+ {
+ OutputAllChecksToConsole(con);
+ }
+ }
+
+ ///
+ /// Registers a statistic.
+ ///
+ ///
+ ///
+ public static bool RegisterCheck(Check check)
+ {
+ SortedDictionary> category = null, newCategory;
+ SortedDictionary container = null, newContainer;
+
+ lock (RegisteredChecks)
+ {
+ // Check name is not unique across category/container/shortname key.
+ // XXX: For now just return false. This is to avoid problems in regression tests where all tests
+ // in a class are run in the same instance of the VM.
+ if (TryGetCheckParents(check, out category, out container))
+ return false;
+
+ // We take a copy-on-write approach here of replacing dictionaries when keys are added or removed.
+ // This means that we don't need to lock or copy them on iteration, which will be a much more
+ // common operation after startup.
+ if (container != null)
+ newContainer = new SortedDictionary(container);
+ else
+ newContainer = new SortedDictionary();
+
+ if (category != null)
+ newCategory = new SortedDictionary>(category);
+ else
+ newCategory = new SortedDictionary>();
+
+ newContainer[check.ShortName] = check;
+ newCategory[check.Container] = newContainer;
+ RegisteredChecks[check.Category] = newCategory;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Deregister an check
+ /// >
+ ///
+ ///
+ public static bool DeregisterCheck(Check check)
+ {
+ SortedDictionary> category = null, newCategory;
+ SortedDictionary container = null, newContainer;
+
+ lock (RegisteredChecks)
+ {
+ if (!TryGetCheckParents(check, out category, out container))
+ return false;
+
+ newContainer = new SortedDictionary(container);
+ newContainer.Remove(check.ShortName);
+
+ newCategory = new SortedDictionary>(category);
+ newCategory.Remove(check.Container);
+
+ newCategory[check.Container] = newContainer;
+ RegisteredChecks[check.Category] = newCategory;
+
+ return true;
+ }
+ }
+
+ public static bool TryGetCheckParents(
+ Check check,
+ out SortedDictionary> category,
+ out SortedDictionary container)
+ {
+ category = null;
+ container = null;
+
+ lock (RegisteredChecks)
+ {
+ if (RegisteredChecks.TryGetValue(check.Category, out category))
+ {
+ if (category.TryGetValue(check.Container, out container))
+ {
+ if (container.ContainsKey(check.ShortName))
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public static void CheckChecks()
+ {
+ lock (RegisteredChecks)
+ {
+ foreach (SortedDictionary> category in RegisteredChecks.Values)
+ {
+ foreach (SortedDictionary container in category.Values)
+ {
+ foreach (Check check in container.Values)
+ {
+ if (!check.CheckIt())
+ m_log.WarnFormat(
+ "[CHECKS MANAGER]: Check {0}.{1}.{2} failed with message {3}", check.Category, check.Container, check.ShortName, check.LastFailureMessage);
+ }
+ }
+ }
+ }
+ }
+
+ private static void OutputAllChecksToConsole(ICommandConsole con)
+ {
+ foreach (var category in RegisteredChecks.Values)
+ {
+ OutputCategoryChecksToConsole(con, category);
+ }
+ }
+
+ private static void OutputCategoryChecksToConsole(
+ ICommandConsole con, SortedDictionary> category)
+ {
+ foreach (var container in category.Values)
+ {
+ OutputContainerChecksToConsole(con, container);
+ }
+ }
+
+ private static void OutputContainerChecksToConsole(ICommandConsole con, SortedDictionary container)
+ {
+ foreach (Check check in container.Values)
+ {
+ con.Output(check.ToConsoleString());
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Framework/Monitoring/StatsLogger.cs b/OpenSim/Framework/Monitoring/StatsLogger.cs
new file mode 100644
index 0000000000..fa2e1b641e
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/StatsLogger.cs
@@ -0,0 +1,108 @@
+/*
+ * 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.Reflection;
+using System.Timers;
+using log4net;
+
+namespace OpenSim.Framework.Monitoring
+{
+ ///
+ /// Provides a means to continuously log stats for debugging purposes.
+ ///
+ public static class StatsLogger
+ {
+ private static readonly ILog m_statsLog = LogManager.GetLogger("special.StatsLogger");
+
+ private static Timer m_loggingTimer;
+ private static int m_statsLogIntervalMs = 5000;
+
+ public static void RegisterConsoleCommands(ICommandConsole console)
+ {
+ console.Commands.AddCommand(
+ "Debug",
+ false,
+ "debug stats record",
+ "debug stats record start|stop",
+ "Control whether stats are being regularly recorded to a separate file.",
+ "For debug purposes. Experimental.",
+ HandleStatsRecordCommand);
+ }
+
+ public static void HandleStatsRecordCommand(string module, string[] cmd)
+ {
+ ICommandConsole con = MainConsole.Instance;
+
+ if (cmd.Length != 4)
+ {
+ con.Output("Usage: debug stats record start|stop");
+ return;
+ }
+
+ if (cmd[3] == "start")
+ {
+ Start();
+ con.OutputFormat("Now recording all stats very {0}ms to file", m_statsLogIntervalMs);
+ }
+ else if (cmd[3] == "stop")
+ {
+ Stop();
+ con.Output("Stopped recording stats to file.");
+ }
+ }
+
+ public static void Start()
+ {
+ if (m_loggingTimer != null)
+ Stop();
+
+ m_loggingTimer = new Timer(m_statsLogIntervalMs);
+ m_loggingTimer.AutoReset = false;
+ m_loggingTimer.Elapsed += Log;
+ m_loggingTimer.Start();
+ }
+
+ public static void Stop()
+ {
+ if (m_loggingTimer != null)
+ {
+ m_loggingTimer.Stop();
+ }
+ }
+
+ private static void Log(object sender, ElapsedEventArgs e)
+ {
+ m_statsLog.InfoFormat("*** STATS REPORT AT {0} ***", DateTime.Now);
+
+ foreach (string report in StatsManager.GetAllStatsReports())
+ m_statsLog.Info(report);
+
+ m_loggingTimer.Start();
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index e6a230454c..c8e838cadf 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -35,9 +35,9 @@ using OpenMetaverse.StructuredData;
namespace OpenSim.Framework.Monitoring
{
///
- /// Singleton used to provide access to statistics reporters
+ /// Static class used to register/deregister/fetch statistics
///
- public class StatsManager
+ public static class StatsManager
{
// Subcommand used to list other stats.
public const string AllSubCommand = "all";
@@ -81,6 +81,8 @@ namespace OpenSim.Framework.Monitoring
+ "More than one name can be given separated by spaces.\n"
+ "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS",
HandleShowStatsCommand);
+
+ StatsLogger.RegisterConsoleCommands(console);
}
public static void HandleShowStatsCommand(string module, string[] cmd)
@@ -145,29 +147,55 @@ namespace OpenSim.Framework.Monitoring
}
}
+ public static List GetAllStatsReports()
+ {
+ List reports = new List();
+
+ foreach (var category in RegisteredStats.Values)
+ reports.AddRange(GetCategoryStatsReports(category));
+
+ return reports;
+ }
+
private static void OutputAllStatsToConsole(ICommandConsole con)
{
- foreach (var category in RegisteredStats.Values)
- {
- OutputCategoryStatsToConsole(con, category);
- }
+ foreach (string report in GetAllStatsReports())
+ con.Output(report);
+ }
+
+ private static List GetCategoryStatsReports(
+ SortedDictionary> category)
+ {
+ List reports = new List();
+
+ foreach (var container in category.Values)
+ reports.AddRange(GetContainerStatsReports(container));
+
+ return reports;
}
private static void OutputCategoryStatsToConsole(
ICommandConsole con, SortedDictionary> category)
{
- foreach (var container in category.Values)
- {
- OutputContainerStatsToConsole(con, container);
- }
+ foreach (string report in GetCategoryStatsReports(category))
+ con.Output(report);
}
- private static void OutputContainerStatsToConsole( ICommandConsole con, SortedDictionary container)
+ private static List GetContainerStatsReports(SortedDictionary container)
{
+ List reports = new List();
+
foreach (Stat stat in container.Values)
- {
- con.Output(stat.ToConsoleString());
- }
+ reports.Add(stat.ToConsoleString());
+
+ return reports;
+ }
+
+ private static void OutputContainerStatsToConsole(
+ ICommandConsole con, SortedDictionary container)
+ {
+ foreach (string report in GetContainerStatsReports(container))
+ con.Output(report);
}
// Creates an OSDMap of the format:
@@ -257,7 +285,7 @@ namespace OpenSim.Framework.Monitoring
// }
///
- /// Registers a statistic.
+ /// Register a statistic.
///
///
///
diff --git a/OpenSim/Framework/Monitoring/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs
index 69d2db58ce..32724ec623 100644
--- a/OpenSim/Framework/Monitoring/Watchdog.cs
+++ b/OpenSim/Framework/Monitoring/Watchdog.cs
@@ -380,6 +380,7 @@ namespace OpenSim.Framework.Monitoring
if (MemoryWatchdog.Enabled)
MemoryWatchdog.Update();
+ ChecksManager.CheckChecks();
StatsManager.RecordStats();
m_watchdogTimer.Start();
diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs
index eb8c9f8e14..7108314e0d 100644
--- a/OpenSim/Framework/Servers/ServerBase.cs
+++ b/OpenSim/Framework/Servers/ServerBase.cs
@@ -246,7 +246,7 @@ namespace OpenSim.Framework.Servers
"Show thread status", HandleShow);
m_console.Commands.AddCommand(
- "General", false, "threads abort",
+ "Debug", false, "threads abort",
"threads abort ",
"Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
@@ -256,8 +256,32 @@ namespace OpenSim.Framework.Servers
"Show thread status. Synonym for \"show threads\"",
(string module, string[] args) => Notice(GetThreadsReport()));
+ m_console.Commands.AddCommand (
+ "Debug", false, "debug comms set",
+ "debug comms set serialosdreq true|false",
+ "Set comms parameters. For debug purposes.",
+ HandleDebugCommsSet);
+
+ m_console.Commands.AddCommand (
+ "Debug", false, "debug comms status",
+ "debug comms status",
+ "Show current debug comms parameters.",
+ HandleDebugCommsStatus);
+
+ m_console.Commands.AddCommand (
+ "Debug", false, "debug threadpool set",
+ "debug threadpool set worker|iocp min|max ",
+ "Set threadpool parameters. For debug purposes.",
+ HandleDebugThreadpoolSet);
+
+ m_console.Commands.AddCommand (
+ "Debug", false, "debug threadpool status",
+ "debug threadpool status",
+ "Show current debug threadpool parameters.",
+ HandleDebugThreadpoolStatus);
+
m_console.Commands.AddCommand(
- "General", false, "force gc",
+ "Debug", false, "force gc",
"force gc",
"Manually invoke runtime garbage collection. For debugging purposes",
HandleForceGc);
@@ -272,16 +296,142 @@ namespace OpenSim.Framework.Servers
"shutdown",
"Quit the application", (mod, args) => Shutdown());
+ ChecksManager.RegisterConsoleCommands(m_console);
StatsManager.RegisterConsoleCommands(m_console);
}
public void RegisterCommonComponents(IConfigSource configSource)
{
+ IConfig networkConfig = configSource.Configs["Network"];
+
+ if (networkConfig != null)
+ {
+ WebUtil.SerializeOSDRequestsPerEndpoint = networkConfig.GetBoolean("SerializeOSDRequests", false);
+ }
+
m_serverStatsCollector = new ServerStatsCollector();
m_serverStatsCollector.Initialise(configSource);
m_serverStatsCollector.Start();
}
+ private void HandleDebugCommsStatus(string module, string[] args)
+ {
+ Notice("serialosdreq is {0}", WebUtil.SerializeOSDRequestsPerEndpoint);
+ }
+
+ private void HandleDebugCommsSet(string module, string[] args)
+ {
+ if (args.Length != 5)
+ {
+ Notice("Usage: debug comms set serialosdreq true|false");
+ return;
+ }
+
+ if (args[3] != "serialosdreq")
+ {
+ Notice("Usage: debug comms set serialosdreq true|false");
+ return;
+ }
+
+ bool setSerializeOsdRequests;
+
+ if (!ConsoleUtil.TryParseConsoleBool(m_console, args[4], out setSerializeOsdRequests))
+ return;
+
+ WebUtil.SerializeOSDRequestsPerEndpoint = setSerializeOsdRequests;
+
+ Notice("serialosdreq is now {0}", setSerializeOsdRequests);
+ }
+
+ private void HandleDebugThreadpoolStatus(string module, string[] args)
+ {
+ int workerThreads, iocpThreads;
+
+ ThreadPool.GetMinThreads(out workerThreads, out iocpThreads);
+ Notice("Min worker threads: {0}", workerThreads);
+ Notice("Min IOCP threads: {0}", iocpThreads);
+
+ ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
+ Notice("Max worker threads: {0}", workerThreads);
+ Notice("Max IOCP threads: {0}", iocpThreads);
+
+ ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads);
+ Notice("Available worker threads: {0}", workerThreads);
+ Notice("Available IOCP threads: {0}", iocpThreads);
+ }
+
+ private void HandleDebugThreadpoolSet(string module, string[] args)
+ {
+ if (args.Length != 6)
+ {
+ Notice("Usage: debug threadpool set worker|iocp min|max ");
+ return;
+ }
+
+ int newThreads;
+
+ if (!ConsoleUtil.TryParseConsoleInt(m_console, args[5], out newThreads))
+ return;
+
+ string poolType = args[3];
+ string bound = args[4];
+
+ bool fail = false;
+ int workerThreads, iocpThreads;
+
+ if (poolType == "worker")
+ {
+ if (bound == "min")
+ {
+ ThreadPool.GetMinThreads(out workerThreads, out iocpThreads);
+
+ if (!ThreadPool.SetMinThreads(newThreads, iocpThreads))
+ fail = true;
+ }
+ else
+ {
+ ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
+
+ if (!ThreadPool.SetMaxThreads(newThreads, iocpThreads))
+ fail = true;
+ }
+ }
+ else
+ {
+ if (bound == "min")
+ {
+ ThreadPool.GetMinThreads(out workerThreads, out iocpThreads);
+
+ if (!ThreadPool.SetMinThreads(workerThreads, newThreads))
+ fail = true;
+ }
+ else
+ {
+ ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
+
+ if (!ThreadPool.SetMaxThreads(workerThreads, newThreads))
+ fail = true;
+ }
+ }
+
+ if (fail)
+ {
+ Notice("ERROR: Could not set {0} {1} threads to {2}", poolType, bound, newThreads);
+ }
+ else
+ {
+ int minWorkerThreads, maxWorkerThreads, minIocpThreads, maxIocpThreads;
+
+ ThreadPool.GetMinThreads(out minWorkerThreads, out minIocpThreads);
+ ThreadPool.GetMaxThreads(out maxWorkerThreads, out maxIocpThreads);
+
+ Notice("Min worker threads now {0}", minWorkerThreads);
+ Notice("Min IOCP threads now {0}", minIocpThreads);
+ Notice("Max worker threads now {0}", maxWorkerThreads);
+ Notice("Max IOCP threads now {0}", maxIocpThreads);
+ }
+ }
+
private void HandleForceGc(string module, string[] args)
{
Notice("Manually invoking runtime garbage collection");
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs
index dfa37cac1d..9fa93ea2b8 100644
--- a/OpenSim/Framework/WebUtil.cs
+++ b/OpenSim/Framework/WebUtil.cs
@@ -66,6 +66,11 @@ namespace OpenSim.Framework
///
public static int RequestNumber { get; internal set; }
+ ///
+ /// Control where OSD requests should be serialized per endpoint.
+ ///
+ public static bool SerializeOSDRequestsPerEndpoint { get; set; }
+
///
/// this is the header field used to communicate the local request id
/// used for performance and debugging
@@ -145,9 +150,16 @@ namespace OpenSim.Framework
public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed)
{
- lock (EndPointLock(url))
+ if (SerializeOSDRequestsPerEndpoint)
{
- return ServiceOSDRequestWorker(url,data,method,timeout,compressed);
+ lock (EndPointLock(url))
+ {
+ return ServiceOSDRequestWorker(url, data, method, timeout, compressed);
+ }
+ }
+ else
+ {
+ return ServiceOSDRequestWorker(url, data, method, timeout, compressed);
}
}
diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs
index e451aa8148..2e155ec9dc 100644
--- a/OpenSim/Region/Application/Application.cs
+++ b/OpenSim/Region/Application/Application.cs
@@ -103,26 +103,38 @@ namespace OpenSim
"[OPENSIM MAIN]: Environment variable MONO_THREADS_PER_CPU is {0}", monoThreadsPerCpu ?? "unset");
// Verify the Threadpool allocates or uses enough worker and IO completion threads
- // .NET 2.0 workerthreads default to 50 * numcores
- // .NET 3.0 workerthreads defaults to 250 * numcores
- // .NET 4.0 workerthreads are dynamic based on bitness and OS resources
- // Max IO Completion threads are 1000 on all 3 CLRs.
+ // .NET 2.0, workerthreads default to 50 * numcores
+ // .NET 3.0, workerthreads defaults to 250 * numcores
+ // .NET 4.0, workerthreads are dynamic based on bitness and OS resources
+ // Max IO Completion threads are 1000 on all 3 CLRs
+ //
+ // Mono 2.10.9 to at least Mono 3.1, workerthreads default to 100 * numcores, iocp threads to 4 * numcores
int workerThreadsMin = 500;
int workerThreadsMax = 1000; // may need further adjustment to match other CLR
int iocpThreadsMin = 1000;
int iocpThreadsMax = 2000; // may need further adjustment to match other CLR
+
+ {
+ int currentMinWorkerThreads, currentMinIocpThreads;
+ System.Threading.ThreadPool.GetMinThreads(out currentMinWorkerThreads, out currentMinIocpThreads);
+ m_log.InfoFormat(
+ "[OPENSIM MAIN]: Runtime gave us {0} min worker threads and {1} min IOCP threads",
+ currentMinWorkerThreads, currentMinIocpThreads);
+ }
+
int workerThreads, iocpThreads;
System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
- m_log.InfoFormat("[OPENSIM MAIN]: Runtime gave us {0} worker threads and {1} IOCP threads", workerThreads, iocpThreads);
+ m_log.InfoFormat("[OPENSIM MAIN]: Runtime gave us {0} max worker threads and {1} max IOCP threads", workerThreads, iocpThreads);
+
if (workerThreads < workerThreadsMin)
{
workerThreads = workerThreadsMin;
- m_log.InfoFormat("[OPENSIM MAIN]: Bumping up to worker threads to {0}",workerThreads);
+ m_log.InfoFormat("[OPENSIM MAIN]: Bumping up to max worker threads to {0}",workerThreads);
}
if (workerThreads > workerThreadsMax)
{
workerThreads = workerThreadsMax;
- m_log.InfoFormat("[OPENSIM MAIN]: Limiting worker threads to {0}",workerThreads);
+ m_log.InfoFormat("[OPENSIM MAIN]: Limiting max worker threads to {0}",workerThreads);
}
// Increase the number of IOCP threads available.
@@ -130,22 +142,24 @@ namespace OpenSim
if (iocpThreads < iocpThreadsMin)
{
iocpThreads = iocpThreadsMin;
- m_log.InfoFormat("[OPENSIM MAIN]: Bumping up IO completion threads to {0}",iocpThreads);
+ m_log.InfoFormat("[OPENSIM MAIN]: Bumping up max IO completion threads to {0}",iocpThreads);
}
// Make sure we don't overallocate IOCP threads and thrash system resources
if ( iocpThreads > iocpThreadsMax )
{
iocpThreads = iocpThreadsMax;
- m_log.InfoFormat("[OPENSIM MAIN]: Limiting IO completion threads to {0}",iocpThreads);
+ m_log.InfoFormat("[OPENSIM MAIN]: Limiting max IO completion threads to {0}",iocpThreads);
}
// set the resulting worker and IO completion thread counts back to ThreadPool
if ( System.Threading.ThreadPool.SetMaxThreads(workerThreads, iocpThreads) )
{
- m_log.InfoFormat("[OPENSIM MAIN]: Threadpool set to {0} worker threads and {1} IO completion threads", workerThreads, iocpThreads);
+ m_log.InfoFormat(
+ "[OPENSIM MAIN]: Threadpool set to {0} max worker threads and {1} max IO completion threads",
+ workerThreads, iocpThreads);
}
else
{
- m_log.Info("[OPENSIM MAIN]: Threadpool reconfiguration failed, runtime defaults still in effect.");
+ m_log.Warn("[OPENSIM MAIN]: Threadpool reconfiguration failed, runtime defaults still in effect.");
}
// Check if the system is compatible with OpenSimulator.
@@ -153,17 +167,16 @@ namespace OpenSim
string supported = String.Empty;
if (Util.IsEnvironmentSupported(ref supported))
{
- m_log.Info("Environment is compatible.\n");
+ m_log.Info("[OPENSIM MAIN]: Environment is supported by OpenSimulator.");
}
else
{
- m_log.Warn("Environment is unsupported (" + supported + ")\n");
+ m_log.Warn("[OPENSIM MAIN]: Environment is not supported by OpenSimulator (" + supported + ")\n");
}
// Configure nIni aliases and localles
Culture.SetCurrentCulture();
-
// Validate that the user has the most basic configuration done
// If not, offer to do the most basic configuration for them warning them along the way of the importance of
// reading these files.
diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs
index fc3999f7a6..3e9363808b 100644
--- a/OpenSim/Region/Application/ConfigurationLoader.cs
+++ b/OpenSim/Region/Application/ConfigurationLoader.cs
@@ -337,7 +337,6 @@ namespace OpenSim
config.Set("physics", "OpenDynamicsEngine");
config.Set("meshing", "Meshmerizer");
config.Set("physical_prim", true);
- config.Set("see_into_this_sim_from_neighbor", true);
config.Set("serverside_object_permissions", true);
config.Set("storage_plugin", "OpenSim.Data.SQLite.dll");
config.Set("storage_connection_string", "URI=file:OpenSim.db,version=3");
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
index 83144e3bcd..575e54c685 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
@@ -29,6 +29,7 @@ using System;
using System.IO;
using System.Net;
using System.Reflection;
+using System.Threading;
using log4net.Config;
using Nini.Config;
using NUnit.Framework;
@@ -53,6 +54,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
[TestFixtureSetUp]
public void FixtureInit()
{
+ // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
+ Util.FireAndForgetMethod = FireAndForgetMethod.None;
+
using (
Stream resource
= GetType().Assembly.GetManifestResourceStream(
@@ -72,6 +76,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
}
}
+ [TestFixtureTearDown]
+ public void TearDown()
+ {
+ // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
+ // threads. Possibly, later tests should be rewritten not to worry about such things.
+ Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
+ }
+
[SetUp]
public override void SetUp()
{
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
index 37646855ca..d9b0effaac 100644
--- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
@@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
// Do Decode!
if (decode)
- Decode(assetID, j2kData);
+ Util.FireAndForget(delegate { Decode(assetID, j2kData); });
}
}
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index e1ca6cd4a2..62b25d0d9a 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -54,8 +54,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
public int DebugLevel { get; set; }
///
- /// Period to sleep per 100 prims in order to avoid CPU spikes when an avatar with many attachments logs in
- /// or many avatars with a medium levels of attachments login simultaneously.
+ /// Period to sleep per 100 prims in order to avoid CPU spikes when an avatar with many attachments logs in/changes
+ /// outfit or many avatars with a medium levels of attachments login/change outfit simultaneously.
///
///
/// A value of 0 will apply no pause. The pause is specified in milliseconds.
@@ -1094,7 +1094,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
}
if (tainted)
- objatt.HasGroupChanged = true;
+ objatt.HasGroupChanged = true;
+
+ if (ThrottlePer100PrimsRezzed > 0)
+ {
+ int throttleMs = (int)Math.Round((float)objatt.PrimCount / 100 * ThrottlePer100PrimsRezzed);
+
+ if (DebugLevel > 0)
+ m_log.DebugFormat(
+ "[ATTACHMENTS MODULE]: Throttling by {0}ms after rez of {1} with {2} prims for attachment to {3} on point {4} in {5}",
+ throttleMs, objatt.Name, objatt.PrimCount, sp.Name, attachmentPt, m_scene.Name);
+
+ Thread.Sleep(throttleMs);
+ }
return objatt;
}
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index df95bf05b8..4286eef379 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -693,8 +693,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (version.Equals("SIMULATION/0.2"))
TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
else
- TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
-
+ TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
}
private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
@@ -703,7 +702,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
ulong destinationHandle = finalDestination.RegionHandle;
AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
- m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Using TP V1");
+ m_log.DebugFormat(
+ "[ENTITY TRANSFER MODULE]: Using TP V1 for {0} going from {1} to {2}",
+ sp.Name, Scene.Name, finalDestination.RegionName);
+
// Let's create an agent there if one doesn't exist yet.
// NOTE: logout will always be false for a non-HG teleport.
bool logout = false;
@@ -961,6 +963,27 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return;
}
+ if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
+ {
+ m_interRegionTeleportCancels.Value++;
+
+ m_log.DebugFormat(
+ "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
+ sp.Name, finalDestination.RegionName, sp.Scene.Name);
+
+ return;
+ }
+ else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
+ {
+ m_interRegionTeleportAborts.Value++;
+
+ m_log.DebugFormat(
+ "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
+ sp.Name, finalDestination.RegionName, sp.Scene.Name);
+
+ return;
+ }
+
// Past this point we have to attempt clean up if the teleport fails, so update transfer state.
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
@@ -1063,20 +1086,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (!sp.DoNotCloseAfterTeleport)
{
// OK, it got this agent. Let's close everything
- m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing in agent {0} in region {1}", sp.Name, Scene.RegionInfo.RegionName);
+ m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing in agent {0} in region {1}", sp.Name, Scene.Name);
sp.CloseChildAgents(newRegionX, newRegionY);
sp.Scene.IncomingCloseAgent(sp.UUID, false);
}
else
{
- m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {0}", sp.Name, Scene.RegionInfo.RegionName);
+ m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {0}", sp.Name, Scene.Name);
sp.DoNotCloseAfterTeleport = false;
}
}
else
+ {
// now we have a child agent in this region.
sp.Reset();
+ }
}
///
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index 8f9800f681..ce7ed26832 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -62,6 +62,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
private string m_ThisGatekeeper;
private bool m_RestrictInventoryAccessAbroad;
+ private bool m_bypassPermissions = true;
+
// private bool m_Initialized = false;
#region INonSharedRegionModule
@@ -100,6 +102,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
else
m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
+
+ m_bypassPermissions = !Util.GetConfigVarFromSections(source, "serverside_object_permissions",
+ new string[] { "Startup", "Permissions" }, true);
+
}
}
}
@@ -114,6 +120,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
scene.EventManager.OnTeleportStart += TeleportStart;
scene.EventManager.OnTeleportFail += TeleportFail;
+
+ // We're fgoing to enforce some stricter permissions if Outbound is false
+ scene.Permissions.OnTakeObject += CanTakeObject;
+ scene.Permissions.OnTakeCopyObject += CanTakeObject;
+ scene.Permissions.OnTransferUserInventory += OnTransferUserInventory;
}
#endregion
@@ -416,6 +427,37 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
// No-op for now
}
+ #endregion
+
+ #region Permissions
+
+ private bool CanTakeObject(UUID objectID, UUID stealer, Scene scene)
+ {
+ if (m_bypassPermissions) return true;
+
+ if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(stealer))
+ {
+ SceneObjectGroup sog = null;
+ if (m_Scene.TryGetSceneObjectGroup(objectID, out sog) && sog.OwnerID == stealer)
+ return true;
+
+ return false;
+ }
+
+ return true;
+ }
+
+ private bool OnTransferUserInventory(UUID itemID, UUID userID, UUID recipientID)
+ {
+ if (m_bypassPermissions) return true;
+
+ if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(recipientID))
+ return false;
+
+ return true;
+ }
+
+
#endregion
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index aa00145afe..89bb0372e5 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -809,7 +809,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
objlist.Add(g);
- veclist.Add(new Vector3(0, 0, 0));
+ veclist.Add(Vector3.Zero);
float offsetHeight = 0;
pos = m_Scene.GetNewRezLocation(
diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index fccf0534b3..bb304dfc1c 100644
--- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -163,7 +163,7 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
public void RegisterScriptInvocation(object target, MethodInfo mi)
{
- m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name);
+// m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name);
Type delegateType;
List typeArgs = mi.GetParameters()
@@ -325,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
///
public void RegisterConstant(string cname, object value)
{
- m_log.DebugFormat("[MODULE COMMANDS] register constant <{0}> with value {1}",cname,value.ToString());
+// m_log.DebugFormat("[MODULE COMMANDS] register constant <{0}> with value {1}",cname,value.ToString());
lock (m_constants)
{
m_constants.Add(cname,value);
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index a5adc29b39..a9aa73c6d8 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -63,35 +63,41 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
///
private bool m_ModuleEnabled = false;
- public LocalSimulationConnectorModule()
- {
- ServiceVersion = "SIMULATION/0.2";
- }
-
#region Region Module interface
- public void Initialise(IConfigSource config)
+ public void Initialise(IConfigSource configSource)
{
- IConfig moduleConfig = config.Configs["Modules"];
+ IConfig moduleConfig = configSource.Configs["Modules"];
if (moduleConfig != null)
{
string name = moduleConfig.GetString("SimulationServices", "");
if (name == Name)
{
- //IConfig userConfig = config.Configs["SimulationService"];
- //if (userConfig == null)
- //{
- // m_log.Error("[AVATAR CONNECTOR]: SimulationService missing from OpenSim.ini");
- // return;
- //}
+ InitialiseService(configSource);
m_ModuleEnabled = true;
- m_log.Info("[SIMULATION CONNECTOR]: Local simulation enabled");
+ m_log.Info("[LOCAL SIMULATION CONNECTOR]: Local simulation enabled.");
}
}
}
+ public void InitialiseService(IConfigSource configSource)
+ {
+ ServiceVersion = "SIMULATION/0.2";
+ IConfig config = configSource.Configs["SimulationService"];
+ if (config != null)
+ {
+ ServiceVersion = config.GetString("ConnectorProtocolVersion", ServiceVersion);
+
+ if (ServiceVersion != "SIMULATION/0.1" && ServiceVersion != "SIMULATION/0.2")
+ throw new Exception(string.Format("Invalid ConnectorProtocolVersion {0}", ServiceVersion));
+
+ m_log.InfoFormat(
+ "[LOCAL SIMULATION CONNECTOR]: Initialzied with connector protocol version {0}", ServiceVersion);
+ }
+ }
+
public void PostInitialise()
{
}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
index a1ab3e3fd3..8bd1d10ecf 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
@@ -50,9 +50,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteSimulationConnectorModule")]
public class RemoteSimulationConnectorModule : ISharedRegionModule, ISimulationService
{
- private bool initialized = false;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ private bool initialized = false;
protected bool m_enabled = false;
protected Scene m_aScene;
// RemoteSimulationConnector does not care about local regions; it delegates that to the Local module
@@ -64,27 +64,23 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
#region Region Module interface
- public virtual void Initialise(IConfigSource config)
+ public virtual void Initialise(IConfigSource configSource)
{
-
- IConfig moduleConfig = config.Configs["Modules"];
+ IConfig moduleConfig = configSource.Configs["Modules"];
if (moduleConfig != null)
{
string name = moduleConfig.GetString("SimulationServices", "");
if (name == Name)
{
- //IConfig userConfig = config.Configs["SimulationService"];
- //if (userConfig == null)
- //{
- // m_log.Error("[AVATAR CONNECTOR]: SimulationService missing from OpenSim.ini");
- // return;
- //}
+ m_localBackend = new LocalSimulationConnectorModule();
+
+ m_localBackend.InitialiseService(configSource);
m_remoteConnector = new SimulationServiceConnector();
m_enabled = true;
- m_log.Info("[SIMULATION CONNECTOR]: Remote simulation enabled");
+ m_log.Info("[REMOTE SIMULATION CONNECTOR]: Remote simulation enabled.");
}
}
}
@@ -142,8 +138,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
}
protected virtual void InitOnce(Scene scene)
- {
- m_localBackend = new LocalSimulationConnectorModule();
+ {
m_aScene = scene;
//m_regionClient = new RegionToRegionClient(m_aScene, m_hyperlinkService);
m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName);
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 8f6073af28..550ab87e5e 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -551,6 +551,9 @@ namespace OpenSim.Region.Framework.Scenes
{
//Console.WriteLine("Scene.Inventory.cs: GiveInventoryItem");
+ if (!Permissions.CanTransferUserInventory(itemId, senderId, recipient))
+ return null;
+
InventoryItemBase item = new InventoryItemBase(itemId, senderId);
item = InventoryService.GetItem(item);
@@ -2127,7 +2130,10 @@ namespace OpenSim.Region.Framework.Scenes
{
// If we don't have permission, stop right here
if (!permissionToTakeCopy)
+ {
+ remoteClient.SendAlertMessage("You don't have permission to take the object");
return;
+ }
permissionToTake = true;
// Don't delete
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 0d9028c254..aa0909243f 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4174,28 +4174,29 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- if (RegionInfo.EstateSettings != null)
- {
- if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, 0))
- {
- m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
- agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
- reason = String.Format("Denied access to region {0}: You have been banned from that region.",
- RegionInfo.RegionName);
- return false;
- }
- }
- else
- {
- m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!");
- }
-
// We only test the things below when we want to cut off
// child agents from being present in the scene for which their root
// agent isn't allowed. Otherwise, we allow child agents. The test for
// the root is done elsewhere (QueryAccess)
if (!bypassAccessControl)
{
+ if (RegionInfo.EstateSettings != null)
+ {
+ int flags = GetUserFlags(agent.AgentID);
+ if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, flags))
+ {
+ m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
+ agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
+ reason = String.Format("Denied access to region {0}: You have been banned from that region.",
+ RegionInfo.RegionName);
+ return false;
+ }
+ }
+ else
+ {
+ m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!");
+ }
+
List agentGroups = new List();
if (m_groupsModule != null)
@@ -4392,36 +4393,42 @@ namespace OpenSim.Region.Framework.Scenes
}
// We have to wait until the viewer contacts this region
- // after receiving the EnableSimulator HTTP Event Queue message. This triggers the viewer to send
+ // after receiving the EnableSimulator HTTP Event Queue message (for the v1 teleport protocol)
+ // or TeleportFinish (for the v2 teleport protocol). This triggers the viewer to send
// a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence.
- ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
+ ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID);
- if (childAgentUpdate != null)
+ if (sp != null)
{
- if (cAgentData.SessionID != childAgentUpdate.ControllingClient.SessionId)
+ if (cAgentData.SessionID != sp.ControllingClient.SessionId)
{
- m_log.WarnFormat("[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).", childAgentUpdate.UUID, cAgentData.SessionID);
+ m_log.WarnFormat(
+ "[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).",
+ sp.UUID, cAgentData.SessionID);
+
Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}",
- childAgentUpdate.UUID, childAgentUpdate.ControllingClient.SessionId, cAgentData.SessionID));
+ sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID));
}
- childAgentUpdate.ChildAgentDataUpdate(cAgentData);
+ sp.ChildAgentDataUpdate(cAgentData);
int ntimes = 20;
if (cAgentData.SenderWantsToWaitForRoot)
{
- while (childAgentUpdate.IsChildAgent && ntimes-- > 0)
+ while (sp.IsChildAgent && ntimes-- > 0)
Thread.Sleep(1000);
m_log.DebugFormat(
"[SCENE]: Found presence {0} {1} {2} in {3} after {4} waits",
- childAgentUpdate.Name, childAgentUpdate.UUID, childAgentUpdate.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 20 - ntimes);
+ sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", Name, 20 - ntimes);
- if (childAgentUpdate.IsChildAgent)
+ if (sp.IsChildAgent)
return false;
}
+
return true;
}
+
return false;
}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index c4876b365f..48bf6f3b8d 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -294,10 +294,24 @@ namespace OpenSim.Region.Framework.Scenes
///
private Vector3 posLastSignificantMove;
- // For teleports and crossings callbacks
+ #region For teleports and crossings callbacks
+
+ ///
+ /// In the V1 teleport protocol, the destination simulator sends ReleaseAgent to this address.
+ ///
string m_callbackURI;
+
UUID m_originRegionID;
+ ///
+ /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent
+ /// teleport is reusing the connection.
+ ///
+ /// May be refactored or move somewhere else soon.
+ public bool DoNotCloseAfterTeleport { get; set; }
+
+ #endregion
+
///
/// Script engines present in the scene
///
@@ -764,13 +778,6 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- ///
- /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent
- /// teleport is reusing the connection.
- ///
- /// May be refactored or move somewhere else soon.
- public bool DoNotCloseAfterTeleport { get; set; }
-
private float m_speedModifier = 1.0f;
public float SpeedModifier
@@ -1516,14 +1523,14 @@ namespace OpenSim.Region.Framework.Scenes
int count = 20;
while (m_originRegionID.Equals(UUID.Zero) && count-- > 0)
{
- m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.RegionInfo.RegionName);
+ m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name);
Thread.Sleep(200);
}
if (m_originRegionID.Equals(UUID.Zero))
{
// Movement into region will fail
- m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived", client.Name);
+ m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name);
return false;
}
@@ -1829,8 +1836,14 @@ namespace OpenSim.Region.Framework.Scenes
// Here's where you get them.
m_AgentControlFlags = flags;
m_headrotation = agentData.HeadRotation;
+ byte oldState = State;
State = agentData.State;
+ // We need to send this back to the client in order to stop the edit beams
+ if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None)
+ ControllingClient.SendAgentTerseUpdate(this);
+
+
PhysicsActor actor = PhysicsActor;
if (actor == null)
{
@@ -3199,8 +3212,7 @@ namespace OpenSim.Region.Framework.Scenes
}
// Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
- if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance ||
- Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance)
+ if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance)
{
m_lastChildAgentUpdatePosition = AbsolutePosition;
m_lastChildAgentUpdateCamPosition = CameraPosition;
diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
index 0cbc5f9e76..d1d318c562 100755
--- a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
@@ -49,10 +49,20 @@ public class ExtendedPhysics : INonSharedRegionModule
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static string LogHeader = "[EXTENDED PHYSICS]";
+ // =============================================================
// Since BulletSim is a plugin, this these values aren't defined easily in one place.
- // This table must coorespond to an identical table in BSScene.
+ // This table must correspond to an identical table in BSScene.
+
+ // Per scene functions. See BSScene.
+
+ // Per avatar functions. See BSCharacter.
+
+ // Per prim functions. See BSPrim.
+ public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType";
public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType";
+ // =============================================================
+
private IConfig Configuration { get; set; }
private bool Enabled { get; set; }
private Scene BaseScene { get; set; }
@@ -123,6 +133,7 @@ public class ExtendedPhysics : INonSharedRegionModule
// Register as LSL functions all the [ScriptInvocation] marked methods.
Comms.RegisterScriptInvocations(this);
+ Comms.RegisterConstants(this);
// When an object is modified, we might need to update its extended physics parameters
BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene;
@@ -136,7 +147,6 @@ public class ExtendedPhysics : INonSharedRegionModule
private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj)
{
- throw new NotImplementedException();
}
// Event generated when some property of a prim changes.
@@ -168,9 +178,11 @@ public class ExtendedPhysics : INonSharedRegionModule
public static int PHYS_LINKSET_TYPE_MANUAL = 2;
[ScriptInvocation]
- public void physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
+ public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
{
- if (!Enabled) return;
+ int ret = -1;
+
+ if (!Enabled) return ret;
// The part that is requesting the change.
SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID);
@@ -186,7 +198,7 @@ public class ExtendedPhysics : INonSharedRegionModule
Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor;
if (rootPhysActor != null)
{
- rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType);
+ ret = (int)rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType);
}
else
{
@@ -204,6 +216,49 @@ public class ExtendedPhysics : INonSharedRegionModule
{
m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
}
+ return ret;
+ }
+
+ [ScriptInvocation]
+ public int physGetLinksetType(UUID hostID, UUID scriptID)
+ {
+ int ret = -1;
+
+ if (!Enabled) return ret;
+
+ // The part that is requesting the change.
+ SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID);
+
+ if (requestingPart != null)
+ {
+ // The type is is always on the root of a linkset.
+ SceneObjectGroup containingGroup = requestingPart.ParentGroup;
+ SceneObjectPart rootPart = containingGroup.RootPart;
+
+ if (rootPart != null)
+ {
+ Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor;
+ if (rootPhysActor != null)
+ {
+ ret = (int)rootPhysActor.Extension(PhysFunctGetLinksetType);
+ }
+ else
+ {
+ m_log.WarnFormat("{0} physGetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}",
+ LogHeader, rootPart.Name, hostID);
+ }
+ }
+ else
+ {
+ m_log.WarnFormat("{0} physGetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}",
+ LogHeader, requestingPart.Name, hostID);
+ }
+ }
+ else
+ {
+ m_log.WarnFormat("{0} physGetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
+ }
+ return ret;
}
}
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 7f946662ad..3afd52e142 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -70,6 +70,17 @@ public abstract class BSLinkset
return ret;
}
+ public class BSLinkInfo
+ {
+ public BSPrimLinkable member;
+ public BSLinkInfo(BSPrimLinkable pMember)
+ {
+ member = pMember;
+ }
+ }
+
+ public LinksetImplementation LinksetImpl { get; protected set; }
+
public BSPrimLinkable LinksetRoot { get; protected set; }
protected BSScene m_physicsScene { get; private set; }
@@ -78,7 +89,8 @@ public abstract class BSLinkset
public int LinksetID { get; private set; }
// The children under the root in this linkset.
- protected HashSet m_children;
+ // protected HashSet m_children;
+ protected Dictionary m_children;
// We lock the diddling of linkset classes to prevent any badness.
// This locks the modification of the instances of this class. Changes
@@ -109,7 +121,7 @@ public abstract class BSLinkset
m_nextLinksetID = 1;
m_physicsScene = scene;
LinksetRoot = parent;
- m_children = new HashSet();
+ m_children = new Dictionary();
LinksetMass = parent.RawMass;
Rebuilding = false;
@@ -170,17 +182,7 @@ public abstract class BSLinkset
bool ret = false;
lock (m_linksetActivityLock)
{
- ret = m_children.Contains(child);
- /* Safer version but the above should work
- foreach (BSPrimLinkable bp in m_children)
- {
- if (child.LocalID == bp.LocalID)
- {
- ret = true;
- break;
- }
- }
- */
+ ret = m_children.ContainsKey(child);
}
return ret;
}
@@ -194,7 +196,24 @@ public abstract class BSLinkset
lock (m_linksetActivityLock)
{
action(LinksetRoot);
- foreach (BSPrimLinkable po in m_children)
+ foreach (BSPrimLinkable po in m_children.Keys)
+ {
+ if (action(po))
+ break;
+ }
+ }
+ return ret;
+ }
+
+ // Perform an action on each member of the linkset including root prim.
+ // Depends on the action on whether this should be done at taint time.
+ public delegate bool ForEachLinkInfoAction(BSLinkInfo obj);
+ public virtual bool ForEachLinkInfo(ForEachLinkInfoAction action)
+ {
+ bool ret = false;
+ lock (m_linksetActivityLock)
+ {
+ foreach (BSLinkInfo po in m_children.Values)
{
if (action(po))
break;
@@ -364,7 +383,7 @@ public abstract class BSLinkset
{
lock (m_linksetActivityLock)
{
- foreach (BSPrimLinkable bp in m_children)
+ foreach (BSPrimLinkable bp in m_children.Keys)
{
mass += bp.RawMass;
}
@@ -382,7 +401,7 @@ public abstract class BSLinkset
com = LinksetRoot.Position * LinksetRoot.RawMass;
float totalMass = LinksetRoot.RawMass;
- foreach (BSPrimLinkable bp in m_children)
+ foreach (BSPrimLinkable bp in m_children.Keys)
{
com += bp.Position * bp.RawMass;
totalMass += bp.RawMass;
@@ -401,7 +420,7 @@ public abstract class BSLinkset
{
com = LinksetRoot.Position;
- foreach (BSPrimLinkable bp in m_children)
+ foreach (BSPrimLinkable bp in m_children.Keys)
{
com += bp.Position;
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 6359046ca8..085d195d83 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -42,6 +42,7 @@ public sealed class BSLinksetCompound : BSLinkset
public BSLinksetCompound(BSScene scene, BSPrimLinkable parent)
: base(scene, parent)
{
+ LinksetImpl = LinksetImplementation.Compound;
}
// ================================================================
@@ -257,7 +258,7 @@ public sealed class BSLinksetCompound : BSLinkset
{
if (!HasChild(child))
{
- m_children.Add(child);
+ m_children.Add(child, new BSLinkInfo(child));
DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
@@ -353,7 +354,7 @@ public sealed class BSLinksetCompound : BSLinkset
// Add the shapes of all the components of the linkset
int memberIndex = 1;
- ForEachMember(delegate(BSPrimLinkable cPrim)
+ ForEachMember((cPrim) =>
{
if (IsRoot(cPrim))
{
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index f17d698462..4bac222ab2 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -36,8 +36,78 @@ public sealed class BSLinksetConstraints : BSLinkset
{
// private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]";
+ public class BSLinkInfoConstraint : BSLinkInfo
+ {
+ public ConstraintType constraintType;
+ public BSConstraint constraint;
+ public OMV.Vector3 linearLimitLow;
+ public OMV.Vector3 linearLimitHigh;
+ public OMV.Vector3 angularLimitLow;
+ public OMV.Vector3 angularLimitHigh;
+ public bool useFrameOffset;
+ public bool enableTransMotor;
+ public float transMotorMaxVel;
+ public float transMotorMaxForce;
+ public float cfm;
+ public float erp;
+ public float solverIterations;
+
+ public BSLinkInfoConstraint(BSPrimLinkable pMember)
+ : base(pMember)
+ {
+ constraint = null;
+ ResetToFixedConstraint();
+ }
+
+ // Set all the parameters for this constraint to a fixed, non-movable constraint.
+ public void ResetToFixedConstraint()
+ {
+ constraintType = ConstraintType.D6_CONSTRAINT_TYPE;
+ linearLimitLow = OMV.Vector3.Zero;
+ linearLimitHigh = OMV.Vector3.Zero;
+ angularLimitLow = OMV.Vector3.Zero;
+ angularLimitHigh = OMV.Vector3.Zero;
+ useFrameOffset = BSParam.LinkConstraintUseFrameOffset;
+ enableTransMotor = BSParam.LinkConstraintEnableTransMotor;
+ transMotorMaxVel = BSParam.LinkConstraintTransMotorMaxVel;
+ transMotorMaxForce = BSParam.LinkConstraintTransMotorMaxForce;
+ cfm = BSParam.LinkConstraintCFM;
+ erp = BSParam.LinkConstraintERP;
+ solverIterations = BSParam.LinkConstraintSolverIterations;
+ }
+
+ // Given a constraint, apply the current constraint parameters to same.
+ public void SetConstraintParameters(BSConstraint constrain)
+ {
+ switch (constraintType)
+ {
+ case ConstraintType.D6_CONSTRAINT_TYPE:
+ BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof;
+ if (constrain6dof != null)
+ {
+ // zero linear and angular limits makes the objects unable to move in relation to each other
+ constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh);
+ constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh);
+
+ // tweek the constraint to increase stability
+ constrain6dof.UseFrameOffset(useFrameOffset);
+ constrain6dof.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce);
+ constrain6dof.SetCFMAndERP(cfm, erp);
+ if (solverIterations != 0f)
+ {
+ constrain6dof.SetSolverIterations(solverIterations);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
{
+ LinksetImpl = LinksetImplementation.Constraint;
}
// When physical properties are changed the linkset needs to recalculate
@@ -142,7 +212,7 @@ public sealed class BSLinksetConstraints : BSLinkset
{
if (!HasChild(child))
{
- m_children.Add(child);
+ m_children.Add(child, new BSLinkInfoConstraint(child));
DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
@@ -190,73 +260,74 @@ public sealed class BSLinksetConstraints : BSLinkset
}
// Create a static constraint between the two passed objects
- private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
+ private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li)
{
+ BSLinkInfoConstraint liConstraint = li as BSLinkInfoConstraint;
+ if (liConstraint == null)
+ return null;
+
// Zero motion for children so they don't interpolate
- childPrim.ZeroMotion(true);
+ li.member.ZeroMotion(true);
- // Relative position normalized to the root prim
- // Essentually a vector pointing from center of rootPrim to center of childPrim
- OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position;
+ BSConstraint constrain = null;
- // real world coordinate of midpoint between the two objects
- OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
+ switch (liConstraint.constraintType)
+ {
+ case ConstraintType.D6_CONSTRAINT_TYPE:
+ // Relative position normalized to the root prim
+ // Essentually a vector pointing from center of rootPrim to center of li.member
+ OMV.Vector3 childRelativePosition = liConstraint.member.Position - rootPrim.Position;
- DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
- rootPrim.LocalID,
- rootPrim.LocalID, rootPrim.PhysBody.AddrString,
- childPrim.LocalID, childPrim.PhysBody.AddrString,
- rootPrim.Position, childPrim.Position, midPoint);
+ // real world coordinate of midpoint between the two objects
+ OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
- // create a constraint that allows no freedom of movement between the two objects
- // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
+ DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
+ rootPrim.LocalID,
+ rootPrim.LocalID, rootPrim.PhysBody.AddrString,
+ liConstraint.member.LocalID, liConstraint.member.PhysBody.AddrString,
+ rootPrim.Position, liConstraint.member.Position, midPoint);
- BSConstraint6Dof constrain = new BSConstraint6Dof(
- m_physicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true );
- // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true );
+ // create a constraint that allows no freedom of movement between the two objects
+ // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
- /* NOTE: below is an attempt to build constraint with full frame computation, etc.
- * Using the midpoint is easier since it lets the Bullet code manipulate the transforms
- * of the objects.
- * Code left for future programmers.
- // ==================================================================================
- // relative position normalized to the root prim
- OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
- OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation;
+ constrain = new BSConstraint6Dof(
+ m_physicsScene.World, rootPrim.PhysBody, liConstraint.member.PhysBody, midPoint, true, true );
- // relative rotation of the child to the parent
- OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation;
- OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation);
+ /* NOTE: below is an attempt to build constraint with full frame computation, etc.
+ * Using the midpoint is easier since it lets the Bullet code manipulate the transforms
+ * of the objects.
+ * Code left for future programmers.
+ // ==================================================================================
+ // relative position normalized to the root prim
+ OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
+ OMV.Vector3 childRelativePosition = (liConstraint.member.Position - rootPrim.Position) * invThisOrientation;
- DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
- BS6DofConstraint constrain = new BS6DofConstraint(
- PhysicsScene.World, rootPrim.Body, childPrim.Body,
- OMV.Vector3.Zero,
- OMV.Quaternion.Inverse(rootPrim.Orientation),
- OMV.Vector3.Zero,
- OMV.Quaternion.Inverse(childPrim.Orientation),
- true,
- true
- );
- // ==================================================================================
- */
+ // relative rotation of the child to the parent
+ OMV.Quaternion childRelativeRotation = invThisOrientation * liConstraint.member.Orientation;
+ OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation);
+
+ DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, liConstraint.member.LocalID);
+ constrain = new BS6DofConstraint(
+ PhysicsScene.World, rootPrim.Body, liConstraint.member.Body,
+ OMV.Vector3.Zero,
+ OMV.Quaternion.Inverse(rootPrim.Orientation),
+ OMV.Vector3.Zero,
+ OMV.Quaternion.Inverse(liConstraint.member.Orientation),
+ true,
+ true
+ );
+ // ==================================================================================
+ */
+
+ break;
+ default:
+ break;
+ }
+
+ liConstraint.SetConstraintParameters(constrain);
m_physicsScene.Constraints.AddConstraint(constrain);
- // zero linear and angular limits makes the objects unable to move in relation to each other
- constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
- constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
-
- // tweek the constraint to increase stability
- constrain.UseFrameOffset(BSParam.LinkConstraintUseFrameOffset);
- constrain.TranslationalLimitMotor(BSParam.LinkConstraintEnableTransMotor,
- BSParam.LinkConstraintTransMotorMaxVel,
- BSParam.LinkConstraintTransMotorMaxForce);
- constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP);
- if (BSParam.LinkConstraintSolverIterations != 0f)
- {
- constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations);
- }
return constrain;
}
@@ -317,23 +388,24 @@ public sealed class BSLinksetConstraints : BSLinkset
return; // Note the 'finally' clause at the botton which will get executed.
}
- foreach (BSPrimLinkable child in m_children)
+ ForEachLinkInfo((li) =>
{
// A child in the linkset physically shows the mass of the whole linkset.
// This allows Bullet to apply enough force on the child to move the whole linkset.
// (Also do the mass stuff before recomputing the constraint so mass is not zero.)
- child.UpdatePhysicalMassProperties(linksetMass, true);
+ li.member.UpdatePhysicalMassProperties(linksetMass, true);
BSConstraint constrain;
- if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain))
+ if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, li.member.PhysBody, out constrain))
{
// If constraint doesn't exist yet, create it.
- constrain = BuildConstraint(LinksetRoot, child);
+ constrain = BuildConstraint(LinksetRoot, li);
}
constrain.RecomputeConstraintVariables(linksetMass);
// PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG
- }
+ return false; // 'false' says to keep processing other members
+ });
}
finally
{
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index e92a1d2bc5..a0b6abc01f 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -1541,6 +1541,50 @@ public class BSPrim : BSPhysObject
PhysicalActors.RemoveDependencies();
}
+ #region Extension
+ public override object Extension(string pFunct, params object[] pParams)
+ {
+ object ret = null;
+ switch (pFunct)
+ {
+ case BSScene.PhysFunctGetLinksetType:
+ {
+ BSPrimLinkable myHandle = this as BSPrimLinkable;
+ if (myHandle != null)
+ {
+ ret = (object)myHandle.LinksetType;
+ }
+ m_log.DebugFormat("{0} Extension.physGetLinksetType, type={1}", LogHeader, ret);
+ break;
+ }
+ case BSScene.PhysFunctSetLinksetType:
+ {
+ if (pParams.Length > 0)
+ {
+ BSLinkset.LinksetImplementation linksetType = (BSLinkset.LinksetImplementation)pParams[0];
+ BSPrimLinkable myHandle = this as BSPrimLinkable;
+ if (myHandle != null && myHandle.Linkset.IsRoot(myHandle))
+ {
+ PhysScene.TaintedObject("BSPrim.PhysFunctSetLinksetType", delegate()
+ {
+ // Cause the linkset type to change
+ m_log.DebugFormat("{0} Extension.physSetLinksetType, oldType={1}, newType={2}",
+ LogHeader, myHandle.Linkset.LinksetImpl, linksetType);
+ myHandle.ConvertLinkset(linksetType);
+ });
+ }
+ ret = (object)(int)linksetType;
+ }
+ break;
+ }
+ default:
+ ret = base.Extension(pFunct, pParams);
+ break;
+ }
+ return ret;
+ }
+ #endregion // Extension
+
// The physics engine says that properties have updated. Update same and inform
// the world that things have changed.
// NOTE: BSPrim.UpdateProperties is overloaded by BSPrimLinkable which modifies updates from root and children prims.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
index 2f392da971..7179a6d571 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
@@ -233,5 +233,46 @@ public class BSPrimLinkable : BSPrimDisplaced
base.HasSomeCollision = value;
}
}
+
+ // Convert the existing linkset of this prim into a new type.
+ public bool ConvertLinkset(BSLinkset.LinksetImplementation newType)
+ {
+ bool ret = false;
+ if (LinksetType != newType)
+ {
+ // Set the implementation type first so the call to BSLinkset.Factory gets the new type.
+ this.LinksetType = newType;
+
+ BSLinkset oldLinkset = this.Linkset;
+ BSLinkset newLinkset = BSLinkset.Factory(PhysScene, this);
+
+ this.Linkset = newLinkset;
+
+ // Pick up any physical dependencies this linkset might have in the physics engine.
+ oldLinkset.RemoveDependencies(this);
+
+ // Create a list of the children (mainly because can't interate through a list that's changing)
+ List children = new List();
+ oldLinkset.ForEachMember((child) =>
+ {
+ if (!oldLinkset.IsRoot(child))
+ children.Add(child);
+ return false; // 'false' says to continue to next member
+ });
+
+ // Remove the children from the old linkset and add to the new (will be a new instance from the factory)
+ foreach (BSPrimLinkable child in children)
+ {
+ oldLinkset.RemoveMeFromLinkset(child);
+ newLinkset.AddMeToLinkset(child);
+ child.Linkset = newLinkset;
+ }
+
+ // Force the shape and linkset to get reconstructed
+ newLinkset.Refresh(this);
+ this.ForceBodyShapeRebuild(true /* inTaintTime */);
+ }
+ return ret;
+ }
}
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 41aca3b2a7..79ac5a5ba0 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -862,6 +862,23 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
public override bool IsThreaded { get { return false; } }
+ #region Extensions
+ // =============================================================
+ // Per scene functions. See below.
+
+ // Per avatar functions. See BSCharacter.
+
+ // Per prim functions. See BSPrim.
+ public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType";
+ public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType";
+ // =============================================================
+
+ public override object Extension(string pFunct, params object[] pParams)
+ {
+ return base.Extension(pFunct, pParams);
+ }
+ #endregion // Extensions
+
#region Taints
// The simulation execution order is:
// Simulate()
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index 739e9848ca..44bfd429a0 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -418,7 +418,8 @@ namespace OpenSim.Region.Physics.Manager
// Extendable interface for new, physics engine specific operations
public virtual object Extension(string pFunct, params object[] pParams)
{
- throw new NotImplementedException();
+ // A NOP of the physics engine does not implement this feature
+ return null;
}
}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 52f2809fc0..dd9bbc1665 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -393,7 +393,8 @@ namespace OpenSim.Region.Physics.Manager
// Extendable interface for new, physics engine specific operations
public virtual object Extension(string pFunct, params object[] pParams)
{
- throw new NotImplementedException();
+ // A NOP if the extension thing is not implemented by the physics engine
+ return null;
}
}
}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index bd776b64c3..edcdfbc565 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -319,7 +319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
object[] convertedParms = new object[parms.Length];
for (int i = 0; i < parms.Length; i++)
- convertedParms[i] = ConvertFromLSL(parms[i],signature[i], fname);
+ convertedParms[i] = ConvertFromLSL(parms[i], signature[i], fname);
// now call the function, the contract with the function is that it will always return
// non-null but don't trust it completely
@@ -448,7 +448,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
}
- MODError(String.Format("{1}: parameter type mismatch; expecting {0}",type.Name, fname));
+ MODError(String.Format("{0}: parameter type mismatch; expecting {1}, type(parm)={2}", fname, type.Name, lslparm.GetType()));
return null;
}
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
index 9e32f4031a..6aa717db03 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
@@ -937,7 +937,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
{
string retval = null;
if (value is int)
- retval = ((int)value).ToString();
+ retval = String.Format("new LSL_Types.LSLInteger({0})",((int)value).ToString());
else if (value is float)
retval = String.Format("new LSL_Types.LSLFloat({0})",((float)value).ToString());
else if (value is string)
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs b/OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs
index 8226705183..e85b0b7e72 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs
@@ -79,7 +79,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
{
m_simianURL = m_config.GetString("SimianServiceURL");
if (String.IsNullOrEmpty(m_simianURL))
- m_log.ErrorFormat("[SimianGrid] service URL is not defined");
+ {
+ //m_log.DebugFormat("[SimianGrid] service URL is not defined");
+ m_enabled = false;
+ return;
+ }
}
}
else
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs
index a4dd36c40e..e7d2f86db6 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs
@@ -74,11 +74,15 @@ namespace OpenSim.Services.Connectors.SimianGrid
{
m_simianURL = m_config.GetString("SimianServiceURL");
if (String.IsNullOrEmpty(m_simianURL))
- m_log.ErrorFormat("[SimianGrid] service URL is not defined");
+ {
+ // m_log.DebugFormat("[SimianGrid] service URL is not defined");
+ m_enabled = false;
+ return;
+ }
InitialiseSimCap();
SimulatorCapability = SimulatorCapability.Trim();
- m_log.WarnFormat("[SimianExternalCaps] using {0} as simulator capability",SimulatorCapability);
+ m_log.InfoFormat("[SimianExternalCaps] using {0} as simulator capability",SimulatorCapability);
}
}
catch (Exception e)
diff --git a/OpenSim/Tests/Clients/Assets/AssetsClient.cs b/OpenSim/Tests/Clients/Assets/AssetsClient.cs
index 26d740b771..e988d0e36a 100644
--- a/OpenSim/Tests/Clients/Assets/AssetsClient.cs
+++ b/OpenSim/Tests/Clients/Assets/AssetsClient.cs
@@ -68,8 +68,18 @@ namespace OpenSim.Tests.Clients.AssetsClient
m_log.InfoFormat("[ASSET CLIENT]: Connecting to {0} max threads = {1} - {2}", serverURI, max1, max2);
ThreadPool.GetMinThreads(out max1, out max2);
m_log.InfoFormat("[ASSET CLIENT]: Connecting to {0} min threads = {1} - {2}", serverURI, max1, max2);
- ThreadPool.SetMinThreads(1, 1);
- ThreadPool.SetMaxThreads(10, 3);
+
+ if (!ThreadPool.SetMinThreads(1, 1))
+ m_log.WarnFormat("[ASSET CLIENT]: Failed to set min threads");
+
+ if (!ThreadPool.SetMaxThreads(10, 3))
+ m_log.WarnFormat("[ASSET CLIENT]: Failed to set max threads");
+
+ ThreadPool.GetMaxThreads(out max1, out max2);
+ m_log.InfoFormat("[ASSET CLIENT]: Post set max threads = {1} - {2}", serverURI, max1, max2);
+ ThreadPool.GetMinThreads(out max1, out max2);
+ m_log.InfoFormat("[ASSET CLIENT]: Post set min threads = {1} - {2}", serverURI, max1, max2);
+
ServicePointManager.DefaultConnectionLimit = 12;
AssetServicesConnector m_Connector = new AssetServicesConnector(serverURI);
diff --git a/OpenSim/Tools/Configger/ConfigurationLoader.cs b/OpenSim/Tools/Configger/ConfigurationLoader.cs
index 28bcc99ff4..72ba18526f 100644
--- a/OpenSim/Tools/Configger/ConfigurationLoader.cs
+++ b/OpenSim/Tools/Configger/ConfigurationLoader.cs
@@ -239,7 +239,6 @@ namespace OpenSim.Tools.Configger
config.Set("physics", "OpenDynamicsEngine");
config.Set("meshing", "Meshmerizer");
config.Set("physical_prim", true);
- config.Set("see_into_this_sim_from_neighbor", true);
config.Set("serverside_object_permissions", true);
config.Set("storage_plugin", "OpenSim.Data.SQLite.dll");
config.Set("storage_connection_string", "URI=file:OpenSim.db,version=3");
diff --git a/bin/OpenSim.32BitLaunch.exe.config b/bin/OpenSim.32BitLaunch.exe.config
index 6ac0206e6c..6a6b3c8768 100644
--- a/bin/OpenSim.32BitLaunch.exe.config
+++ b/bin/OpenSim.32BitLaunch.exe.config
@@ -11,22 +11,56 @@
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bin/OpenSim.exe.config b/bin/OpenSim.exe.config
index 8a891f4917..b2cb4e5b81 100755
--- a/bin/OpenSim.exe.config
+++ b/bin/OpenSim.exe.config
@@ -11,6 +11,10 @@
+
+
+
+
@@ -21,11 +25,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -42,5 +58,10 @@
+
+
+
+
+
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index d498258e62..313466ca38 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -180,10 +180,6 @@
;; if the first change occurred this number of seconds ago.
; MaximumTimeBeforePersistenceConsidered = 600
- ;# {see_into_this_sim_from_neighbor} {} {Should avatars in neighbor sims see objects in this sim?} {true false} true
- ;; Should avatars in neighbor sims see objects in this sim?
- ; see_into_this_sim_from_neighbor = true
-
;# {physical_prim} {} {Allow prims to be physical?} {true false} true
;; if you would like to allow prims to be physical and move by physics
;; with the physical checkbox in the client set this to true.
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index 286076da19..f8e28297b1 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -710,8 +710,8 @@
Enabled = true
; Controls the number of milliseconds that are slept per 100 prims rezzed in attachments
- ; Experimental setting to control CPU spiking when avatars with many attachments login
- ; or when multiple avatars with medium level attachments login simultaneously.
+ ; Experimental setting to control CPU spiking when avatars with many attachments login/change outfit
+ ; or when multiple avatars with medium level attachments login/change outfit simultaneously.
; If 0 then no throttling is performed.
ThrottlePer100PrimsRezzed = 0;
diff --git a/bin/Robust.32BitLaunch.exe.config b/bin/Robust.32BitLaunch.exe.config
index dae45ffaaa..ec17049a84 100644
--- a/bin/Robust.32BitLaunch.exe.config
+++ b/bin/Robust.32BitLaunch.exe.config
@@ -11,22 +11,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bin/Robust.exe.config b/bin/Robust.exe.config
index 4914f55cb2..62975fd6a1 100644
--- a/bin/Robust.exe.config
+++ b/bin/Robust.exe.config
@@ -11,6 +11,10 @@
+
+
+
+
@@ -19,15 +23,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bin/config-include/Grid.ini b/bin/config-include/Grid.ini
index 15ba55a27f..1837bdd752 100644
--- a/bin/config-include/Grid.ini
+++ b/bin/config-include/Grid.ini
@@ -30,6 +30,17 @@
SimulationServiceInConnector = true
LibraryModule = true
+[SimulationService]
+ ; This is the protocol version which the simulator advertises to the source destination when acting as a target destination for a teleport
+ ; It is used to control the teleport handoff process.
+ ; Valid values are
+ ; "SIMULATION/0.2"
+ ; - this is the default. A source simulator which only implements "SIMULATION/0.1" can still teleport with that protocol
+ ; - this protocol is more efficient than "SIMULATION/0.1"
+ ; "SIMULATION/0.1"
+ ; - this is an older teleport protocol used in OpenSimulator 0.7.5 and before.
+ ConnectorProtocolVersion = "SIMULATION/0.2"
+
[SimulationDataStore]
LocalServiceModule = "OpenSim.Services.Connectors.dll:SimulationDataService"
diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini
index d3b9cb4c85..7b7beb2cf0 100644
--- a/bin/config-include/Standalone.ini
+++ b/bin/config-include/Standalone.ini
@@ -26,6 +26,17 @@
GridInfoServiceInConnector = true
MapImageServiceInConnector = true
+[SimulationService]
+ ; This is the protocol version which the simulator advertises to the source destination when acting as a target destination for a teleport
+ ; It is used to control the teleport handoff process.
+ ; Valid values are
+ ; "SIMULATION/0.2"
+ ; - this is the default. A source simulator which only implements "SIMULATION/0.1" can still teleport with that protocol
+ ; - this protocol is more efficient than "SIMULATION/0.1"
+ ; "SIMULATION/0.1"
+ ; - this is an older teleport protocol used in OpenSimulator 0.7.5 and before.
+ ConnectorProtocolVersion = "SIMULATION/0.2"
+
[SimulationDataStore]
LocalServiceModule = "OpenSim.Services.Connectors.dll:SimulationDataService"