Merge branch 'master' into careminster

Conflicts:
	OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
	OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
	OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
	OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
	OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
avinationmerge
Melanie 2012-10-26 21:13:01 +01:00
commit 26cc57b6ca
47 changed files with 1117 additions and 449 deletions

View File

@ -358,6 +358,9 @@ namespace OpenSim.Framework
SetVisualParams(visualParams);
}
/// <summary>
/// Set avatar height by a calculation based on their visual parameters.
/// </summary>
public virtual void SetHeight()
{
// Start with shortest possible female avatar height

View File

@ -33,7 +33,8 @@ namespace OpenSim.Framework.Client
{
event ChatMessage OnChatFromClient;
void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, byte source,
byte audible);
void SendChatMessage(
string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, UUID ownerID, byte source,
byte audible);
}
}
}

View File

@ -27,88 +27,202 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using log4net;
using OpenMetaverse;
public class ConsoleUtil
namespace OpenSim.Framework.Console
{
// 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();
/// <summary>
/// Convert a minimum vector input from the console to an OpenMetaverse.Vector3
/// </summary>
/// <param name='rawConsoleVector'>/param>
/// <param name='vector'></param>
/// <returns></returns>
public static bool TryParseConsoleMinVector(string rawConsoleVector, out Vector3 vector)
public class ConsoleUtil
{
return TryParseConsoleVector(rawConsoleVector, c => float.MinValue.ToString(), out vector);
}
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Convert a maximum vector input from the console to an OpenMetaverse.Vector3
/// </summary>
/// <param name='rawConsoleVector'>/param>
/// <param name='vector'></param>
/// <returns></returns>
public static bool TryParseConsoleMaxVector(string rawConsoleVector, out Vector3 vector)
{
return TryParseConsoleVector(rawConsoleVector, c => float.MaxValue.ToString(), out vector);
}
public const int LocalIdNotFound = 0;
/// <summary>
/// Used by modules to display stock co-ordinate help, though possibly this should be under some general section
/// rather than in each help summary.
/// </summary>
public const string CoordHelp
= @"Each component of the coord is comma separated. There must be no spaces between the commas.
If you don't care about the z component you can simply omit it.
If you don't care about the x or y components then you can leave them blank (though a comma is still required)
If you want to specify the maxmimum value of a component then you can use ~ instead of a number
If you want to specify the minimum value of a component then you can use -~ instead of a number
e.g.
delete object pos 20,20,20 to 40,40,40
delete object pos 20,20 to 40,40
delete object pos ,20,20 to ,40,40
delete object pos ,,30 to ,,~
delete object pos ,,-~ to ,,30";
public const string MinRawConsoleVectorValue = "-~";
public const string MaxRawConsoleVectorValue = "~";
public const string VectorSeparator = ",";
public static char[] VectorSeparatorChars = VectorSeparator.ToCharArray();
/// <summary>
/// Convert a vector input from the console to an OpenMetaverse.Vector3
/// </summary>
/// <param name='rawConsoleVector'>
/// A string in the form <x>,<y>,<z> 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.
/// </param>
/// <param name='blankComponentFunc'></param>
/// <param name='vector'></param>
/// <returns></returns>
public static bool TryParseConsoleVector(
string rawConsoleVector, Func<string, string> blankComponentFunc, out Vector3 vector)
{
List<string> components = rawConsoleVector.Split(VectorSeparatorChars).ToList();
if (components.Count < 1 || components.Count > 3)
/// <summary>
/// Check if the given file path exists.
/// </summary>
/// <remarks>If not, warning is printed to the given console.</remarks>
/// <returns>true if the file does not exist, false otherwise.</returns>
/// <param name='console'></param>
/// <param name='path'></param>
public static bool CheckFileDoesNotExist(ICommandConsole console, string path)
{
vector = Vector3.Zero;
return false;
if (File.Exists(path))
{
console.OutputFormat("File {0} already exists. Please move or remove it.", path);
return false;
}
return true;
}
/// <summary>
/// Try to parse a console UUID from the console.
/// </summary>
/// <remarks>
/// Will complain to the console if parsing fails.
/// </remarks>
/// <returns></returns>
/// <param name='console'>If null then no complaint is printed.</param>
/// <param name='rawUuid'></param>
/// <param name='uuid'></param>
public static bool TryParseConsoleUuid(ICommandConsole console, string rawUuid, out UUID uuid)
{
if (!UUID.TryParse(rawUuid, out uuid))
{
if (console != null)
console.OutputFormat("{0} is not a valid uuid", rawUuid);
return false;
}
return true;
}
for (int i = components.Count; i < 3; i++)
components.Add("");
public static bool TryParseConsoleLocalId(ICommandConsole console, string rawLocalId, out uint localId)
{
if (!uint.TryParse(rawLocalId, out localId))
{
if (console != null)
console.OutputFormat("{0} is not a valid local id", localId);
List<string> semiDigestedComponents
= components.ConvertAll<string>(
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;
});
return false;
}
string semiDigestedConsoleVector = string.Join(VectorSeparator, semiDigestedComponents.ToArray());
if (localId == 0)
{
if (console != null)
console.OutputFormat("{0} is not a valid local id - it must be greater than 0", localId);
// m_log.DebugFormat("[CONSOLE UTIL]: Parsing {0} into OpenMetaverse.Vector3", semiDigestedConsoleVector);
return false;
}
return Vector3.TryParse(semiDigestedConsoleVector, out vector);
return true;
}
/// <summary>
/// Tries to parse the input as either a UUID or a local ID.
/// </summary>
/// <returns>true if parsing succeeded, false otherwise.</returns>
/// <param name='console'></param>
/// <param name='rawId'></param>
/// <param name='uuid'></param>
/// <param name='localId'>
/// Will be set to ConsoleUtil.LocalIdNotFound if parsing result was a UUID or no parse succeeded.
/// </param>
public static bool TryParseConsoleId(ICommandConsole console, string rawId, out UUID uuid, out uint localId)
{
if (TryParseConsoleUuid(null, rawId, out uuid))
{
localId = LocalIdNotFound;
return true;
}
if (TryParseConsoleLocalId(null, rawId, out localId))
{
return true;
}
if (console != null)
console.OutputFormat("{0} is not a valid UUID or local id", rawId);
return false;
}
/// <summary>
/// Convert a minimum vector input from the console to an OpenMetaverse.Vector3
/// </summary>
/// <param name='rawConsoleVector'>/param>
/// <param name='vector'></param>
/// <returns></returns>
public static bool TryParseConsoleMinVector(string rawConsoleVector, out Vector3 vector)
{
return TryParseConsoleVector(rawConsoleVector, c => float.MinValue.ToString(), out vector);
}
/// <summary>
/// Convert a maximum vector input from the console to an OpenMetaverse.Vector3
/// </summary>
/// <param name='rawConsoleVector'>/param>
/// <param name='vector'></param>
/// <returns></returns>
public static bool TryParseConsoleMaxVector(string rawConsoleVector, out Vector3 vector)
{
return TryParseConsoleVector(rawConsoleVector, c => float.MaxValue.ToString(), out vector);
}
/// <summary>
/// Convert a vector input from the console to an OpenMetaverse.Vector3
/// </summary>
/// <param name='rawConsoleVector'>
/// A string in the form <x>,<y>,<z> 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.
/// </param>
/// <param name='blankComponentFunc'></param>
/// <param name='vector'></param>
/// <returns></returns>
public static bool TryParseConsoleVector(
string rawConsoleVector, Func<string, string> blankComponentFunc, out Vector3 vector)
{
List<string> 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<string> semiDigestedComponents
= components.ConvertAll<string>(
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);
}
}
}

View File

@ -1112,8 +1112,20 @@ namespace OpenSim.Framework
void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs);
void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args);
void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, byte source,
byte audible);
/// <summary>
/// Send chat to the viewer.
/// </summary>
/// <param name='message'></param>
/// <param name='type'></param>
/// <param name='fromPos'></param>
/// <param name='fromName'></param>
/// <param name='fromAgentID'></param>
/// <param name='ownerID'></param>
/// <param name='source'></param>
/// <param name='audible'></param>
void SendChatMessage(
string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, UUID ownerID, byte source,
byte audible);
void SendInstantMessage(GridInstantMessage im);

View File

@ -621,7 +621,7 @@ namespace OpenSim
if (account == null)
{
m_log.ErrorFormat(
"[OPENSIM]: Unable to store account. If this simulator is connected to a grid, you must create the estate owner account first.");
"[OPENSIM]: Unable to store account. If this simulator is connected to a grid, you must create the estate owner account first at the grid level.");
}
else
{

View File

@ -846,8 +846,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(mov, ThrottleOutPacketType.Unknown);
}
public void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName,
UUID fromAgentID, byte source, byte audible)
public void SendChatMessage(
string message, byte type, Vector3 fromPos, string fromName,
UUID fromAgentID, UUID ownerID, byte source, byte audible)
{
ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator);
reply.ChatData.Audible = audible;
@ -856,7 +857,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
reply.ChatData.SourceType = source;
reply.ChatData.Position = fromPos;
reply.ChatData.FromName = Util.StringToBytes256(fromName);
reply.ChatData.OwnerID = fromAgentID;
reply.ChatData.OwnerID = ownerID;
reply.ChatData.SourceID = fromAgentID;
OutPacket(reply, ThrottleOutPacketType.Unknown);

View File

@ -197,6 +197,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
string fromName = c.From;
string fromNamePrefix = "";
UUID fromID = UUID.Zero;
UUID ownerID = UUID.Zero;
string message = c.Message;
IScene scene = c.Scene;
UUID destination = c.Destination;
@ -224,11 +225,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
fromNamePrefix = m_adminPrefix;
}
destination = UUID.Zero; // Avatars cant "SayTo"
ownerID = c.Sender.AgentId;
break;
case ChatSourceType.Object:
fromID = c.SenderUUID;
if (c.SenderObject != null && c.SenderObject is SceneObjectPart)
ownerID = ((SceneObjectPart)c.SenderObject).OwnerID;
break;
}
@ -262,8 +268,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
// objects on a parcel with access restrictions
if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)
{
if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix + fromName, c.Type, message, sourceType))
receiverIDs.Add(presence.UUID);
if (destination != UUID.Zero)
{
if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, true))
receiverIDs.Add(presence.UUID);
}
else
{
if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, false))
receiverIDs.Add(presence.UUID);
}
}
}
}
@ -324,7 +338,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
(((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
return;
client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID,
client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID,
(byte)sourceType, (byte)ChatAudibleLevel.Fully);
receiverIDs.Add(client.AgentId);
}
@ -341,15 +355,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
/// <param name="fromPos"></param>
/// <param name="regionPos">/param>
/// <param name="fromAgentID"></param>
/// <param name='ownerID'>
/// Owner of the message. For at least some messages from objects, this has to be correctly filled with the owner's UUID.
/// This is the case for script error messages in viewer 3 since LLViewer change EXT-7762
/// </param>
/// <param name="fromName"></param>
/// <param name="type"></param>
/// <param name="message"></param>
/// <param name="src"></param>
/// <returns>true if the message was sent to the receiver, false if it was not sent due to failing a
/// precondition</returns>
protected virtual bool TrySendChatMessage(ScenePresence presence, Vector3 fromPos, Vector3 regionPos,
UUID fromAgentID, string fromName, ChatTypeEnum type,
string message, ChatSourceType src)
protected virtual bool TrySendChatMessage(
ScenePresence presence, Vector3 fromPos, Vector3 regionPos,
UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type,
string message, ChatSourceType src, bool ignoreDistance)
{
// don't send chat to child agents
if (presence.IsChildAgent) return false;
@ -369,8 +388,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
}
// TODO: should change so the message is sent through the avatar rather than direct to the ClientView
presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName,
fromAgentID, (byte)src, (byte)ChatAudibleLevel.Fully);
presence.ControllingClient.SendChatMessage(
message, (byte) type, fromPos, fromName,
fromAgentID, ownerID, (byte)src, (byte)ChatAudibleLevel.Fully);
return true;
}

View File

@ -35,6 +35,7 @@ using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
using OpenSim.Framework.Console;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
@ -209,6 +210,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
Guid id, string firstName, string lastName, string invPath, string pass, string savePath,
Dictionary<string, object> options)
{
if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, savePath))
return false;
if (m_scenes.Count > 0)
{
UserAccount userInfo = GetUserInfo(firstName, lastName, pass);

View File

@ -38,15 +38,15 @@ using OpenSim.Services.Interfaces;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
{
public class InventoryTransferModule : IInventoryTransferModule, ISharedRegionModule
public class InventoryTransferModule : ISharedRegionModule
{
private static readonly ILog m_log
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
private List<Scene> m_Scenelist = new List<Scene>();
private Dictionary<UUID, Scene> m_AgentRegions =
new Dictionary<UUID, Scene>();
// private Dictionary<UUID, Scene> m_AgentRegions =
// new Dictionary<UUID, Scene>();
private IMessageTransferModule m_TransferModule = null;
private bool m_Enabled = true;
@ -76,12 +76,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
m_Scenelist.Add(scene);
scene.RegisterModuleInterface<IInventoryTransferModule>(this);
// scene.RegisterModuleInterface<IInventoryTransferModule>(this);
scene.EventManager.OnNewClient += OnNewClient;
scene.EventManager.OnClientClosed += ClientLoggedOut;
// scene.EventManager.OnClientClosed += ClientLoggedOut;
scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene;
// scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene;
}
public void RegionLoaded(Scene scene)
@ -96,9 +96,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
m_Scenelist.Clear();
scene.EventManager.OnNewClient -= OnNewClient;
scene.EventManager.OnClientClosed -= ClientLoggedOut;
// scene.EventManager.OnClientClosed -= ClientLoggedOut;
scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene;
// scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene;
}
}
}
@ -106,9 +106,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
public void RemoveRegion(Scene scene)
{
scene.EventManager.OnNewClient -= OnNewClient;
scene.EventManager.OnClientClosed -= ClientLoggedOut;
// scene.EventManager.OnClientClosed -= ClientLoggedOut;
scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene;
// scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene;
m_Scenelist.Remove(scene);
}
@ -138,10 +138,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
client.OnInstantMessage += OnInstantMessage;
}
protected void OnSetRootAgentScene(UUID id, Scene scene)
{
m_AgentRegions[id] = scene;
}
// protected void OnSetRootAgentScene(UUID id, Scene scene)
// {
// m_AgentRegions[id] = scene;
// }
private Scene FindClientScene(UUID agentId)
{
@ -465,69 +465,69 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
}
}
public bool NeedSceneCacheClear(UUID agentID, Scene scene)
{
if (!m_AgentRegions.ContainsKey(agentID))
{
// Since we can get here two ways, we need to scan
// the scenes here. This is somewhat more expensive
// but helps avoid a nasty bug
//
foreach (Scene s in m_Scenelist)
{
ScenePresence presence;
if (s.TryGetScenePresence(agentID, out presence))
{
// If the agent is in this scene, then we
// are being called twice in a single
// teleport. This is wasteful of cycles
// but harmless due to this 2nd level check
//
// If the agent is found in another scene
// then the list wasn't current
//
// If the agent is totally unknown, then what
// are we even doing here??
//
if (s == scene)
{
//m_log.Debug("[INVTRANSFERMOD]: s == scene. Returning true in " + scene.RegionInfo.RegionName);
return true;
}
else
{
//m_log.Debug("[INVTRANSFERMOD]: s != scene. Returning false in " + scene.RegionInfo.RegionName);
return false;
}
}
}
//m_log.Debug("[INVTRANSFERMOD]: agent not in scene. Returning true in " + scene.RegionInfo.RegionName);
return true;
}
// The agent is left in current Scene, so we must be
// going to another instance
//
if (m_AgentRegions[agentID] == scene)
{
//m_log.Debug("[INVTRANSFERMOD]: m_AgentRegions[agentID] == scene. Returning true in " + scene.RegionInfo.RegionName);
m_AgentRegions.Remove(agentID);
return true;
}
// Another region has claimed the agent
//
//m_log.Debug("[INVTRANSFERMOD]: last resort. Returning false in " + scene.RegionInfo.RegionName);
return false;
}
public void ClientLoggedOut(UUID agentID, Scene scene)
{
if (m_AgentRegions.ContainsKey(agentID))
m_AgentRegions.Remove(agentID);
}
// public bool NeedSceneCacheClear(UUID agentID, Scene scene)
// {
// if (!m_AgentRegions.ContainsKey(agentID))
// {
// // Since we can get here two ways, we need to scan
// // the scenes here. This is somewhat more expensive
// // but helps avoid a nasty bug
// //
//
// foreach (Scene s in m_Scenelist)
// {
// ScenePresence presence;
//
// if (s.TryGetScenePresence(agentID, out presence))
// {
// // If the agent is in this scene, then we
// // are being called twice in a single
// // teleport. This is wasteful of cycles
// // but harmless due to this 2nd level check
// //
// // If the agent is found in another scene
// // then the list wasn't current
// //
// // If the agent is totally unknown, then what
// // are we even doing here??
// //
// if (s == scene)
// {
// //m_log.Debug("[INVTRANSFERMOD]: s == scene. Returning true in " + scene.RegionInfo.RegionName);
// return true;
// }
// else
// {
// //m_log.Debug("[INVTRANSFERMOD]: s != scene. Returning false in " + scene.RegionInfo.RegionName);
// return false;
// }
// }
// }
// //m_log.Debug("[INVTRANSFERMOD]: agent not in scene. Returning true in " + scene.RegionInfo.RegionName);
// return true;
// }
//
// // The agent is left in current Scene, so we must be
// // going to another instance
// //
// if (m_AgentRegions[agentID] == scene)
// {
// //m_log.Debug("[INVTRANSFERMOD]: m_AgentRegions[agentID] == scene. Returning true in " + scene.RegionInfo.RegionName);
// m_AgentRegions.Remove(agentID);
// return true;
// }
//
// // Another region has claimed the agent
// //
// //m_log.Debug("[INVTRANSFERMOD]: last resort. Returning false in " + scene.RegionInfo.RegionName);
// return false;
// }
//
// public void ClientLoggedOut(UUID agentID, Scene scene)
// {
// if (m_AgentRegions.ContainsKey(agentID))
// m_AgentRegions.Remove(agentID);
// }
/// <summary>
///

View File

@ -677,13 +677,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Reset();
}
// REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
if (sp.Scene.NeedSceneCacheClear(sp.UUID))
{
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
sp.UUID);
}
// Commented pending deletion since this method no longer appears to do anything at all
// // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
// if (sp.Scene.NeedSceneCacheClear(sp.UUID))
// {
// m_log.DebugFormat(
// "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
// sp.UUID);
// }
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
}
@ -1222,11 +1223,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// the user may change their profile information in other region,
// so the userinfo in UserProfileCache is not reliable any more, delete it
// REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
if (agent.Scene.NeedSceneCacheClear(agent.UUID))
{
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
}
// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
// {
// m_log.DebugFormat(
// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
// }
//m_log.Debug("AFTER CROSS");
//Scene.DumpChildrenSeeds(UUID);

View File

@ -28,6 +28,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
@ -172,12 +173,42 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
/// <param name="hostID">UUID of the SceneObjectPart</param>
/// <param name="channel">channel to listen on</param>
/// <param name="name">name to filter on</param>
/// <param name="id">key to filter on (user given, could be totally faked)</param>
/// <param name="id">
/// key to filter on (user given, could be totally faked)
/// </param>
/// <param name="msg">msg to filter on</param>
/// <returns>number of the scripts handle</returns>
public int Listen(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg)
public int Listen(uint localID, UUID itemID, UUID hostID, int channel,
string name, UUID id, string msg)
{
return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg);
return m_listenerManager.AddListener(localID, itemID, hostID,
channel, name, id, msg);
}
/// <summary>
/// Create a listen event callback with the specified filters.
/// The parameters localID,itemID are needed to uniquely identify
/// the script during 'peek' time. Parameter hostID is needed to
/// determine the position of the script.
/// </summary>
/// <param name="localID">localID of the script engine</param>
/// <param name="itemID">UUID of the script engine</param>
/// <param name="hostID">UUID of the SceneObjectPart</param>
/// <param name="channel">channel to listen on</param>
/// <param name="name">name to filter on</param>
/// <param name="id">
/// key to filter on (user given, could be totally faked)
/// </param>
/// <param name="msg">msg to filter on</param>
/// <param name="regexBitfield">
/// Bitfield indicating which strings should be processed as regex.
/// </param>
/// <returns>number of the scripts handle</returns>
public int Listen(uint localID, UUID itemID, UUID hostID, int channel,
string name, UUID id, string msg, int regexBitfield)
{
return m_listenerManager.AddListener(localID, itemID, hostID,
channel, name, id, msg, regexBitfield);
}
/// <summary>
@ -326,7 +357,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
if (channel == 0)
{
// Channel 0 goes to viewer ONLY
m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, false, false, target);
m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, target, false, false);
return true;
}
@ -470,15 +501,25 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
m_curlisteners = 0;
}
public int AddListener(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg)
public int AddListener(uint localID, UUID itemID, UUID hostID,
int channel, string name, UUID id, string msg)
{
return AddListener(localID, itemID, hostID, channel, name, id,
msg, 0);
}
public int AddListener(uint localID, UUID itemID, UUID hostID,
int channel, string name, UUID id, string msg,
int regexBitfield)
{
// do we already have a match on this particular filter event?
List<ListenerInfo> coll = GetListeners(itemID, channel, name, id, msg);
List<ListenerInfo> coll = GetListeners(itemID, channel, name, id,
msg);
if (coll.Count > 0)
{
// special case, called with same filter settings, return same handle
// (2008-05-02, tested on 1.21.1 server, still holds)
// special case, called with same filter settings, return same
// handle (2008-05-02, tested on 1.21.1 server, still holds)
return coll[0].GetHandle();
}
@ -490,7 +531,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
if (newHandle > 0)
{
ListenerInfo li = new ListenerInfo(newHandle, localID, itemID, hostID, channel, name, id, msg);
ListenerInfo li = new ListenerInfo(newHandle, localID,
itemID, hostID, channel, name, id, msg,
regexBitfield);
List<ListenerInfo> listeners;
if (!m_listeners.TryGetValue(channel,out listeners))
@ -631,6 +674,22 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
return -1;
}
/// These are duplicated from ScriptBaseClass
/// http://opensimulator.org/mantis/view.php?id=6106#c21945
#region Constants for the bitfield parameter of osListenRegex
/// <summary>
/// process name parameter as regex
/// </summary>
public const int OS_LISTEN_REGEX_NAME = 0x1;
/// <summary>
/// process message parameter as regex
/// </summary>
public const int OS_LISTEN_REGEX_MESSAGE = 0x2;
#endregion
// Theres probably a more clever and efficient way to
// do this, maybe with regex.
// PM2008: Ha, one could even be smart and define a specialized Enumerator.
@ -656,7 +715,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
{
continue;
}
if (li.GetName().Length > 0 && !li.GetName().Equals(name))
if (li.GetName().Length > 0 && (
((li.RegexBitfield & OS_LISTEN_REGEX_NAME) != OS_LISTEN_REGEX_NAME && !li.GetName().Equals(name)) ||
((li.RegexBitfield & OS_LISTEN_REGEX_NAME) == OS_LISTEN_REGEX_NAME && !Regex.IsMatch(name, li.GetName()))
))
{
continue;
}
@ -664,7 +726,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
{
continue;
}
if (li.GetMessage().Length > 0 && !li.GetMessage().Equals(msg))
if (li.GetMessage().Length > 0 && (
((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) != OS_LISTEN_REGEX_MESSAGE && !li.GetMessage().Equals(msg)) ||
((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) == OS_LISTEN_REGEX_MESSAGE && !Regex.IsMatch(msg, li.GetMessage()))
))
{
continue;
}
@ -697,10 +762,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
{
int idx = 0;
Object[] item = new Object[6];
int dataItemLength = 6;
while (idx < data.Length)
{
Array.Copy(data, idx, item, 0, 6);
dataItemLength = (idx + 7 == data.Length || (idx + 7 < data.Length && data[idx + 7] is bool)) ? 7 : 6;
item = new Object[dataItemLength];
Array.Copy(data, idx, item, 0, dataItemLength);
ListenerInfo info =
ListenerInfo.FromData(localID, itemID, hostID, item);
@ -712,12 +780,12 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
m_listeners[(int)item[2]].Add(info);
}
idx+=6;
idx+=dataItemLength;
}
}
}
public class ListenerInfo: IWorldCommListenerInfo
public class ListenerInfo : IWorldCommListenerInfo
{
private bool m_active; // Listener is active or not
private int m_handle; // Assigned handle of this listener
@ -731,16 +799,29 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
public ListenerInfo(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message)
{
Initialise(handle, localID, ItemID, hostID, channel, name, id, message);
Initialise(handle, localID, ItemID, hostID, channel, name, id,
message, 0);
}
public ListenerInfo(int handle, uint localID, UUID ItemID,
UUID hostID, int channel, string name, UUID id,
string message, int regexBitfield)
{
Initialise(handle, localID, ItemID, hostID, channel, name, id,
message, regexBitfield);
}
public ListenerInfo(ListenerInfo li, string name, UUID id, string message)
{
Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message);
Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message, 0);
}
private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name,
UUID id, string message)
public ListenerInfo(ListenerInfo li, string name, UUID id, string message, int regexBitfield)
{
Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message, regexBitfield);
}
private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message, int regexBitfield)
{
m_active = true;
m_handle = handle;
@ -751,11 +832,12 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
m_name = name;
m_id = id;
m_message = message;
RegexBitfield = regexBitfield;
}
public Object[] GetSerializationData()
{
Object[] data = new Object[6];
Object[] data = new Object[7];
data[0] = m_active;
data[1] = m_handle;
@ -763,16 +845,19 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
data[3] = m_name;
data[4] = m_id;
data[5] = m_message;
data[6] = RegexBitfield;
return data;
}
public static ListenerInfo FromData(uint localID, UUID ItemID, UUID hostID, Object[] data)
{
ListenerInfo linfo = new ListenerInfo((int)data[1], localID,
ItemID, hostID, (int)data[2], (string)data[3],
(UUID)data[4], (string)data[5]);
linfo.m_active=(bool)data[0];
ListenerInfo linfo = new ListenerInfo((int)data[1], localID, ItemID, hostID, (int)data[2], (string)data[3], (UUID)data[4], (string)data[5]);
linfo.m_active = (bool)data[0];
if (data.Length >= 7)
{
linfo.RegexBitfield = (int)data[6];
}
return linfo;
}
@ -831,5 +916,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
{
return m_id;
}
public int RegexBitfield { get; private set; }
}
}

View File

@ -110,7 +110,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
lastX = (lastX == null) ? curLastX : (lastX > curLastX) ? lastX : curLastX;
}
Rect = new Rectangle((int)firstX, (int)firstY, (int)(lastY - firstY + 1), (int)(lastX - firstX + 1));
Rect = new Rectangle((int)firstX, (int)firstY, (int)(lastX - firstX + 1), (int)(lastY - firstY + 1));
// Calculate the subdirectory in which each region will be stored in the archive

View File

@ -32,6 +32,8 @@ using System.Reflection;
using log4net;
using NDesk.Options;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
@ -117,7 +119,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
//
// foreach (string param in mainParams)
// m_log.DebugFormat("GOT PARAM [{0}]", param);
if (mainParams.Count > 2)
{
DearchiveRegion(mainParams[2], mergeOar, skipAssets, Guid.Empty);
@ -150,14 +152,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver
List<string> mainParams = ops.Parse(cmdparams);
string path;
if (mainParams.Count > 2)
{
ArchiveRegion(mainParams[2], options);
}
path = mainParams[2];
else
{
ArchiveRegion(DEFAULT_OAR_BACKUP_FILENAME, options);
}
path = DEFAULT_OAR_BACKUP_FILENAME;
if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, path))
return;
ArchiveRegion(path, options);
}
public void ArchiveRegion(string savePath, Dictionary<string, object> options)

View File

@ -27,10 +27,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using log4net;
using Mono.Addins;
using NDesk.Options;
@ -41,6 +43,7 @@ using OpenSim.Framework.Console;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
namespace OpenSim.Region.CoreModules.World.Objects.Commands
{
@ -96,9 +99,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
HandleDeleteObject);
m_console.Commands.AddCommand(
"Objects", false, "delete object uuid",
"delete object uuid <UUID>",
"Delete a scene object by uuid",
"Objects", false, "delete object id",
"delete object id <UUID-or-localID>",
"Delete a scene object by uuid or localID",
HandleDeleteObject);
m_console.Commands.AddCommand(
@ -122,28 +125,18 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
"delete object pos",
"delete object pos <start-coord> to <end-coord>",
"Delete 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"
+ "delete object pos 20,20,20 to 40,40,40\n"
+ "delete object pos 20,20 to 40,40\n"
+ "delete object pos ,20,20 to ,40,40\n"
+ "delete object pos ,,30 to ,,~\n"
+ "delete object pos ,,-~ to ,,30",
ConsoleUtil.CoordHelp,
HandleDeleteObject);
m_console.Commands.AddCommand(
"Objects",
false,
"show object uuid",
"show object uuid [--full] <UUID>",
"Show details of a scene object with the given UUID",
"show object id",
"show object id [--full] <UUID-or-localID>",
"Show details of a scene object with the given UUID or localID",
"The --full option will print out information on all the parts of the object.\n"
+ "For yet more detailed part information, use the \"show part\" commands.",
HandleShowObjectByUuid);
HandleShowObjectById);
m_console.Commands.AddCommand(
"Objects",
@ -164,25 +157,15 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
"Show details of scene objects within the given area.",
"The --full option will print out information on all the parts of the object.\n"
+ "For yet more detailed part information, use the \"show part\" commands.\n"
+ "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",
+ ConsoleUtil.CoordHelp,
HandleShowObjectByPos);
m_console.Commands.AddCommand(
"Objects",
false,
"show part uuid",
"show part uuid <UUID>",
"Show details of a scene object parts with the given UUID", HandleShowPartByUuid);
"show part id",
"show part id <UUID-or-localID>",
"Show details of a scene object part with the given UUID or localID", HandleShowPartById);
m_console.Commands.AddCommand(
"Objects",
@ -190,7 +173,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
"show part name",
"show part name [--regex] <name>",
"Show details of scene object parts with the given name.",
"If --regex is specified then the name is treatead as a regular expression",
"If --regex is specified then the name is treated as a regular expression",
HandleShowPartByName);
m_console.Commands.AddCommand(
@ -199,18 +182,19 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
"show part pos",
"show part pos <start-coord> to <end-coord>",
"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",
ConsoleUtil.CoordHelp,
HandleShowPartByPos);
m_console.Commands.AddCommand(
"Objects",
false,
"dump object id",
"dump object id <UUID-or-localID>",
"Dump the formatted serialization of the given object to the file <UUID>.xml",
"e.g. dump object uuid c1ed6809-cc24-4061-a4c2-93082a2d1f1d will dump serialization to c1ed6809-cc24-4061-a4c2-93082a2d1f1d.xml\n"
+ "To locate the UUID or localID in the first place, you need to use the other show object commands.\n"
+ "If a local ID is given then the filename used is still that for the UUID",
HandleDumpObjectById);
}
public void RemoveRegion(Scene scene)
@ -265,7 +249,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
m_console.OutputFormat(sb.ToString());
}
private void HandleShowObjectByUuid(string module, string[] cmdparams)
private void HandleShowObjectById(string module, string[] cmdparams)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
return;
@ -281,14 +265,17 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
return;
}
UUID objectUuid;
if (!UUID.TryParse(mainParams[3], out objectUuid))
{
m_console.OutputFormat("{0} is not a valid uuid", mainParams[3]);
UUID uuid;
uint localId;
if (!ConsoleUtil.TryParseConsoleId(m_console, mainParams[3], out uuid, out localId))
return;
}
SceneObjectGroup so = m_scene.GetSceneObjectGroup(objectUuid);
SceneObjectGroup so;
if (localId != ConsoleUtil.LocalIdNotFound)
so = m_scene.GetSceneObjectGroup(localId);
else
so = m_scene.GetSceneObjectGroup(uuid);
if (so == null)
{
@ -365,7 +352,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
OutputSogsToConsole(searchPredicate, showFull);
}
private void HandleShowPartByUuid(string module, string[] cmdparams)
private void HandleShowPartById(string module, string[] cmdparams)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
return;
@ -378,18 +365,20 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
if (mainParams.Count < 4)
{
m_console.OutputFormat("Usage: show part uuid [--full] <uuid>");
m_console.OutputFormat("Usage: show part id [--full] <UUID-or-localID>");
return;
}
UUID objectUuid;
if (!UUID.TryParse(mainParams[3], out objectUuid))
{
m_console.OutputFormat("{0} is not a valid uuid", mainParams[3]);
uint localId;
if (!ConsoleUtil.TryParseConsoleId(m_console, mainParams[3], out objectUuid, out localId))
return;
}
SceneObjectPart sop = m_scene.GetSceneObjectPart(objectUuid);
SceneObjectPart sop;
if (localId == ConsoleUtil.LocalIdNotFound)
sop = m_scene.GetSceneObjectPart(objectUuid);
else
sop = m_scene.GetSceneObjectPart(localId);
if (sop == null)
{
@ -477,6 +466,51 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
OutputSopsToConsole(searchPredicate, true);
}
private void HandleDumpObjectById(string module, string[] cmdparams)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
return;
if (cmdparams.Length < 4)
{
m_console.OutputFormat("Usage: dump object id <UUID-or-localID>");
return;
}
UUID objectUuid;
uint localId;
if (!ConsoleUtil.TryParseConsoleId(m_console, cmdparams[3], out objectUuid, out localId))
return;
SceneObjectGroup so;
if (localId == ConsoleUtil.LocalIdNotFound)
so = m_scene.GetSceneObjectGroup(objectUuid);
else
so = m_scene.GetSceneObjectGroup(localId);
if (so == null)
{
// m_console.OutputFormat("No part found with uuid {0}", objectUuid);
return;
}
// In case we found it via local ID.
objectUuid = so.UUID;
string fileName = string.Format("{0}.xml", objectUuid);
if (!ConsoleUtil.CheckFileDoesNotExist(m_console, fileName))
return;
using (XmlTextWriter xtw = new XmlTextWriter(fileName, Encoding.UTF8))
{
xtw.Formatting = Formatting.Indented;
SceneObjectSerializer.ToOriginalXmlFormat(so, xtw, true);
}
m_console.OutputFormat("Object dumped to file {0}", fileName);
}
/// <summary>
/// Append a scene object report to an input StringBuilder
/// </summary>
@ -641,19 +675,24 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
break;
case "uuid":
if (!UUID.TryParse(o, out match))
case "id":
UUID uuid;
uint localId;
if (!ConsoleUtil.TryParseConsoleId(m_console, o, out uuid, out localId))
return;
requireConfirmation = false;
deletes = new List<SceneObjectGroup>();
m_scene.ForEachSOG(delegate (SceneObjectGroup g)
{
if (g.UUID == match && !g.IsAttachment)
deletes.Add(g);
});
SceneObjectGroup so;
if (localId == ConsoleUtil.LocalIdNotFound)
so = m_scene.GetSceneObjectGroup(uuid);
else
so = m_scene.GetSceneObjectGroup(localId);
if (!so.IsAttachment)
deletes.Add(so);
// if (deletes.Count == 0)
// m_console.OutputFormat("No objects were found with uuid {0}", match);

View File

@ -45,6 +45,13 @@ namespace OpenSim.Region.Framework.Interfaces
void Deactivate();
void Activate();
UUID GetID();
/// <summary>
/// Bitfield indicating which strings should be processed as regex.
/// 1 corresponds to IWorldCommListenerInfo::GetName()
/// 2 corresponds to IWorldCommListenerInfo::GetMessage()
/// </summary>
int RegexBitfield { get; }
}
public interface IWorldComm
@ -60,7 +67,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// the script during 'peek' time. Parameter hostID is needed to
/// determine the position of the script.
/// </summary>
/// <param name="localID">localID of the script engine</param>
/// <param name="LocalID">localID of the script engine</param>
/// <param name="itemID">UUID of the script engine</param>
/// <param name="hostID">UUID of the SceneObjectPart</param>
/// <param name="channel">channel to listen on</param>
@ -70,6 +77,23 @@ namespace OpenSim.Region.Framework.Interfaces
/// <returns>number of the scripts handle</returns>
int Listen(uint LocalID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg);
/// <summary>
/// Create a listen event callback with the specified filters.
/// The parameters localID,itemID are needed to uniquely identify
/// the script during 'peek' time. Parameter hostID is needed to
/// determine the position of the script.
/// </summary>
/// <param name="LocalID">localID of the script engine</param>
/// <param name="itemID">UUID of the script engine</param>
/// <param name="hostID">UUID of the SceneObjectPart</param>
/// <param name="channel">channel to listen on</param>
/// <param name="name">name to filter on</param>
/// <param name="id">key to filter on (user given, could be totally faked)</param>
/// <param name="msg">msg to filter on</param>
/// <param name="regexBitfield">Bitfield indicating which strings should be processed as regex.</param>
/// <returns>number of the scripts handle</returns>
int Listen(uint LocalID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg, int regexBitfield);
/// <summary>
/// This method scans over the objects which registered an interest in listen callbacks.
/// For everyone it finds, it checks if it fits the given filter. If it does, then

View File

@ -87,7 +87,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
{
if (m_defaultAnimation.AnimID == animID)
{
m_defaultAnimation = new OpenSim.Framework.Animation(UUID.Zero, 1, UUID.Zero);
m_defaultAnimation = new OpenSim.Framework.Animation(animID, 1, UUID.Zero);
}
else if (HasAnimation(animID))
{

View File

@ -38,8 +38,20 @@ namespace OpenSim.Region.Framework.Scenes
{
public partial class Scene
{
/// <summary>
/// Send chat to listeners.
/// </summary>
/// <param name='message'></param>
/// <param name='type'>/param>
/// <param name='channel'></param>
/// <param name='fromPos'></param>
/// <param name='fromName'></param>
/// <param name='fromID'></param>
/// <param name='targetID'></param>
/// <param name='fromAgent'></param>
/// <param name='broadcast'></param>
public void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
UUID fromID, bool fromAgent, bool broadcast, UUID destination)
UUID fromID, UUID targetID, bool fromAgent, bool broadcast)
{
OSChatMessage args = new OSChatMessage();
@ -49,7 +61,7 @@ namespace OpenSim.Region.Framework.Scenes
args.Position = fromPos;
args.SenderUUID = fromID;
args.Scene = this;
args.Destination = destination;
args.Destination = targetID;
if (fromAgent)
{
@ -66,6 +78,10 @@ namespace OpenSim.Region.Framework.Scenes
args.From = fromName;
//args.
// m_log.DebugFormat(
// "[SCENE]: Sending message {0} on channel {1}, type {2} from {3}, broadcast {4}",
// args.Message.Replace("\n", "\\n"), args.Channel, args.Type, fromName, broadcast);
if (broadcast)
EventManager.TriggerOnChatBroadcast(this, args);
else
@ -75,7 +91,7 @@ namespace OpenSim.Region.Framework.Scenes
protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
UUID fromID, bool fromAgent, bool broadcast)
{
SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, broadcast, UUID.Zero);
SimChat(message, type, channel, fromPos, fromName, fromID, UUID.Zero, fromAgent, broadcast);
}
/// <summary>

View File

@ -1300,6 +1300,12 @@ namespace OpenSim.Region.Framework.Scenes
// This is the method that shuts down the scene.
public override void Close()
{
if (m_shuttingDown)
{
m_log.WarnFormat("[SCENE]: Ignoring close request because already closing {0}", Name);
return;
}
m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
StatsReporter.Close();
@ -1343,6 +1349,14 @@ namespace OpenSim.Region.Framework.Scenes
m_sceneGraph.Close();
if (!GridService.DeregisterRegion(RegionInfo.RegionID))
m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
base.Close();
// XEngine currently listens to the EventManager.OnShutdown event to trigger script stop and persistence.
// Therefore. we must dispose of the PhysicsScene after this to prevent a window where script code can
// attempt to reference a null or disposed physics scene.
if (PhysicsScene != null)
{
PhysicsScene phys = PhysicsScene;
@ -1351,12 +1365,6 @@ namespace OpenSim.Region.Framework.Scenes
phys.Dispose();
phys = null;
}
if (!GridService.DeregisterRegion(RegionInfo.RegionID))
m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
// call the base class Close method.
base.Close();
}
/// <summary>
@ -3595,9 +3603,10 @@ namespace OpenSim.Region.Framework.Scenes
if (closeChildAgents && CapsModule != null)
CapsModule.RemoveCaps(agentID);
// REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
// this method is doing is HORRIBLE!!!
avatar.Scene.NeedSceneCacheClear(avatar.UUID);
// // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
// // this method is doing is HORRIBLE!!!
// Commented pending deletion since this method no longer appears to do anything at all
// avatar.Scene.NeedSceneCacheClear(avatar.UUID);
if (closeChildAgents && !isChildAgent)
{
@ -4899,12 +4908,23 @@ namespace OpenSim.Region.Framework.Scenes
/// Get a group via its UUID
/// </summary>
/// <param name="fullID"></param>
/// <returns>null if no group with that name exists</returns>
/// <returns>null if no group with that id exists</returns>
public SceneObjectGroup GetSceneObjectGroup(UUID fullID)
{
return m_sceneGraph.GetSceneObjectGroup(fullID);
}
/// <summary>
/// Get a group via its local ID
/// </summary>
/// <remarks>This will only return a group if the local ID matches a root part</remarks>
/// <param name="localID"></param>
/// <returns>null if no group with that id exists</returns>
public SceneObjectGroup GetSceneObjectGroup(uint localID)
{
return m_sceneGraph.GetSceneObjectGroup(localID);
}
/// <summary>
/// Get a group by name from the scene (will return the first
/// found, if there are more than one prim with the same name)
@ -5065,14 +5085,15 @@ namespace OpenSim.Region.Framework.Scenes
client.SendRegionHandle(regionID, handle);
}
public bool NeedSceneCacheClear(UUID agentID)
{
IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>();
if (inv == null)
return true;
return inv.NeedSceneCacheClear(agentID, this);
}
// Commented pending deletion since this method no longer appears to do anything at all
// public bool NeedSceneCacheClear(UUID agentID)
// {
// IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>();
// if (inv == null)
// return true;
//
// return inv.NeedSceneCacheClear(agentID, this);
// }
public void CleanTempObjects()
{

View File

@ -1062,6 +1062,30 @@ namespace OpenSim.Region.Framework.Scenes
return null;
}
/// <summary>
/// Get a group in the scene
/// </summary>
/// <remarks>
/// This will only return a group if the local ID matches the root part, not other parts.
/// </remarks>
/// <param name="localID">Local id of the root part of the group</param>
/// <returns>null if no such group was found</returns>
protected internal SceneObjectGroup GetSceneObjectGroup(uint localID)
{
lock (SceneObjectGroupsByLocalPartID)
{
if (SceneObjectGroupsByLocalPartID.ContainsKey(localID))
{
SceneObjectGroup so = SceneObjectGroupsByLocalPartID[localID];
if (so.LocalId == localID)
return so;
}
}
return null;
}
/// <summary>
/// Get a group by name from the scene (will return the first
/// found, if there are more than one prim with the same name)

View File

@ -69,7 +69,7 @@ namespace OpenSim.Region.Framework.Scenes
public ScriptControlled eventControls;
}
public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs);
public delegate void SendCoarseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs);
public class ScenePresence : EntityBase, IScenePresence
{
@ -188,7 +188,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public bool SitGround { get; private set; }
private SendCourseLocationsMethod m_sendCourseLocationsMethod;
private SendCoarseLocationsMethod m_sendCoarseLocationsMethod;
//private Vector3 m_requestedSitOffset = new Vector3();
@ -711,7 +711,7 @@ namespace OpenSim.Region.Framework.Scenes
AttachmentsSyncLock = new Object();
AllowMovement = true;
IsChildAgent = true;
m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
Animator = new ScenePresenceAnimator(this);
PresenceType = type;
DrawDistance = world.DefaultDrawDistance;
@ -2629,17 +2629,17 @@ namespace OpenSim.Region.Framework.Scenes
public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
{
SendCourseLocationsMethod d = m_sendCourseLocationsMethod;
SendCoarseLocationsMethod d = m_sendCoarseLocationsMethod;
if (d != null)
{
d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs);
}
}
public void SetSendCourseLocationMethod(SendCourseLocationsMethod d)
public void SetSendCoarseLocationMethod(SendCoarseLocationsMethod d)
{
if (d != null)
m_sendCourseLocationsMethod = d;
m_sendCoarseLocationsMethod = d;
}
public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
@ -2843,7 +2843,7 @@ namespace OpenSim.Region.Framework.Scenes
#region Significant Movement Method
/// <summary>
/// This checks for a significant movement and sends a courselocationchange update
/// This checks for a significant movement and sends a coarselocationchange update
/// </summary>
protected void CheckForSignificantMovement()
{

View File

@ -65,5 +65,22 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(scene.Frame, Is.EqualTo(1));
}
[Test]
public void TestShutdownScene()
{
TestHelpers.InMethod();
Scene scene = new SceneHelpers().SetupScene();
scene.Close();
Assert.That(scene.ShuttingDown, Is.True);
Assert.That(scene.Active, Is.False);
// Trying to update a shutdown scene should result in no update
scene.Update(1);
Assert.That(scene.Frame, Is.EqualTo(0));
}
}
}

View File

@ -958,7 +958,8 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
}
public void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, byte source, byte audible)
public void SendChatMessage(
string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, UUID ownerID, byte source, byte audible)
{
if (audible > 0 && message.Length > 0)
IRC_SendChannelPrivmsg(fromName, message);

View File

@ -127,6 +127,9 @@ namespace OpenSim.Region.OptionalModules.Asset
}
string fileName = rawAssetId;
if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, fileName))
return;
using (FileStream fs = new FileStream(fileName, FileMode.CreateNew))
{

View File

@ -546,8 +546,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
c.SenderUUID = UUID.Zero;
c.Scene = agent.Scene;
agent.ControllingClient.SendChatMessage(msg, (byte) ChatTypeEnum.Say, PosOfGod, m_whoami, UUID.Zero,
(byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully);
agent.ControllingClient.SendChatMessage(
msg, (byte) ChatTypeEnum.Say, PosOfGod, m_whoami, UUID.Zero, UUID.Zero,
(byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully);
}
private static void checkStringParameters(XmlRpcRequest request, string[] param)

View File

@ -607,13 +607,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{
}
public virtual void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName,
UUID fromAgentID, byte source, byte audible)
public virtual void SendChatMessage(
string message, byte type, Vector3 fromPos, string fromName,
UUID fromAgentID, UUID ownerID, byte source, byte audible)
{
}
public virtual void SendChatMessage(byte[] message, byte type, Vector3 fromPos, string fromName,
UUID fromAgentID, byte source, byte audible)
public virtual void SendChatMessage(
byte[] message, byte type, Vector3 fromPos, string fromName,
UUID fromAgentID, UUID ownerID, byte source, byte audible)
{
}

View File

@ -105,7 +105,7 @@ public class BSCharacter : BSPhysObject
shapeData.Position = _position;
shapeData.Rotation = _orientation;
shapeData.Velocity = _velocity;
shapeData.Size = Scale;
shapeData.Size = Scale; // capsule is a native shape but scale is not just <1,1,1>
shapeData.Scale = Scale;
shapeData.Mass = _mass;
shapeData.Buoyancy = _buoyancy;
@ -144,7 +144,9 @@ public class BSCharacter : BSPhysObject
ForcePosition = _position;
// Set the velocity and compute the proper friction
ForceVelocity = _velocity;
BulletSimAPI.SetRestitution2(BSBody.ptr, PhysicsScene.Params.avatarRestitution);
BulletSimAPI.SetMargin2(BSShape.ptr, PhysicsScene.Params.collisionMargin);
BulletSimAPI.SetLocalScaling2(BSShape.ptr, Scale);
BulletSimAPI.SetContactProcessingThreshold2(BSBody.ptr, PhysicsScene.Params.contactProcessingThreshold);
if (PhysicsScene.Params.ccdMotionThreshold > 0f)
@ -156,11 +158,15 @@ public class BSCharacter : BSPhysObject
OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, MassRaw);
BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia);
// Make so capsule does not fall over
BulletSimAPI.SetAngularFactorV2(BSBody.ptr, OMV.Vector3.Zero);
BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.CF_CHARACTER_OBJECT);
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, BSBody.ptr);
BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ACTIVE_TAG);
// BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ACTIVE_TAG);
BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.DISABLE_DEACTIVATION);
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, BSBody.ptr);
// Do this after the object has been added to the world
@ -175,11 +181,13 @@ public class BSCharacter : BSPhysObject
}
// No one calls this method so I don't know what it could possibly mean
public override bool Stopped { get { return false; } }
public override OMV.Vector3 Size {
get
{
// Avatar capsule size is kept in the scale parameter.
return _size;
// return _size;
return new OMV.Vector3(Scale.X * 2f, Scale.Y * 2f, Scale.Z);
}
set {
@ -199,7 +207,9 @@ public class BSCharacter : BSPhysObject
}
}
public override OMV.Vector3 Scale { get; set; }
public override PrimitiveBaseShape Shape
{
set { BaseShape = value; }
@ -264,7 +274,7 @@ public class BSCharacter : BSPhysObject
// Check that the current position is sane and, if not, modify the position to make it so.
// Check for being below terrain and being out of bounds.
// Check for being below terrain or on water.
// Returns 'true' of the position was made sane by some action.
private bool PositionSanityCheck()
{
@ -335,7 +345,7 @@ public class BSCharacter : BSPhysObject
}
// Avatars don't do vehicles
public override int VehicleType { get { return 0; } set { return; } }
public override int VehicleType { get { return (int)Vehicle.TYPE_NONE; } set { return; } }
public override void VehicleFloatParam(int param, float value) { }
public override void VehicleVectorParam(int param, OMV.Vector3 value) {}
public override void VehicleRotationParam(int param, OMV.Quaternion rotation) { }
@ -588,9 +598,8 @@ public class BSCharacter : BSPhysObject
newScale.X = PhysicsScene.Params.avatarCapsuleRadius;
newScale.Y = PhysicsScene.Params.avatarCapsuleRadius;
// From the total height, remote the capsule half spheres that are at each end
newScale.Z = (size.Z * 2f) - Math.Min(newScale.X, newScale.Y);
// newScale.Z = (size.Z * 2f);
// From the total height, remove the capsule half spheres that are at each end
newScale.Z = size.Z- (newScale.X + newScale.Y);
Scale = newScale;
}
@ -636,7 +645,7 @@ public class BSCharacter : BSPhysObject
BulletSimAPI.SetLinearVelocity2(BSBody.ptr, avVel);
}
// Tell the linkset about this
// Tell the linkset about value changes
Linkset.UpdateProperties(this);
// Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.

View File

@ -692,7 +692,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
{
if (_taintedObjects.Count > 0) // save allocating new list if there is nothing to process
{
// swizzle a new list into the list location so we can process what's there
int taintCount = m_taintsToProcessPerStep;
TaintCallbackEntry oneCallback = new TaintCallbackEntry();
while (_taintedObjects.Count > 0 && taintCount-- > 0)
@ -711,7 +710,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
{
try
{
DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", DetailLogZero, oneCallback.ident); // DEBUG DEBUG DEBUG
DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", DetailLogZero, oneCallback.ident);
oneCallback.callback();
}
catch (Exception e)

View File

@ -338,6 +338,7 @@ public class BSShapeCollection : IDisposable
ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_AVATAR,
ShapeData.FixedShapeKey.KEY_CAPSULE, shapeCallback);
DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.BSShape);
ret = true;
haveShape = true;
}
// If the prim attributes are simple, this could be a simple Bullet native shape
@ -411,15 +412,14 @@ public class BSShapeCollection : IDisposable
ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey,
ShapeDestructionCallback shapeCallback)
{
// release any previous shape
DereferenceShape(prim.BSShape, true, shapeCallback);
shapeData.Type = shapeType;
// Bullet native objects are scaled by the Bullet engine so pass the size in
prim.Scale = shapeData.Size;
shapeData.Scale = shapeData.Size;
// release any previous shape
DereferenceShape(prim.BSShape, true, shapeCallback);
BulletShape newShape = BuildPhysicalNativeShape(shapeType, shapeData, shapeKey);
// Don't need to do a 'ReferenceShape()' here because native shapes are not shared.
@ -443,7 +443,8 @@ public class BSShapeCollection : IDisposable
if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
{
newShape = new BulletShape(
BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1.0f, 1.0f, nativeShapeData.Scale), shapeType);
BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, nativeShapeData.Scale)
, shapeType);
DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", nativeShapeData.ID, nativeShapeData.Scale);
}
else
@ -790,7 +791,6 @@ public class BSShapeCollection : IDisposable
// If the collisionObject is not the correct type for solidness, rebuild what's there
mustRebuild = true;
}
}
if (mustRebuild || forceRebuild)

View File

@ -333,8 +333,8 @@ public class BSTerrainManager
// Make sure the new shape is processed.
// BulletSimAPI.Activate2(mapInfo.terrainBody.ptr, true);
BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.ISLAND_SLEEPING);
// BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
// BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.ISLAND_SLEEPING);
BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
m_terrainModified = true;
};

View File

@ -719,21 +719,21 @@ namespace OpenSim.Region.RegionCombinerModule
rootConn.ClientEventForwarder = new RegionCombinerClientEventForwarder(rootConn);
// Sets up the CoarseLocationUpdate forwarder for this root region
scene.EventManager.OnNewPresence += SetCourseLocationDelegate;
scene.EventManager.OnNewPresence += SetCoarseLocationDelegate;
// Adds this root region to a dictionary of regions that are connectable
m_regions.Add(scene.RegionInfo.originRegionID, rootConn);
}
}
private void SetCourseLocationDelegate(ScenePresence presence)
private void SetCoarseLocationDelegate(ScenePresence presence)
{
presence.SetSendCourseLocationMethod(SendCourseLocationUpdates);
presence.SetSendCoarseLocationMethod(SendCoarseLocationUpdates);
}
// This delegate was refactored for non-combined regions.
// This combined region version will not use the pre-compiled lists of locations and ids
private void SendCourseLocationUpdates(UUID sceneId, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
private void SendCoarseLocationUpdates(UUID sceneId, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
{
RegionConnections connectiondata = null;
lock (m_regions)
@ -756,18 +756,18 @@ namespace OpenSim.Region.RegionCombinerModule
}
});
DistributeCourseLocationUpdates(CoarseLocations, AvatarUUIDs, connectiondata, presence);
DistributeCoarseLocationUpdates(CoarseLocations, AvatarUUIDs, connectiondata, presence);
}
private void DistributeCourseLocationUpdates(List<Vector3> locations, List<UUID> uuids,
private void DistributeCoarseLocationUpdates(List<Vector3> locations, List<UUID> uuids,
RegionConnections connectiondata, ScenePresence rootPresence)
{
RegionData[] rdata = connectiondata.ConnectedRegions.ToArray();
//List<IClientAPI> clients = new List<IClientAPI>();
Dictionary<Vector2, RegionCourseLocationStruct> updates = new Dictionary<Vector2, RegionCourseLocationStruct>();
Dictionary<Vector2, RegionCoarseLocationStruct> updates = new Dictionary<Vector2, RegionCoarseLocationStruct>();
// Root Region entry
RegionCourseLocationStruct rootupdatedata = new RegionCourseLocationStruct();
RegionCoarseLocationStruct rootupdatedata = new RegionCoarseLocationStruct();
rootupdatedata.Locations = new List<Vector3>();
rootupdatedata.Uuids = new List<UUID>();
rootupdatedata.Offset = Vector2.Zero;
@ -781,7 +781,7 @@ namespace OpenSim.Region.RegionCombinerModule
foreach (RegionData regiondata in rdata)
{
Vector2 offset = new Vector2(regiondata.Offset.X, regiondata.Offset.Y);
RegionCourseLocationStruct updatedata = new RegionCourseLocationStruct();
RegionCoarseLocationStruct updatedata = new RegionCoarseLocationStruct();
updatedata.Locations = new List<Vector3>();
updatedata.Uuids = new List<UUID>();
updatedata.Offset = offset;
@ -807,7 +807,7 @@ namespace OpenSim.Region.RegionCombinerModule
if (!updates.ContainsKey(offset))
{
// This shouldn't happen
RegionCourseLocationStruct updatedata = new RegionCourseLocationStruct();
RegionCoarseLocationStruct updatedata = new RegionCoarseLocationStruct();
updatedata.Locations = new List<Vector3>();
updatedata.Uuids = new List<UUID>();
updatedata.Offset = offset;

View File

@ -33,7 +33,7 @@ using OpenSim.Framework;
namespace OpenSim.Region.RegionCombinerModule
{
struct RegionCourseLocationStruct
struct RegionCoarseLocationStruct
{
public List<Vector3> Locations;
public List<UUID> Uuids;

View File

@ -11578,12 +11578,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
internal void Deprecated(string command)
{
throw new Exception("Command deprecated: " + command);
throw new ScriptException("Command deprecated: " + command);
}
internal void LSLError(string msg)
{
throw new Exception("LSL Runtime Error: " + msg);
throw new ScriptException("LSL Runtime Error: " + msg);
}
public delegate void AssetRequestCallback(UUID assetID, AssetBase asset);

View File

@ -95,13 +95,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
internal void MODError(string msg)
{
throw new Exception("MOD Runtime Error: " + msg);
throw new ScriptException("MOD Runtime Error: " + msg);
}
//
//Dumps an error message on the debug console.
//
/// <summary>
/// Dumps an error message on the debug console.
/// </summary>
/// <param name='message'></param>
internal void MODShoutError(string message)
{
if (message.Length > 1023)
@ -359,20 +359,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
result[i] = (string)(LSL_String)plist[i];
else if (plist[i] is LSL_Integer)
result[i] = (int)(LSL_Integer)plist[i];
// The int check exists because of the many plain old int script constants in ScriptBase which
// are not LSL_Integers.
else if (plist[i] is int)
result[i] = plist[i];
else if (plist[i] is LSL_Float)
result[i] = (float)(LSL_Float)plist[i];
else if (plist[i] is LSL_Key)
result[i] = new UUID((LSL_Key)plist[i]);
else if (plist[i] is LSL_Rotation)
{
result[i] = (OpenMetaverse.Quaternion)(
(LSL_Rotation)plist[i]);
}
result[i] = (Quaternion)((LSL_Rotation)plist[i]);
else if (plist[i] is LSL_Vector)
{
result[i] = (OpenMetaverse.Vector3)(
(LSL_Vector)plist[i]);
}
result[i] = (Vector3)((LSL_Vector)plist[i]);
else
MODError(String.Format("{0}: unknown LSL list element type", fname));
}

View File

@ -218,7 +218,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
else
{
throw new Exception("OSSL Runtime Error: " + msg);
throw new ScriptException("OSSL Runtime Error: " + msg);
}
}
@ -1789,18 +1789,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
protected string LoadNotecard(string notecardNameOrUuid)
{
UUID assetID = CacheNotecard(notecardNameOrUuid);
StringBuilder notecardData = new StringBuilder();
for (int count = 0; count < NotecardCache.GetLines(assetID); count++)
if (assetID != UUID.Zero)
{
string line = NotecardCache.GetLine(assetID, count) + "\n";
// m_log.DebugFormat("[OSSL]: From notecard {0} loading line {1}", notecardNameOrUuid, line);
notecardData.Append(line);
StringBuilder notecardData = new StringBuilder();
for (int count = 0; count < NotecardCache.GetLines(assetID); count++)
{
string line = NotecardCache.GetLine(assetID, count) + "\n";
// m_log.DebugFormat("[OSSL]: From notecard {0} loading line {1}", notecardNameOrUuid, line);
notecardData.Append(line);
}
return notecardData.ToString();
}
return notecardData.ToString();
return null;
}
/// <summary>
@ -2373,11 +2379,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return UUID.Zero.ToString();
}
}
else
{
OSSLError(string.Format("osNpcCreate: Notecard reference '{0}' not found.", notecard));
}
}
if (appearance == null)
return new LSL_Key(UUID.Zero.ToString());
UUID ownerID = UUID.Zero;
if (owned)
ownerID = m_host.OwnerID;
@ -2446,6 +2453,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return;
string appearanceSerialized = LoadNotecard(notecard);
if (appearanceSerialized == null)
OSSLError(string.Format("osNpcCreate: Notecard reference '{0}' not found.", notecard));
OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
// OSD a = OSDParser.DeserializeLLSDXml(appearanceSerialized);
// Console.WriteLine("appearanceSerialized {0}", appearanceSerialized);
@ -3691,5 +3702,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
DropAttachmentAt(false, pos, rot);
}
public LSL_Integer osListenRegex(int channelID, string name, string ID, string msg, int regexBitfield)
{
CheckThreatLevel(ThreatLevel.Low, "osListenRegex");
m_host.AddScriptLPS(1);
UUID keyID;
UUID.TryParse(ID, out keyID);
// if we want the name to be used as a regular expression, ensure it is valid first.
if ((regexBitfield & ScriptBaseClass.OS_LISTEN_REGEX_NAME) == ScriptBaseClass.OS_LISTEN_REGEX_NAME)
{
try
{
Regex.IsMatch("", name);
}
catch (Exception)
{
OSSLShoutError("Name regex is invalid.");
return -1;
}
}
// if we want the msg to be used as a regular expression, ensure it is valid first.
if ((regexBitfield & ScriptBaseClass.OS_LISTEN_REGEX_MESSAGE) == ScriptBaseClass.OS_LISTEN_REGEX_MESSAGE)
{
try
{
Regex.IsMatch("", msg);
}
catch (Exception)
{
OSSLShoutError("Message regex is invalid.");
return -1;
}
}
IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
return (wComm == null) ? -1 : wComm.Listen(
m_host.LocalId,
m_item.ItemID,
m_host.UUID,
channelID,
name,
keyID,
msg,
regexBitfield
);
}
public LSL_Integer osRegexIsMatch(string input, string pattern)
{
CheckThreatLevel(ThreatLevel.Low, "osRegexIsMatch");
m_host.AddScriptLPS(1);
try
{
return Regex.IsMatch(input, pattern) ? 1 : 0;
}
catch (Exception)
{
OSSLShoutError("Possible invalid regular expression detected.");
return 0;
}
}
}
}

View File

@ -418,5 +418,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
/// <param name="pos"></param>
/// <param name="rot"></param>
void osForceDropAttachmentAt(vector pos, rotation rot);
/// <summary>
/// Identical to llListen except for a bitfield which indicates which
/// string parameters should be parsed as regex patterns.
/// </summary>
/// <param name="channelID"></param>
/// <param name="name"></param>
/// <param name="ID"></param>
/// <param name="msg"></param>
/// <param name="regexBitfield">
/// OS_LISTEN_REGEX_NAME
/// OS_LISTEN_REGEX_MESSAGE
/// </param>
/// <returns></returns>
LSL_Integer osListenRegex(int channelID, string name, string ID,
string msg, int regexBitfield);
/// <summary>
/// Wraps to bool Regex.IsMatch(string input, string pattern)
/// </summary>
/// <param name="input">string to test for match</param>
/// <param name="regex">string to use as pattern</param>
/// <returns>boolean</returns>
LSL_Integer osRegexIsMatch(string input, string pattern);
}
}

View File

@ -741,5 +741,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int KFM_CMD_PLAY = 0;
public const int KFM_CMD_STOP = 1;
public const int KFM_CMD_PAUSE = 2;
/// <summary>
/// process name parameter as regex
/// </summary>
public const int OS_LISTEN_REGEX_NAME = 0x1;
/// <summary>
/// process message parameter as regex
/// </summary>
public const int OS_LISTEN_REGEX_MESSAGE = 0x2;
}
}

View File

@ -992,5 +992,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{
m_OSSL_Functions.osForceDropAttachmentAt(pos, rot);
}
public LSL_Integer osListenRegex(int channelID, string name, string ID, string msg, int regexBitfield)
{
return m_OSSL_Functions.osListenRegex(channelID, name, ID, msg, regexBitfield);
}
public LSL_Integer osRegexIsMatch(string input, string pattern)
{
return m_OSSL_Functions.osRegexIsMatch(input, pattern);
}
}
}

View File

@ -0,0 +1,40 @@
/*
* 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;
namespace OpenSim.Region.ScriptEngine.Shared
{
public class ScriptException : Exception
{
public ScriptException() : base() {}
public ScriptException(string message) : base(message) {}
public ScriptException(string message, Exception innerException) : base(message, innerException) {}
}
}

View File

@ -75,76 +75,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
m_engine.AddRegion(m_scene);
}
/// <summary>
/// Test creation of an NPC where the appearance data comes from a notecard
/// </summary>
[Test]
public void TestOsNpcCreateUsingAppearanceFromNotecard()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
// Store an avatar with a different height from default in a notecard.
UUID userId = TestHelpers.ParseTail(0x1);
float newHeight = 1.9f;
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
sp.Appearance.AvatarHeight = newHeight;
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
SceneObjectPart part = so.RootPart;
m_scene.AddSceneObject(so);
OSSL_Api osslApi = new OSSL_Api();
osslApi.Initialize(m_engine, part, null);
string notecardName = "appearanceNc";
osslApi.osOwnerSaveAppearance(notecardName);
// Try creating a bot using the appearance in the notecard.
string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), notecardName);
Assert.That(npcRaw, Is.Not.Null);
UUID npcId = new UUID(npcRaw);
ScenePresence npc = m_scene.GetScenePresence(npcId);
Assert.That(npc, Is.Not.Null);
Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
}
/// <summary>
/// Test creation of an NPC where the appearance data comes from an avatar already in the region.
/// </summary>
[Test]
public void TestOsNpcCreateUsingAppearanceFromAvatar()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
// Store an avatar with a different height from default in a notecard.
UUID userId = TestHelpers.ParseTail(0x1);
float newHeight = 1.9f;
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
sp.Appearance.AvatarHeight = newHeight;
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
SceneObjectPart part = so.RootPart;
m_scene.AddSceneObject(so);
OSSL_Api osslApi = new OSSL_Api();
osslApi.Initialize(m_engine, part, null);
string notecardName = "appearanceNc";
osslApi.osOwnerSaveAppearance(notecardName);
// Try creating a bot using the existing avatar's appearance
string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), sp.UUID.ToString());
Assert.That(npcRaw, Is.Not.Null);
UUID npcId = new UUID(npcRaw);
ScenePresence npc = m_scene.GetScenePresence(npcId);
Assert.That(npc, Is.Not.Null);
Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
}
[Test]
public void TestOsOwnerSaveAppearance()
{

View File

@ -36,6 +36,7 @@ using OpenMetaverse;
using OpenMetaverse.Assets;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Region.CoreModules.Avatar.Attachments;
using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
using OpenSim.Region.OptionalModules.World.NPC;
using OpenSim.Region.Framework.Scenes;
@ -71,13 +72,193 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
config.Set("Enabled", "true");
m_scene = new SceneHelpers().SetupScene();
SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule());
SceneHelpers.SetupSceneModules(
m_scene, initConfigSource, new AvatarFactoryModule(), new AttachmentsModule(), new NPCModule());
m_engine = new XEngine.XEngine();
m_engine.Initialise(initConfigSource);
m_engine.AddRegion(m_scene);
}
/// <summary>
/// Test creation of an NPC where the appearance data comes from a notecard
/// </summary>
[Test]
public void TestOsNpcCreateUsingAppearanceFromNotecard()
{
TestHelpers.InMethod();
// Store an avatar with a different height from default in a notecard.
UUID userId = TestHelpers.ParseTail(0x1);
float newHeight = 1.9f;
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
sp.Appearance.AvatarHeight = newHeight;
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
SceneObjectPart part = so.RootPart;
m_scene.AddSceneObject(so);
OSSL_Api osslApi = new OSSL_Api();
osslApi.Initialize(m_engine, part, null);
string notecardName = "appearanceNc";
osslApi.osOwnerSaveAppearance(notecardName);
// Try creating a bot using the appearance in the notecard.
string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), notecardName);
Assert.That(npcRaw, Is.Not.Null);
UUID npcId = new UUID(npcRaw);
ScenePresence npc = m_scene.GetScenePresence(npcId);
Assert.That(npc, Is.Not.Null);
Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
}
[Test]
public void TestOsNpcCreateNotExistingNotecard()
{
TestHelpers.InMethod();
UUID userId = TestHelpers.ParseTail(0x1);
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
m_scene.AddSceneObject(so);
OSSL_Api osslApi = new OSSL_Api();
osslApi.Initialize(m_engine, so.RootPart, null);
string npcRaw;
bool gotExpectedException = false;
try
{
npcRaw
= osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), "not existing notecard name");
}
catch (ScriptException)
{
gotExpectedException = true;
}
Assert.That(gotExpectedException, Is.True);
}
/// <summary>
/// Test creation of an NPC where the appearance data comes from an avatar already in the region.
/// </summary>
[Test]
public void TestOsNpcCreateUsingAppearanceFromAvatar()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
// Store an avatar with a different height from default in a notecard.
UUID userId = TestHelpers.ParseTail(0x1);
float newHeight = 1.9f;
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
sp.Appearance.AvatarHeight = newHeight;
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
SceneObjectPart part = so.RootPart;
m_scene.AddSceneObject(so);
OSSL_Api osslApi = new OSSL_Api();
osslApi.Initialize(m_engine, part, null);
string notecardName = "appearanceNc";
osslApi.osOwnerSaveAppearance(notecardName);
// Try creating a bot using the existing avatar's appearance
string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), sp.UUID.ToString());
Assert.That(npcRaw, Is.Not.Null);
UUID npcId = new UUID(npcRaw);
ScenePresence npc = m_scene.GetScenePresence(npcId);
Assert.That(npc, Is.Not.Null);
Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
}
[Test]
public void TestOsNpcLoadAppearance()
{
TestHelpers.InMethod();
// Store an avatar with a different height from default in a notecard.
UUID userId = TestHelpers.ParseTail(0x1);
float firstHeight = 1.9f;
float secondHeight = 2.1f;
string firstAppearanceNcName = "appearanceNc1";
string secondAppearanceNcName = "appearanceNc2";
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
sp.Appearance.AvatarHeight = firstHeight;
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
SceneObjectPart part = so.RootPart;
m_scene.AddSceneObject(so);
OSSL_Api osslApi = new OSSL_Api();
osslApi.Initialize(m_engine, part, null);
osslApi.osOwnerSaveAppearance(firstAppearanceNcName);
string npcRaw
= osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), firstAppearanceNcName);
// Create a second appearance notecard with a different height
sp.Appearance.AvatarHeight = secondHeight;
osslApi.osOwnerSaveAppearance(secondAppearanceNcName);
osslApi.osNpcLoadAppearance(npcRaw, secondAppearanceNcName);
UUID npcId = new UUID(npcRaw);
ScenePresence npc = m_scene.GetScenePresence(npcId);
Assert.That(npc, Is.Not.Null);
Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(secondHeight));
}
[Test]
public void TestOsNpcLoadAppearanceNotExistingNotecard()
{
TestHelpers.InMethod();
// Store an avatar with a different height from default in a notecard.
UUID userId = TestHelpers.ParseTail(0x1);
float firstHeight = 1.9f;
float secondHeight = 2.1f;
string firstAppearanceNcName = "appearanceNc1";
string secondAppearanceNcName = "appearanceNc2";
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
sp.Appearance.AvatarHeight = firstHeight;
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
SceneObjectPart part = so.RootPart;
m_scene.AddSceneObject(so);
OSSL_Api osslApi = new OSSL_Api();
osslApi.Initialize(m_engine, part, null);
osslApi.osOwnerSaveAppearance(firstAppearanceNcName);
string npcRaw
= osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), firstAppearanceNcName);
bool gotExpectedException = false;
try
{
osslApi.osNpcLoadAppearance(npcRaw, secondAppearanceNcName);
}
catch (ScriptException)
{
gotExpectedException = true;
}
Assert.That(gotExpectedException, Is.True);
UUID npcId = new UUID(npcRaw);
ScenePresence npc = m_scene.GetScenePresence(npcId);
Assert.That(npc, Is.Not.Null);
Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(firstHeight));
}
/// <summary>
/// Test removal of an owned NPC.
/// </summary>
@ -85,7 +266,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
public void TestOsNpcRemoveOwned()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
// Store an avatar with a different height from default in a notecard.
UUID userId = TestHelpers.ParseTail(0x1);

View File

@ -141,6 +141,9 @@ namespace OpenSim.Server.Handlers.Asset
}
string fileName = rawAssetId;
if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, fileName))
return;
using (FileStream fs = new FileStream(fileName, FileMode.CreateNew))
{

View File

@ -531,13 +531,9 @@ namespace OpenSim.Tests.Common.Mock
{
}
public virtual void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName,
UUID fromAgentID, byte source, byte audible)
{
}
public virtual void SendChatMessage(byte[] message, byte type, Vector3 fromPos, string fromName,
UUID fromAgentID, byte source, byte audible)
public virtual void SendChatMessage(
string message, byte type, Vector3 fromPos, string fromName,
UUID fromAgentID, UUID ownerID, byte source, byte audible)
{
}

View File

@ -303,37 +303,37 @@
<Key Name="fileName" Value="snd_TerrainStone.ogg" />
</Section>
<Section Name="snd_TerrainMetal">
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807200c9a66" />
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807201c9a66" />
<Key Name="name" Value="snd_TerrainMetal" />
<Key Name="assetType" Value="1" />
<Key Name="fileName" Value="snd_TerrainMetal.ogg" />
</Section>
<Section Name="snd_TerrainGlass">
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807200c9a66" />
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807202c9a66" />
<Key Name="name" Value="snd_TerrainGlass" />
<Key Name="assetType" Value="1" />
<Key Name="fileName" Value="snd_TerrainGlass.ogg" />
</Section>
<Section Name="snd_TerrainWood">
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807200c9a66" />
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807203c9a66" />
<Key Name="name" Value="snd_TerrainWood" />
<Key Name="assetType" Value="1" />
<Key Name="fileName" Value="snd_TerrainWood.ogg" />
</Section>
<Section Name="snd_TerrainFlesh">
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807200c9a66" />
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807204c9a66" />
<Key Name="name" Value="snd_TerrainFlesh" />
<Key Name="assetType" Value="1" />
<Key Name="fileName" Value="snd_TerrainFlesh.ogg" />
</Section>
<Section Name="snd_TerrainPlastic">
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807200c9a66" />
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807205c9a66" />
<Key Name="name" Value="snd_TerrainPlastic" />
<Key Name="assetType" Value="1" />
<Key Name="fileName" Value="snd_TerrainPlastic.ogg" />
</Section>
<Section Name="snd_TerrainRubber">
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807200c9a66" />
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807206c9a66" />
<Key Name="name" Value="snd_TerrainRubber" />
<Key Name="assetType" Value="1" />
<Key Name="fileName" Value="snd_TerrainRubber.ogg" />

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.