diff --git a/OpenSim/Framework/Console/ConsoleUtil.cs b/OpenSim/Framework/Console/ConsoleUtil.cs
new file mode 100644
index 0000000000..2612a50425
--- /dev/null
+++ b/OpenSim/Framework/Console/ConsoleUtil.cs
@@ -0,0 +1,114 @@
+/*
+ * 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 log4net;
+using OpenMetaverse;
+
+public class ConsoleUtil
+{
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ public const string MinRawConsoleVectorValue = "-~";
+ public const string MaxRawConsoleVectorValue = "~";
+
+ public const string VectorSeparator = ",";
+ public static char[] VectorSeparatorChars = VectorSeparator.ToCharArray();
+
+ ///
+ /// Convert a minimum vector input from the console to an OpenMetaverse.Vector3
+ ///
+ /// /param>
+ ///
+ ///
+ public static bool TryParseConsoleMinVector(string rawConsoleVector, out Vector3 vector)
+ {
+ return TryParseConsoleVector(rawConsoleVector, c => float.MinValue.ToString(), out vector);
+ }
+
+ ///
+ /// Convert a maximum vector input from the console to an OpenMetaverse.Vector3
+ ///
+ /// /param>
+ ///
+ ///
+ public static bool TryParseConsoleMaxVector(string rawConsoleVector, out Vector3 vector)
+ {
+ return TryParseConsoleVector(rawConsoleVector, c => float.MaxValue.ToString(), out vector);
+ }
+
+ ///
+ /// Convert a vector input from the console to an OpenMetaverse.Vector3
+ ///
+ ///
+ /// A string in the form ,, where there is no space between values.
+ /// Any component can be missing (e.g. ,,40). blankComponentFunc is invoked to replace the blank with a suitable value
+ /// Also, if the blank component is at the end, then the comma can be missed off entirely (e.g. 40,30 or 40)
+ /// The strings "~" and "-~" are valid in components. The first substitutes float.MaxValue whilst the second is float.MinValue
+ /// Other than that, component values must be numeric.
+ ///
+ ///
+ ///
+ ///
+ public static bool TryParseConsoleVector(
+ string rawConsoleVector, Func blankComponentFunc, out Vector3 vector)
+ {
+ List components = rawConsoleVector.Split(VectorSeparatorChars).ToList();
+
+ if (components.Count < 1 || components.Count > 3)
+ {
+ vector = Vector3.Zero;
+ return false;
+ }
+
+ for (int i = components.Count; i < 3; i++)
+ components.Add("");
+
+ List semiDigestedComponents
+ = components.ConvertAll(
+ c =>
+ {
+ if (c == "")
+ return blankComponentFunc.Invoke(c);
+ else if (c == MaxRawConsoleVectorValue)
+ return float.MaxValue.ToString();
+ else if (c == MinRawConsoleVectorValue)
+ return float.MinValue.ToString();
+ else
+ return c;
+ });
+
+ string semiDigestedConsoleVector = string.Join(VectorSeparator, semiDigestedComponents.ToArray());
+
+ m_log.DebugFormat("[CONSOLE UTIL]: Parsing {0} into OpenMetaverse.Vector3", semiDigestedConsoleVector);
+
+ return Vector3.TryParse(semiDigestedConsoleVector, out vector);
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Framework/GridInstantMessage.cs b/OpenSim/Framework/GridInstantMessage.cs
index a6bf6e3c32..6ae0488fc2 100644
--- a/OpenSim/Framework/GridInstantMessage.cs
+++ b/OpenSim/Framework/GridInstantMessage.cs
@@ -44,7 +44,6 @@ namespace OpenSim.Framework
public Vector3 Position;
public byte[] binaryBucket;
-
public uint ParentEstateID;
public Guid RegionID;
public uint timestamp;
@@ -58,7 +57,7 @@ namespace OpenSim.Framework
string _fromAgentName, UUID _toAgentID,
byte _dialog, bool _fromGroup, string _message,
UUID _imSessionID, bool _offline, Vector3 _position,
- byte[] _binaryBucket)
+ byte[] _binaryBucket, bool addTimestamp)
{
fromAgentID = _fromAgentID.Guid;
fromAgentName = _fromAgentName;
@@ -79,7 +78,9 @@ namespace OpenSim.Framework
ParentEstateID = scene.RegionInfo.EstateSettings.ParentEstateID;
RegionID = scene.RegionInfo.RegionSettings.RegionUUID.Guid;
}
- timestamp = (uint)Util.UnixTimeSinceEpoch();
+
+ if (addTimestamp)
+ timestamp = (uint)Util.UnixTimeSinceEpoch();
}
public GridInstantMessage(IScene scene, UUID _fromAgentID,
@@ -87,7 +88,7 @@ namespace OpenSim.Framework
string _message, bool _offline,
Vector3 _position) : this(scene, _fromAgentID, _fromAgentName,
_toAgentID, _dialog, false, _message,
- _fromAgentID ^ _toAgentID, _offline, _position, new byte[0])
+ _fromAgentID ^ _toAgentID, _offline, _position, new byte[0], true)
{
}
}
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index a26e9308db..74551ea3f2 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -545,6 +545,19 @@ namespace OpenSim.Framework
return (x + y - (min >> 1) - (min >> 2) + (min >> 4));
}
+ ///
+ /// Determines whether a point is inside a bounding box.
+ ///
+ /// /param>
+ ///
+ ///
+ ///
+ public static bool IsInsideBox(Vector3 v, Vector3 min, Vector3 max)
+ {
+ return v.X >= min.X & v.Y >= min.Y && v.Z >= min.Z
+ && v.X <= max.X && v.Y <= max.Y && v.Z <= max.Z;
+ }
+
///
/// Are the co-ordinates of the new region visible from the old region?
///
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 6f00957743..6ccabf153b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -5962,7 +5962,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
msgpack.MessageBlock.ID,
msgpack.MessageBlock.Offline != 0 ? true : false,
msgpack.MessageBlock.Position,
- msgpack.MessageBlock.BinaryBucket);
+ msgpack.MessageBlock.BinaryBucket,
+ true);
handlerInstantMessage(this, im);
}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 60ab70edb0..b3db0644c4 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -227,6 +227,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_pausedAckTimeout = 1000 * 300; // 5 minutes
}
+ // FIXME: This actually only needs to be done once since the PacketPool is shared across all servers.
+ // However, there is no harm in temporarily doing it multiple times.
+ IConfig packetConfig = configSource.Configs["PacketPool"];
+ if (packetConfig != null)
+ {
+ PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
+ PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
+ }
+
#region BinaryStats
config = configSource.Configs["Statistics.Binary"];
m_shouldCollectStats = false;
diff --git a/OpenSim/Framework/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
similarity index 98%
rename from OpenSim/Framework/PacketPool.cs
rename to OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
index 41d17c54f2..fc9406b88d 100644
--- a/OpenSim/Framework/PacketPool.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -32,9 +32,8 @@ using OpenMetaverse;
using OpenMetaverse.Packets;
using log4net;
-namespace OpenSim.Framework
+namespace OpenSim.Region.ClientStack.LindenUDP
{
-
public sealed class PacketPool
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -44,6 +43,9 @@ namespace OpenSim.Framework
private bool packetPoolEnabled = true;
private bool dataBlockPoolEnabled = true;
+ ///
+ /// Pool of packets available for reuse.
+ ///
private readonly Dictionary> pool = new Dictionary>();
private static Dictionary> DataBlocks =
@@ -244,4 +246,4 @@ namespace OpenSim.Framework
}
}
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
index d942e8742a..5ec0ea94b4 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
@@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
client.FirstName+" "+client.LastName,
destID, (byte)211, false,
String.Empty,
- transactionID, false, new Vector3(), new byte[0]),
+ transactionID, false, new Vector3(), new byte[0], true),
delegate(bool success) {} );
}
}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index c14cb1791b..21dff4bfee 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -313,6 +313,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
m_TransferModule.SendInstantMessage(im, delegate(bool success) {});
}
}
+
+ // XXX: This code was placed here to try and accomdate RLV which moves given folders named #RLV/~
+ // to a folder called name in #RLV. However, this approach may not be ultimately correct - from analysis
+ // of Firestorm 4.2.2 on sending an InventoryOffered instead of TaskInventoryOffered (as was previously
+ // done), the viewer itself would appear to move and rename the folder, rather than the simulator doing it here.
else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
{
UUID destinationFolderID = UUID.Zero;
@@ -324,6 +329,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
if (destinationFolderID != UUID.Zero)
{
+ InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId);
+ if (destinationFolder == null)
+ {
+ m_log.WarnFormat(
+ "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist",
+ client.Name, scene.Name, destinationFolderID);
+
+ return;
+ }
+
IInventoryService invService = scene.InventoryService;
UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip
@@ -331,9 +346,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId);
item = invService.GetItem(item);
InventoryFolderBase folder = null;
+ UUID? previousParentFolderID = null;
if (item != null) // It's an item
{
+ previousParentFolderID = item.Folder;
item.Folder = destinationFolderID;
invService.DeleteItems(item.Owner, new List() { item.ID });
@@ -346,10 +363,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
if (folder != null) // It's a folder
{
+ previousParentFolderID = folder.ParentID;
folder.ParentID = destinationFolderID;
invService.MoveFolder(folder);
}
}
+
+ // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code).
+ if (previousParentFolderID != null)
+ {
+ InventoryFolderBase previousParentFolder
+ = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId);
+ previousParentFolder = invService.GetFolder(previousParentFolder);
+ scene.SendInventoryUpdate(client, previousParentFolder, true, true);
+
+ scene.SendInventoryUpdate(client, destinationFolder, true, true);
+ }
}
}
else if (
@@ -370,9 +399,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId);
item = invService.GetItem(item);
InventoryFolderBase folder = null;
+ UUID? previousParentFolderID = null;
if (item != null && trashFolder != null)
{
+ previousParentFolderID = item.Folder;
item.Folder = trashFolder.ID;
// Diva comment: can't we just update this item???
@@ -388,6 +419,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
if (folder != null & trashFolder != null)
{
+ previousParentFolderID = folder.ParentID;
folder.ParentID = trashFolder.ID;
invService.MoveFolder(folder);
client.SendBulkUpdateInventory(folder);
@@ -408,6 +440,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
client.SendAgentAlertMessage("Unable to delete "+
"received inventory" + reason, false);
}
+ // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code).
+ else if (previousParentFolderID != null)
+ {
+ InventoryFolderBase previousParentFolder
+ = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId);
+ previousParentFolder = invService.GetFolder(previousParentFolder);
+ scene.SendInventoryUpdate(client, previousParentFolder, true, true);
+
+ scene.SendInventoryUpdate(client, trashFolder, true, true);
+ }
ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
index 92cf9d1616..9c369f6060 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
@@ -186,7 +186,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
client.FirstName+" "+client.LastName, targetid,
(byte)InstantMessageDialog.RequestTeleport, false,
message, sessionID, false, presence.AbsolutePosition,
- new Byte[0]);
+ new Byte[0], true);
m.RegionID = client.Scene.RegionInfo.RegionID.Guid;
m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", m.imSessionID, m.RegionID, m.message);
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index c5bb9a5080..e355ebf1fe 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -1028,6 +1028,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
Scene initiatingScene)
{
Thread.Sleep(10000);
+
IMessageTransferModule im = initiatingScene.RequestModuleInterface();
if (im != null)
{
@@ -1040,11 +1041,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
(uint)(int)position.X,
(uint)(int)position.Y,
(uint)(int)position.Z);
- GridInstantMessage m = new GridInstantMessage(initiatingScene, UUID.Zero,
- "Region", agent.UUID,
- (byte)InstantMessageDialog.GodLikeRequestTeleport, false,
- "", gotoLocation, false, new Vector3(127, 0, 0),
- new Byte[0]);
+
+ GridInstantMessage m
+ = new GridInstantMessage(
+ initiatingScene,
+ UUID.Zero,
+ "Region",
+ agent.UUID,
+ (byte)InstantMessageDialog.GodLikeRequestTeleport,
+ false,
+ "",
+ gotoLocation,
+ false,
+ new Vector3(127, 0, 0),
+ new Byte[0],
+ false);
+
im.SendInstantMessage(m, delegate(bool success)
{
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Client Initiating Teleport sending IM success = {0}", success);
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 36c84c7bc6..b4811dadce 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -31,6 +31,7 @@ using System.Reflection;
using OpenSim.Framework;
using OpenSim.Framework.Console;
+using OpenSim.Region.ClientStack.LindenUDP;
using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
index 09f6758ba4..6e39e9acc9 100644
--- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
@@ -123,6 +123,25 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
"If --regex is specified then the name is treatead as a regular expression",
HandleShowObjectByName);
+ m_console.Commands.AddCommand(
+ "Objects",
+ false,
+ "show object pos",
+ "show object pos to ",
+ "Show details of scene objects within the given area.",
+ "Each component of the coord is comma separated. There must be no spaces between the commas.\n"
+ + "If you don't care about the z component you can simply omit it.\n"
+ + "If you don't care about the x or y components then you can leave them blank (though a comma is still required)\n"
+ + "If you want to specify the maxmimum value of a component then you can use ~ instead of a number\n"
+ + "If you want to specify the minimum value of a component then you can use -~ instead of a number\n"
+ + "e.g.\n"
+ + "show object pos 20,20,20 to 40,40,40\n"
+ + "show object pos 20,20 to 40,40\n"
+ + "show object pos ,20,20 to ,40,40\n"
+ + "show object pos ,,30 to ,,~\n"
+ + "show object pos ,,-~ to ,,30",
+ HandleShowObjectByPos);
+
m_console.Commands.AddCommand(
"Objects",
false,
@@ -138,6 +157,25 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
"Show details of scene object parts with the given name.",
"If --regex is specified then the name is treatead as a regular expression",
HandleShowPartByName);
+
+ m_console.Commands.AddCommand(
+ "Objects",
+ false,
+ "show part pos",
+ "show part pos to ",
+ "Show details of scene object parts within the given area.",
+ "Each component of the coord is comma separated. There must be no spaces between the commas.\n"
+ + "If you don't care about the z component you can simply omit it.\n"
+ + "If you don't care about the x or y components then you can leave them blank (though a comma is still required)\n"
+ + "If you want to specify the maxmimum value of a component then you can use ~ instead of a number\n"
+ + "If you want to specify the minimum value of a component then you can use -~ instead of a number\n"
+ + "e.g.\n"
+ + "show object pos 20,20,20 to 40,40,40\n"
+ + "show object pos 20,20 to 40,40\n"
+ + "show object pos ,20,20 to ,40,40\n"
+ + "show object pos ,,30 to ,,~\n"
+ + "show object pos ,,-~ to ,,30",
+ HandleShowPartByPos);
}
public void RemoveRegion(Scene scene)
@@ -150,6 +188,43 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
// m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
}
+ private void OutputSogsToConsole(Predicate searchPredicate)
+ {
+ List sceneObjects = m_scene.GetSceneObjectGroups().FindAll(searchPredicate);
+
+ StringBuilder sb = new StringBuilder();
+
+ foreach (SceneObjectGroup so in sceneObjects)
+ {
+ AddSceneObjectReport(sb, so);
+ sb.Append("\n");
+ }
+
+ sb.AppendFormat("{0} object(s) found in {1}\n", sceneObjects.Count, m_scene.Name);
+
+ m_console.OutputFormat(sb.ToString());
+ }
+
+ private void OutputSopsToConsole(Predicate searchPredicate)
+ {
+ List sceneObjects = m_scene.GetSceneObjectGroups();
+ List parts = new List();
+
+ sceneObjects.ForEach(so => parts.AddRange(Array.FindAll(so.Parts, searchPredicate)));
+
+ StringBuilder sb = new StringBuilder();
+
+ foreach (SceneObjectPart part in parts)
+ {
+ AddScenePartReport(sb, part);
+ sb.Append("\n");
+ }
+
+ sb.AppendFormat("{0} parts found in {1}\n", parts.Count, m_scene.Name);
+
+ m_console.OutputFormat(sb.ToString());
+ }
+
private void HandleShowObjectByUuid(string module, string[] cmd)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
@@ -200,36 +275,54 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
string name = mainParams[3];
- List sceneObjects = new List();
- Action searchAction;
+ Predicate searchPredicate;
if (useRegex)
{
Regex nameRegex = new Regex(name);
- searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }};
+ searchPredicate = so => nameRegex.IsMatch(so.Name);
}
else
{
- searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }};
+ searchPredicate = so => so.Name == name;
}
- m_scene.ForEachSOG(searchAction);
+ OutputSogsToConsole(searchPredicate);
+ }
- if (sceneObjects.Count == 0)
+ private void HandleShowObjectByPos(string module, string[] cmdparams)
+ {
+ if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
+ return;
+
+ if (cmdparams.Length < 5)
{
- m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName);
+ m_console.OutputFormat("Usage: show object pos to ");
return;
}
- StringBuilder sb = new StringBuilder();
+ string rawConsoleStartVector = cmdparams[3];
+ Vector3 startVector;
- foreach (SceneObjectGroup so in sceneObjects)
+ if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector))
{
- AddSceneObjectReport(sb, so);
- sb.Append("\n");
+ m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector);
+ return;
}
- m_console.OutputFormat(sb.ToString());
+ string rawConsoleEndVector = cmdparams[5];
+ Vector3 endVector;
+
+ if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector))
+ {
+ m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector);
+ return;
+ }
+
+ Predicate searchPredicate
+ = so => Util.IsInsideBox(so.AbsolutePosition, startVector, endVector);
+
+ OutputSogsToConsole(searchPredicate);
}
private void HandleShowPartByUuid(string module, string[] cmd)
@@ -264,6 +357,38 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
m_console.OutputFormat(sb.ToString());
}
+ private void HandleShowPartByPos(string module, string[] cmdparams)
+ {
+ if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
+ return;
+
+ if (cmdparams.Length < 5)
+ {
+ m_console.OutputFormat("Usage: show part pos to ");
+ return;
+ }
+
+ string rawConsoleStartVector = cmdparams[3];
+ Vector3 startVector;
+
+ if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector))
+ {
+ m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector);
+ return;
+ }
+
+ string rawConsoleEndVector = cmdparams[5];
+ Vector3 endVector;
+
+ if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector))
+ {
+ m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector);
+ return;
+ }
+
+ OutputSopsToConsole(sop => Util.IsInsideBox(sop.AbsolutePosition, startVector, endVector));
+ }
+
private void HandleShowPartByName(string module, string[] cmdparams)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
@@ -282,37 +407,19 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
string name = mainParams[3];
- List parts = new List();
-
- Action searchAction;
+ Predicate searchPredicate;
if (useRegex)
{
Regex nameRegex = new Regex(name);
- searchAction = so => so.ForEachPart(sop => { if (nameRegex.IsMatch(sop.Name)) { parts.Add(sop); } });
+ searchPredicate = sop => nameRegex.IsMatch(sop.Name);
}
else
{
- searchAction = so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } });
+ searchPredicate = sop => sop.Name == name;
}
- m_scene.ForEachSOG(searchAction);
-
- if (parts.Count == 0)
- {
- m_console.OutputFormat("No parts with name {0} found in {1}", name, m_scene.RegionInfo.RegionName);
- return;
- }
-
- StringBuilder sb = new StringBuilder();
-
- foreach (SceneObjectPart part in parts)
- {
- AddScenePartReport(sb, part);
- sb.Append("\n");
- }
-
- m_console.OutputFormat(sb.ToString());
+ OutputSopsToConsole(searchPredicate);
}
private StringBuilder AddSceneObjectReport(StringBuilder sb, SceneObjectGroup so)
diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
index 24cd06978e..f8088c3d3c 100644
--- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
+++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
@@ -1,4 +1,31 @@
-using System;
+/*
+ * 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 OpenMetaverse;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 35df85c750..30bf7441ac 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -1469,7 +1469,7 @@ namespace OpenSim.Region.Framework.Scenes
return newFolderID;
}
- private void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems)
+ public void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems)
{
if (folder == null)
return;
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index bb3748ec29..66fc216913 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -148,7 +148,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
OnInstantMessage(this, new GridInstantMessage(m_scene,
m_uuid, m_firstname + " " + m_lastname,
target, 0, false, message,
- UUID.Zero, false, Position, new byte[0]));
+ UUID.Zero, false, Position, new byte[0], true));
}
public void SendAgentOffline(UUID[] agentIDs)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index d8da173b1c..49f0ef7b8b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -4326,7 +4326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
World.RegionInfo.RegionName+" "+
m_host.AbsolutePosition.ToString(),
agentItem.ID, true, m_host.AbsolutePosition,
- bucket);
+ bucket, true);
ScenePresence sp;
@@ -6912,16 +6912,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (m_TransferModule != null)
{
byte[] bucket = new byte[] { (byte)AssetType.Folder };
-
+
+ Vector3 pos = m_host.AbsolutePosition;
+
GridInstantMessage msg = new GridInstantMessage(World,
- m_host.UUID, m_host.Name + ", an object owned by " +
- resolveName(m_host.OwnerID) + ",", destID,
+ m_host.OwnerID, m_host.Name, destID,
(byte)InstantMessageDialog.TaskInventoryOffered,
- false, category + "\n" + m_host.Name + " is located at " +
- World.RegionInfo.RegionName + " " +
- m_host.AbsolutePosition.ToString(),
- folderID, true, m_host.AbsolutePosition,
- bucket);
+ false, string.Format("'{0}'"),
+// We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06
+// false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z),
+ folderID, false, pos,
+ bucket, false);
m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
}
diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs
index c11ea0225a..625eba4b0a 100644
--- a/OpenSim/Region/UserStatistics/WebStatsModule.cs
+++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Region.UserStatistics
///
/// User statistics sessions keyed by agent ID
///
- private Dictionary m_sessions = new Dictionary();
+ private Dictionary m_sessions = new Dictionary();
private List m_scenes = new List();
private Dictionary reports = new Dictionary();
@@ -319,14 +319,18 @@ namespace OpenSim.Region.UserStatistics
private void OnMakeRootAgent(ScenePresence agent)
{
+// m_log.DebugFormat(
+// "[WEB STATS MODULE]: Looking for session {0} for {1} in {2}",
+// agent.ControllingClient.SessionId, agent.Name, agent.Scene.Name);
+
lock (m_sessions)
{
- UserSessionID uid;
+ UserSession uid;
if (!m_sessions.ContainsKey(agent.UUID))
{
UserSessionData usd = UserSessionUtil.newUserSessionData();
- uid = new UserSessionID();
+ uid = new UserSession();
uid.name_f = agent.Firstname;
uid.name_l = agent.Lastname;
uid.session_data = usd;
@@ -411,9 +415,9 @@ namespace OpenSim.Region.UserStatistics
return String.Empty;
}
- private UserSessionID ParseViewerStats(string request, UUID agentID)
+ private UserSession ParseViewerStats(string request, UUID agentID)
{
- UserSessionID uid = new UserSessionID();
+ UserSession uid = new UserSession();
UserSessionData usd;
OSD message = OSDParser.DeserializeLLSDXml(request);
OSDMap mmap;
@@ -425,22 +429,25 @@ namespace OpenSim.Region.UserStatistics
if (!m_sessions.ContainsKey(agentID))
{
m_log.WarnFormat("[WEB STATS MODULE]: no session for stat disclosure for agent {0}", agentID);
- return new UserSessionID();
+ return new UserSession();
}
+
uid = m_sessions[agentID];
+
+// m_log.DebugFormat("[WEB STATS MODULE]: Got session {0} for {1}", uid.session_id, agentID);
}
else
{
// parse through the beginning to locate the session
if (message.Type != OSDType.Map)
- return new UserSessionID();
+ return new UserSession();
mmap = (OSDMap)message;
{
UUID sessionID = mmap["session_id"].AsUUID();
if (sessionID == UUID.Zero)
- return new UserSessionID();
+ return new UserSession();
// search through each session looking for the owner
@@ -459,7 +466,7 @@ namespace OpenSim.Region.UserStatistics
// can't find a session
if (agentID == UUID.Zero)
{
- return new UserSessionID();
+ return new UserSession();
}
}
}
@@ -468,12 +475,12 @@ namespace OpenSim.Region.UserStatistics
usd = uid.session_data;
if (message.Type != OSDType.Map)
- return new UserSessionID();
+ return new UserSession();
mmap = (OSDMap)message;
{
if (mmap["agent"].Type != OSDType.Map)
- return new UserSessionID();
+ return new UserSession();
OSDMap agent_map = (OSDMap)mmap["agent"];
usd.agent_id = agentID;
usd.name_f = uid.name_f;
@@ -493,17 +500,18 @@ namespace OpenSim.Region.UserStatistics
(float)agent_map["fps"].AsReal());
if (mmap["downloads"].Type != OSDType.Map)
- return new UserSessionID();
+ return new UserSession();
OSDMap downloads_map = (OSDMap)mmap["downloads"];
usd.d_object_kb = (float)downloads_map["object_kbytes"].AsReal();
usd.d_texture_kb = (float)downloads_map["texture_kbytes"].AsReal();
usd.d_world_kb = (float)downloads_map["workd_kbytes"].AsReal();
+// m_log.DebugFormat("[WEB STATS MODULE]: mmap[\"session_id\"] = [{0}]", mmap["session_id"].AsUUID());
usd.session_id = mmap["session_id"].AsUUID();
if (mmap["system"].Type != OSDType.Map)
- return new UserSessionID();
+ return new UserSession();
OSDMap system_map = (OSDMap)mmap["system"];
usd.s_cpu = system_map["cpu"].AsString();
@@ -512,13 +520,13 @@ namespace OpenSim.Region.UserStatistics
usd.s_ram = system_map["ram"].AsInteger();
if (mmap["stats"].Type != OSDType.Map)
- return new UserSessionID();
+ return new UserSession();
OSDMap stats_map = (OSDMap)mmap["stats"];
{
if (stats_map["failures"].Type != OSDType.Map)
- return new UserSessionID();
+ return new UserSession();
OSDMap stats_failures = (OSDMap)stats_map["failures"];
usd.f_dropped = stats_failures["dropped"].AsInteger();
usd.f_failed_resends = stats_failures["failed_resends"].AsInteger();
@@ -527,18 +535,18 @@ namespace OpenSim.Region.UserStatistics
usd.f_send_packet = stats_failures["send_packet"].AsInteger();
if (stats_map["net"].Type != OSDType.Map)
- return new UserSessionID();
+ return new UserSession();
OSDMap stats_net = (OSDMap)stats_map["net"];
{
if (stats_net["in"].Type != OSDType.Map)
- return new UserSessionID();
+ return new UserSession();
OSDMap net_in = (OSDMap)stats_net["in"];
usd.n_in_kb = (float)net_in["kbytes"].AsReal();
usd.n_in_pk = net_in["packets"].AsInteger();
if (stats_net["out"].Type != OSDType.Map)
- return new UserSessionID();
+ return new UserSession();
OSDMap net_out = (OSDMap)stats_net["out"];
usd.n_out_kb = (float)net_out["kbytes"].AsReal();
@@ -549,11 +557,18 @@ namespace OpenSim.Region.UserStatistics
uid.session_data = usd;
m_sessions[agentID] = uid;
+
+// m_log.DebugFormat(
+// "[WEB STATS MODULE]: Parse data for {0} {1}, session {2}", uid.name_f, uid.name_l, uid.session_id);
+
return uid;
}
- private void UpdateUserStats(UserSessionID uid, SqliteConnection db)
+ private void UpdateUserStats(UserSession uid, SqliteConnection db)
{
+// m_log.DebugFormat(
+// "[WEB STATS MODULE]: Updating user stats for {0} {1}, session {2}", uid.name_f, uid.name_l, uid.session_id);
+
if (uid.session_id == UUID.Zero)
return;
@@ -740,7 +755,6 @@ VALUES
s.min_ping = ArrayMin_f(__ping);
s.max_ping = ArrayMax_f(__ping);
s.mode_ping = ArrayMode_f(__ping);
-
}
#region Statistics
@@ -985,7 +999,7 @@ VALUES
}
#region structs
- public struct UserSessionID
+ public class UserSession
{
public UUID session_id;
public UUID region_id;
diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
index 9d6d9ad69c..88a3026aa2 100644
--- a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
@@ -52,6 +52,8 @@ namespace OpenSim.Services.Connectors
private int m_retryCounter;
private Dictionary> m_retryQueue = new Dictionary>();
private System.Timers.Timer m_retryTimer;
+ private int m_maxAssetRequestConcurrency = 30;
+
private delegate void AssetRetrievedEx(AssetBase asset);
// Keeps track of concurrent requests for the same asset, so that it's only loaded once.
@@ -80,6 +82,10 @@ namespace OpenSim.Services.Connectors
public virtual void Initialise(IConfigSource source)
{
+ IConfig netconfig = source.Configs["Network"];
+ if (netconfig != null)
+ m_maxAssetRequestConcurrency = netconfig.GetInt("MaxRequestConcurrency",m_maxAssetRequestConcurrency);
+
IConfig assetConfig = source.Configs["AssetService"];
if (assetConfig == null)
{
@@ -204,7 +210,7 @@ namespace OpenSim.Services.Connectors
if (asset == null || asset.Data == null || asset.Data.Length == 0)
{
asset = SynchronousRestObjectRequester.
- MakeRequest("GET", uri, 0, 30);
+ MakeRequest("GET", uri, 0, m_maxAssetRequestConcurrency);
if (m_Cache != null)
m_Cache.Cache(asset);
@@ -311,7 +317,7 @@ namespace OpenSim.Services.Connectors
h.Invoke(a);
if (handlers != null)
handlers.Clear();
- }, 30);
+ }, m_maxAssetRequestConcurrency);
success = true;
}
diff --git a/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs b/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs
index 20d7eaf301..94bda82d14 100644
--- a/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs
+++ b/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs
@@ -207,7 +207,7 @@ namespace OpenSim.Services.Connectors
if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null))
{
if (replyData["result"] is Dictionary)
- guinfo = new GridUserInfo((Dictionary)replyData["result"]);
+ guinfo = Create((Dictionary)replyData["result"]);
}
return guinfo;
@@ -273,7 +273,7 @@ namespace OpenSim.Services.Connectors
{
if (griduser is Dictionary)
{
- GridUserInfo pinfo = new GridUserInfo((Dictionary)griduser);
+ GridUserInfo pinfo = Create((Dictionary)griduser);
rinfos.Add(pinfo);
}
else
@@ -286,5 +286,10 @@ namespace OpenSim.Services.Connectors
return rinfos.ToArray();
}
+
+ protected virtual GridUserInfo Create(Dictionary griduser)
+ {
+ return new GridUserInfo(griduser);
+ }
}
}
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index 042fd3a612..f4d9021888 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -423,6 +423,10 @@
; " (Mozilla Compatible)" to the text where there are problems with a web server
;user_agent = "OpenSim LSL (Mozilla Compatible)"
+ ; OpenSim can send multiple simultaneous requests for services such as asset
+ ; retrieval. However, some versions of mono appear to hang when there are too
+ ; many simultaneous requests, default is 30 and is currently applied only to assets
+ ;MaxRequestConcurrency = 30
[XMLRPC]
; ##
diff --git a/prebuild.xml b/prebuild.xml
index d149010d06..eae85bb4c8 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -1497,110 +1497,6 @@
-
-
-
- ../../../bin/
- true
-
-
-
-
- ../../../bin/
- true
-
-
-
- ../../../bin/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ../../../bin/
-
-
-
-
- ../../../bin/
-
-
-
- ../../../bin/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1723,6 +1619,111 @@
+
+
+
+ ../../../bin/
+ true
+
+
+
+
+ ../../../bin/
+ true
+
+
+
+ ../../../bin/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ../../../bin/
+
+
+
+
+ ../../../bin/
+
+
+
+ ../../../bin/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+