Merge branch 'master' of brain.opensimulator.org:/var/git/opensim
commit
c7a02dc058
|
@ -1403,7 +1403,10 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
prim.Sound = DBGuid.FromDB(row["LoopedSound"].ToString());
|
prim.Sound = DBGuid.FromDB(row["LoopedSound"].ToString());
|
||||||
prim.SoundGain = (float)(double)row["LoopedSoundGain"];
|
prim.SoundGain = (float)(double)row["LoopedSoundGain"];
|
||||||
|
if (prim.Sound != UUID.Zero)
|
||||||
prim.SoundFlags = 1; // If it's persisted at all, it's looped
|
prim.SoundFlags = 1; // If it's persisted at all, it's looped
|
||||||
|
else
|
||||||
|
prim.SoundFlags = 0;
|
||||||
|
|
||||||
if (!(row["TextureAnimation"] is DBNull))
|
if (!(row["TextureAnimation"] is DBNull))
|
||||||
prim.TextureAnimation = (byte[])row["TextureAnimation"];
|
prim.TextureAnimation = (byte[])row["TextureAnimation"];
|
||||||
|
|
|
@ -1742,7 +1742,10 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
prim.Sound = new UUID((Guid)primRow["LoopedSound"]);
|
prim.Sound = new UUID((Guid)primRow["LoopedSound"]);
|
||||||
prim.SoundGain = Convert.ToSingle(primRow["LoopedSoundGain"]);
|
prim.SoundGain = Convert.ToSingle(primRow["LoopedSoundGain"]);
|
||||||
|
if (prim.Sound != UUID.Zero)
|
||||||
prim.SoundFlags = 1; // If it's persisted at all, it's looped
|
prim.SoundFlags = 1; // If it's persisted at all, it's looped
|
||||||
|
else
|
||||||
|
prim.SoundFlags = 0;
|
||||||
|
|
||||||
if (!(primRow["TextureAnimation"] is DBNull))
|
if (!(primRow["TextureAnimation"] is DBNull))
|
||||||
prim.TextureAnimation = (Byte[])primRow["TextureAnimation"];
|
prim.TextureAnimation = (Byte[])primRow["TextureAnimation"];
|
||||||
|
|
|
@ -1742,7 +1742,10 @@ namespace OpenSim.Data.SQLite
|
||||||
|
|
||||||
prim.Sound = new UUID(row["LoopedSound"].ToString());
|
prim.Sound = new UUID(row["LoopedSound"].ToString());
|
||||||
prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]);
|
prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]);
|
||||||
|
if (prim.Sound != UUID.Zero)
|
||||||
prim.SoundFlags = 1; // If it's persisted at all, it's looped
|
prim.SoundFlags = 1; // If it's persisted at all, it's looped
|
||||||
|
else
|
||||||
|
prim.SoundFlags = 0;
|
||||||
|
|
||||||
if (!row.IsNull("TextureAnimation"))
|
if (!row.IsNull("TextureAnimation"))
|
||||||
prim.TextureAnimation = Convert.FromBase64String(row["TextureAnimation"].ToString());
|
prim.TextureAnimation = Convert.FromBase64String(row["TextureAnimation"].ToString());
|
||||||
|
|
|
@ -51,7 +51,14 @@ namespace OpenSim.Framework
|
||||||
private object m_syncRoot = new object();
|
private object m_syncRoot = new object();
|
||||||
|
|
||||||
/// <summary>Number of clients in the collection</summary>
|
/// <summary>Number of clients in the collection</summary>
|
||||||
public int Count { get { return m_dict1.Count; } }
|
public int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (m_syncRoot)
|
||||||
|
return m_dict1.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default constructor
|
/// Default constructor
|
||||||
|
@ -60,7 +67,7 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
m_dict1 = new Dictionary<UUID, IClientAPI>();
|
m_dict1 = new Dictionary<UUID, IClientAPI>();
|
||||||
m_dict2 = new Dictionary<IPEndPoint, IClientAPI>();
|
m_dict2 = new Dictionary<IPEndPoint, IClientAPI>();
|
||||||
m_array = new IClientAPI[0];
|
m_array = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -74,17 +81,9 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
lock (m_syncRoot)
|
lock (m_syncRoot)
|
||||||
{
|
{
|
||||||
// allow self healing
|
|
||||||
// if (m_dict1.ContainsKey(value.AgentId) || m_dict2.ContainsKey(value.RemoteEndPoint))
|
|
||||||
// return false;
|
|
||||||
|
|
||||||
m_dict1[value.AgentId] = value;
|
m_dict1[value.AgentId] = value;
|
||||||
m_dict2[value.RemoteEndPoint] = value;
|
m_dict2[value.RemoteEndPoint] = value;
|
||||||
|
m_array = null;
|
||||||
// dict1 is the master
|
|
||||||
IClientAPI[] newArray = new IClientAPI[m_dict1.Count];
|
|
||||||
m_dict1.Values.CopyTo(newArray, 0);
|
|
||||||
m_array = newArray;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -105,10 +104,7 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
m_dict1.Remove(key);
|
m_dict1.Remove(key);
|
||||||
m_dict2.Remove(value.RemoteEndPoint);
|
m_dict2.Remove(value.RemoteEndPoint);
|
||||||
|
m_array = null;
|
||||||
IClientAPI[] newArray = new IClientAPI[m_dict1.Count];
|
|
||||||
m_dict1.Values.CopyTo(newArray, 0);
|
|
||||||
m_array = newArray;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,7 +120,7 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
m_dict1.Clear();
|
m_dict1.Clear();
|
||||||
m_dict2.Clear();
|
m_dict2.Clear();
|
||||||
m_array = new IClientAPI[0];
|
m_array = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +131,7 @@ namespace OpenSim.Framework
|
||||||
/// <returns>True if the UUID was found in the collection, otherwise false</returns>
|
/// <returns>True if the UUID was found in the collection, otherwise false</returns>
|
||||||
public bool ContainsKey(UUID key)
|
public bool ContainsKey(UUID key)
|
||||||
{
|
{
|
||||||
|
lock (m_syncRoot)
|
||||||
return m_dict1.ContainsKey(key);
|
return m_dict1.ContainsKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +142,7 @@ namespace OpenSim.Framework
|
||||||
/// <returns>True if the endpoint was found in the collection, otherwise false</returns>
|
/// <returns>True if the endpoint was found in the collection, otherwise false</returns>
|
||||||
public bool ContainsKey(IPEndPoint key)
|
public bool ContainsKey(IPEndPoint key)
|
||||||
{
|
{
|
||||||
|
lock (m_syncRoot)
|
||||||
return m_dict2.ContainsKey(key);
|
return m_dict2.ContainsKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,8 +154,12 @@ namespace OpenSim.Framework
|
||||||
/// <returns>True if the lookup succeeded, otherwise false</returns>
|
/// <returns>True if the lookup succeeded, otherwise false</returns>
|
||||||
public bool TryGetValue(UUID key, out IClientAPI value)
|
public bool TryGetValue(UUID key, out IClientAPI value)
|
||||||
{
|
{
|
||||||
try { return m_dict1.TryGetValue(key, out value); }
|
try
|
||||||
catch (Exception)
|
{
|
||||||
|
lock (m_syncRoot)
|
||||||
|
return m_dict1.TryGetValue(key, out value);
|
||||||
|
}
|
||||||
|
catch
|
||||||
{
|
{
|
||||||
value = null;
|
value = null;
|
||||||
return false;
|
return false;
|
||||||
|
@ -172,8 +174,12 @@ namespace OpenSim.Framework
|
||||||
/// <returns>True if the lookup succeeded, otherwise false</returns>
|
/// <returns>True if the lookup succeeded, otherwise false</returns>
|
||||||
public bool TryGetValue(IPEndPoint key, out IClientAPI value)
|
public bool TryGetValue(IPEndPoint key, out IClientAPI value)
|
||||||
{
|
{
|
||||||
try { return m_dict2.TryGetValue(key, out value); }
|
try
|
||||||
catch (Exception)
|
{
|
||||||
|
lock (m_syncRoot)
|
||||||
|
return m_dict2.TryGetValue(key, out value);
|
||||||
|
}
|
||||||
|
catch
|
||||||
{
|
{
|
||||||
value = null;
|
value = null;
|
||||||
return false;
|
return false;
|
||||||
|
@ -187,7 +193,20 @@ namespace OpenSim.Framework
|
||||||
/// <param name="action">Action to perform on each element</param>
|
/// <param name="action">Action to perform on each element</param>
|
||||||
public void ForEach(Action<IClientAPI> action)
|
public void ForEach(Action<IClientAPI> action)
|
||||||
{
|
{
|
||||||
IClientAPI[] localArray = m_array;
|
IClientAPI[] localArray;
|
||||||
|
lock (m_syncRoot)
|
||||||
|
{
|
||||||
|
if (m_array == null)
|
||||||
|
{
|
||||||
|
if (m_dict1.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_array = new IClientAPI[m_dict1.Count];
|
||||||
|
m_dict1.Values.CopyTo(m_array, 0);
|
||||||
|
}
|
||||||
|
localArray = m_array;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < localArray.Length; i++)
|
for (int i = 0; i < localArray.Length; i++)
|
||||||
action(localArray[i]);
|
action(localArray[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -390,7 +390,7 @@ namespace OpenSim.Framework
|
||||||
IClientAPI remoteClient, UUID invoice, UUID senderID, bool scripted, bool collisionEvents, bool physics);
|
IClientAPI remoteClient, UUID invoice, UUID senderID, bool scripted, bool collisionEvents, bool physics);
|
||||||
|
|
||||||
public delegate void EstateTeleportOneUserHomeRequest(
|
public delegate void EstateTeleportOneUserHomeRequest(
|
||||||
IClientAPI remoteClient, UUID invoice, UUID senderID, UUID prey);
|
IClientAPI remoteClient, UUID invoice, UUID senderID, UUID prey, bool kill);
|
||||||
|
|
||||||
public delegate void EstateTeleportAllUsersHomeRequest(IClientAPI remoteClient, UUID invoice, UUID senderID);
|
public delegate void EstateTeleportAllUsersHomeRequest(IClientAPI remoteClient, UUID invoice, UUID senderID);
|
||||||
|
|
||||||
|
@ -671,7 +671,6 @@ namespace OpenSim.Framework
|
||||||
Particles = 1 << 19,
|
Particles = 1 << 19,
|
||||||
ExtraData = 1 << 20,
|
ExtraData = 1 << 20,
|
||||||
Sound = 1 << 21,
|
Sound = 1 << 21,
|
||||||
Joint = 1 << 22,
|
|
||||||
|
|
||||||
TerseUpdate = Position | Rotation | Velocity | Acceleration | AngularVelocity,
|
TerseUpdate = Position | Rotation | Velocity | Acceleration | AngularVelocity,
|
||||||
FullUpdate = 0x00ffffff,
|
FullUpdate = 0x00ffffff,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
|
@ -229,6 +229,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
PollServiceHttpRequest req;
|
PollServiceHttpRequest req;
|
||||||
while (m_running)
|
while (m_running)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
req = null;
|
req = null;
|
||||||
if (!m_requests.TryTake(out req, 4500) || req == null)
|
if (!m_requests.TryTake(out req, 4500) || req == null)
|
||||||
|
@ -239,8 +241,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
Watchdog.UpdateThread();
|
Watchdog.UpdateThread();
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!req.HttpContext.CanSend())
|
if (!req.HttpContext.CanSend())
|
||||||
{
|
{
|
||||||
req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id);
|
req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id);
|
||||||
|
@ -305,6 +305,12 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (ThreadAbortException)
|
||||||
|
{
|
||||||
|
Thread.ResetAbort();
|
||||||
|
// Shouldn't set this to 'false', the normal shutdown should cause things to exit
|
||||||
|
// m_running = false;
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());
|
m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());
|
||||||
|
|
|
@ -212,7 +212,6 @@ namespace OpenSim.Framework
|
||||||
return heights;
|
return heights;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TerrainData.GetDoubles
|
|
||||||
public double[,] GetDoubles()
|
public double[,] GetDoubles()
|
||||||
{
|
{
|
||||||
double[,] ret = new double[SizeX, SizeY];
|
double[,] ret = new double[SizeX, SizeY];
|
||||||
|
|
|
@ -2437,34 +2437,6 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
#region FireAndForget Threading Pattern
|
#region FireAndForget Threading Pattern
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Created to work around a limitation in Mono with nested delegates
|
|
||||||
/// </summary>
|
|
||||||
private sealed class FireAndForgetWrapper
|
|
||||||
{
|
|
||||||
private static object syncRoot = new Object();
|
|
||||||
|
|
||||||
public void FireAndForget(System.Threading.WaitCallback callback)
|
|
||||||
{
|
|
||||||
callback.BeginInvoke(null, EndFireAndForget, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void FireAndForget(System.Threading.WaitCallback callback, object obj)
|
|
||||||
{
|
|
||||||
callback.BeginInvoke(obj, EndFireAndForget, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void EndFireAndForget(IAsyncResult ar)
|
|
||||||
{
|
|
||||||
System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState;
|
|
||||||
|
|
||||||
try { callback.EndInvoke(ar); }
|
|
||||||
catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); }
|
|
||||||
|
|
||||||
ar.AsyncWaitHandle.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void InitThreadPool(int minThreads, int maxThreads)
|
public static void InitThreadPool(int minThreads, int maxThreads)
|
||||||
{
|
{
|
||||||
if (maxThreads < 2)
|
if (maxThreads < 2)
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
private string m_GetTextureURL;
|
private string m_GetTextureURL;
|
||||||
private string m_GetMeshURL;
|
private string m_GetMeshURL;
|
||||||
private string m_GetMesh2URL;
|
private string m_GetMesh2URL;
|
||||||
// private string m_GetAssetURL;
|
private string m_GetAssetURL;
|
||||||
|
|
||||||
class APollRequest
|
class APollRequest
|
||||||
{
|
{
|
||||||
|
@ -87,7 +87,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
private Dictionary<UUID, string> m_capsDictTexture = new Dictionary<UUID, string>();
|
private Dictionary<UUID, string> m_capsDictTexture = new Dictionary<UUID, string>();
|
||||||
private Dictionary<UUID, string> m_capsDictGetMesh = new Dictionary<UUID, string>();
|
private Dictionary<UUID, string> m_capsDictGetMesh = new Dictionary<UUID, string>();
|
||||||
private Dictionary<UUID, string> m_capsDictGetMesh2 = new Dictionary<UUID, string>();
|
private Dictionary<UUID, string> m_capsDictGetMesh2 = new Dictionary<UUID, string>();
|
||||||
//private Dictionary<UUID, string> m_capsDictGetAsset = new Dictionary<UUID, string>();
|
private Dictionary<UUID, string> m_capsDictGetAsset = new Dictionary<UUID, string>();
|
||||||
|
|
||||||
#region Region Module interfaceBase Members
|
#region Region Module interfaceBase Members
|
||||||
|
|
||||||
|
@ -113,11 +113,11 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
m_GetMesh2URL = config.GetString("Cap_GetMesh2", string.Empty);
|
m_GetMesh2URL = config.GetString("Cap_GetMesh2", string.Empty);
|
||||||
if (m_GetMesh2URL != string.Empty)
|
if (m_GetMesh2URL != string.Empty)
|
||||||
m_Enabled = true;
|
m_Enabled = true;
|
||||||
/*
|
|
||||||
m_GetAssetURL = config.GetString("Cap_GetAsset", string.Empty);
|
m_GetAssetURL = config.GetString("Cap_GetAsset", string.Empty);
|
||||||
if (m_GetAssetURL != string.Empty)
|
if (m_GetAssetURL != string.Empty)
|
||||||
m_Enabled = true;
|
m_Enabled = true;
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRegion(Scene pScene)
|
public void AddRegion(Scene pScene)
|
||||||
|
@ -203,6 +203,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private static void DoAssetRequests()
|
private static void DoAssetRequests()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
while (m_NumberScenes > 0)
|
while (m_NumberScenes > 0)
|
||||||
{
|
{
|
||||||
|
@ -219,6 +221,11 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
Watchdog.UpdateThread();
|
Watchdog.UpdateThread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (ThreadAbortException)
|
||||||
|
{
|
||||||
|
Thread.ResetAbort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class PollServiceAssetEventArgs : PollServiceEventArgs
|
private class PollServiceAssetEventArgs : PollServiceEventArgs
|
||||||
{
|
{
|
||||||
|
@ -441,7 +448,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
else if (m_GetMesh2URL != string.Empty)
|
else if (m_GetMesh2URL != string.Empty)
|
||||||
caps.RegisterHandler("GetMesh2", m_GetMesh2URL);
|
caps.RegisterHandler("GetMesh2", m_GetMesh2URL);
|
||||||
|
|
||||||
/* we can't support this cap. Current viewers connect to the wrong regions.
|
|
||||||
//ViewerAsset
|
//ViewerAsset
|
||||||
if (m_GetAssetURL == "localhost")
|
if (m_GetAssetURL == "localhost")
|
||||||
{
|
{
|
||||||
|
@ -459,7 +465,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
}
|
}
|
||||||
else if (m_GetAssetURL != string.Empty)
|
else if (m_GetAssetURL != string.Empty)
|
||||||
caps.RegisterHandler("ViewerAsset", m_GetMesh2URL);
|
caps.RegisterHandler("ViewerAsset", m_GetMesh2URL);
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeregisterCaps(UUID agentID, Caps caps)
|
private void DeregisterCaps(UUID agentID, Caps caps)
|
||||||
|
@ -480,13 +486,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
MainServer.Instance.RemovePollServiceHTTPHandler("", capUrl);
|
MainServer.Instance.RemovePollServiceHTTPHandler("", capUrl);
|
||||||
m_capsDictGetMesh2.Remove(agentID);
|
m_capsDictGetMesh2.Remove(agentID);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (m_capsDictGetAsset.TryGetValue(agentID, out capUrl))
|
if (m_capsDictGetAsset.TryGetValue(agentID, out capUrl))
|
||||||
{
|
{
|
||||||
MainServer.Instance.RemovePollServiceHTTPHandler("", capUrl);
|
MainServer.Instance.RemovePollServiceHTTPHandler("", capUrl);
|
||||||
m_capsDictGetAsset.Remove(agentID);
|
m_capsDictGetAsset.Remove(agentID);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -395,7 +395,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
private static void DoInventoryRequests()
|
private static void DoInventoryRequests()
|
||||||
{
|
{
|
||||||
while (true)
|
bool running = true;
|
||||||
|
while (running)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
APollRequest poolreq;
|
APollRequest poolreq;
|
||||||
if (m_queue.TryTake(out poolreq, 4500))
|
if (m_queue.TryTake(out poolreq, 4500))
|
||||||
|
@ -407,6 +410,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
}
|
}
|
||||||
Watchdog.UpdateThread();
|
Watchdog.UpdateThread();
|
||||||
}
|
}
|
||||||
|
catch (ThreadAbortException)
|
||||||
|
{
|
||||||
|
Thread.ResetAbort();
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -120,7 +120,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <summary>Circuit code that this client is connected on</summary>
|
/// <summary>Circuit code that this client is connected on</summary>
|
||||||
public readonly uint CircuitCode;
|
public readonly uint CircuitCode;
|
||||||
/// <summary>Sequence numbers of packets we've received (for duplicate checking)</summary>
|
/// <summary>Sequence numbers of packets we've received (for duplicate checking)</summary>
|
||||||
public IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(200);
|
public IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(256);
|
||||||
|
|
||||||
/// <summary>Packets we have sent that need to be ACKed by the client</summary>
|
/// <summary>Packets we have sent that need to be ACKed by the client</summary>
|
||||||
public UnackedPacketCollection NeedAcks = new UnackedPacketCollection();
|
public UnackedPacketCollection NeedAcks = new UnackedPacketCollection();
|
||||||
|
@ -210,12 +210,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is the percentage of the udp texture queue to add to the task queue since
|
|
||||||
/// textures are now generally handled through http.
|
|
||||||
/// </summary>
|
|
||||||
private double m_cannibalrate = 0.0;
|
|
||||||
|
|
||||||
private ClientInfo m_info = new ClientInfo();
|
private ClientInfo m_info = new ClientInfo();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -257,8 +251,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// Create an array of token buckets for this clients different throttle categories
|
// Create an array of token buckets for this clients different throttle categories
|
||||||
m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
|
m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
|
||||||
|
|
||||||
m_cannibalrate = rates.CannibalizeTextureRate;
|
|
||||||
|
|
||||||
m_burst = rates.Total * rates.BrustTime;
|
m_burst = rates.Total * rates.BrustTime;
|
||||||
|
|
||||||
for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
|
for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
|
||||||
|
@ -449,12 +441,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
asset = Math.Max(asset, LLUDPServer.MTU);
|
asset = Math.Max(asset, LLUDPServer.MTU);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Since most textures are now delivered through http, make it possible
|
|
||||||
// to cannibalize some of the bw from the texture throttle to use for
|
|
||||||
// the task queue (e.g. object updates)
|
|
||||||
task = task + (int)(m_cannibalrate * texture);
|
|
||||||
texture = (int)((1 - m_cannibalrate) * texture);
|
|
||||||
|
|
||||||
int total = resend + land + wind + cloud + task + texture + asset;
|
int total = resend + land + wind + cloud + task + texture + asset;
|
||||||
|
|
||||||
float m_burst = total * m_burstTime;
|
float m_burst = total * m_burstTime;
|
||||||
|
@ -575,22 +561,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
DoubleLocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
|
DoubleLocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
|
||||||
|
|
||||||
if (m_deliverPackets == false)
|
if (forceQueue || m_deliverPackets == false)
|
||||||
{
|
{
|
||||||
queue.Enqueue(packet, highPriority);
|
queue.Enqueue(packet, highPriority);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenBucket bucket = m_throttleCategories[category];
|
// need to enqueue if queue is not empty
|
||||||
|
|
||||||
// Don't send this packet if queue is not empty
|
|
||||||
if (queue.Count > 0 || m_nextPackets[category] != null)
|
if (queue.Count > 0 || m_nextPackets[category] != null)
|
||||||
{
|
{
|
||||||
queue.Enqueue(packet, highPriority);
|
queue.Enqueue(packet, highPriority);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!forceQueue && bucket.CheckTokens(packet.Buffer.DataLength))
|
// check bandwidth
|
||||||
|
TokenBucket bucket = m_throttleCategories[category];
|
||||||
|
if (bucket.CheckTokens(packet.Buffer.DataLength))
|
||||||
{
|
{
|
||||||
// enough tokens so it can be sent imediatly by caller
|
// enough tokens so it can be sent imediatly by caller
|
||||||
bucket.RemoveTokens(packet.Buffer.DataLength);
|
bucket.RemoveTokens(packet.Buffer.DataLength);
|
||||||
|
@ -608,7 +594,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// We don't have a token bucket for this category, so it will not be queued
|
// We don't have a token bucket for this category, so it will not be queued
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -650,6 +635,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// leaving a dequeued packet still waiting to be sent out. Try to
|
// leaving a dequeued packet still waiting to be sent out. Try to
|
||||||
// send it again
|
// send it again
|
||||||
OutgoingPacket nextPacket = m_nextPackets[i];
|
OutgoingPacket nextPacket = m_nextPackets[i];
|
||||||
|
if(nextPacket.Buffer == null)
|
||||||
|
{
|
||||||
|
if (m_packetOutboxes[i].Count < 5)
|
||||||
|
emptyCategories |= CategoryToFlag(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (bucket.RemoveTokens(nextPacket.Buffer.DataLength))
|
if (bucket.RemoveTokens(nextPacket.Buffer.DataLength))
|
||||||
{
|
{
|
||||||
// Send the packet
|
// Send the packet
|
||||||
|
@ -681,6 +672,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
// A packet was pulled off the queue. See if we have
|
// A packet was pulled off the queue. See if we have
|
||||||
// enough tokens in the bucket to send it out
|
// enough tokens in the bucket to send it out
|
||||||
|
if(packet.Buffer == null)
|
||||||
|
{
|
||||||
|
// packet canceled elsewhere (by a ack for example)
|
||||||
|
if (queue.Count < 5)
|
||||||
|
emptyCategories |= CategoryToFlag(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (bucket.RemoveTokens(packet.Buffer.DataLength))
|
if (bucket.RemoveTokens(packet.Buffer.DataLength))
|
||||||
{
|
{
|
||||||
// Send the packet
|
// Send the packet
|
||||||
|
@ -695,7 +694,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// Save the dequeued packet for the next iteration
|
// Save the dequeued packet for the next iteration
|
||||||
m_nextPackets[i] = packet;
|
m_nextPackets[i] = packet;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -803,8 +802,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fires the OnQueueEmpty callback and sets the minimum time that it
|
/// Fires the OnQueueEmpty callback and sets the minimum time that it
|
||||||
/// can be called again
|
/// can be called again
|
||||||
|
@ -843,6 +840,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void FreeUDPBuffer(UDPPacketBuffer buf)
|
||||||
|
{
|
||||||
|
m_udpServer.FreeUDPBuffer(buf);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a
|
/// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a
|
||||||
/// flag value
|
/// flag value
|
||||||
|
@ -853,34 +855,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
ThrottleOutPacketType category = (ThrottleOutPacketType)i;
|
ThrottleOutPacketType category = (ThrottleOutPacketType)i;
|
||||||
|
|
||||||
/*
|
|
||||||
* Land = 1,
|
|
||||||
/// <summary>Wind data</summary>
|
|
||||||
Wind = 2,
|
|
||||||
/// <summary>Cloud data</summary>
|
|
||||||
Cloud = 3,
|
|
||||||
/// <summary>Any packets that do not fit into the other throttles</summary>
|
|
||||||
Task = 4,
|
|
||||||
/// <summary>Texture assets</summary>
|
|
||||||
Texture = 5,
|
|
||||||
/// <summary>Non-texture assets</summary>
|
|
||||||
Asset = 6,
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (category)
|
switch (category)
|
||||||
{
|
{
|
||||||
case ThrottleOutPacketType.Land:
|
case ThrottleOutPacketType.Land:
|
||||||
return ThrottleOutPacketTypeFlags.Land;
|
return ThrottleOutPacketTypeFlags.Land; // Terrain data
|
||||||
case ThrottleOutPacketType.Wind:
|
case ThrottleOutPacketType.Wind:
|
||||||
return ThrottleOutPacketTypeFlags.Wind;
|
return ThrottleOutPacketTypeFlags.Wind; // Wind data
|
||||||
case ThrottleOutPacketType.Cloud:
|
case ThrottleOutPacketType.Cloud:
|
||||||
return ThrottleOutPacketTypeFlags.Cloud;
|
return ThrottleOutPacketTypeFlags.Cloud; // Cloud data
|
||||||
case ThrottleOutPacketType.Task:
|
case ThrottleOutPacketType.Task:
|
||||||
return ThrottleOutPacketTypeFlags.Task;
|
return ThrottleOutPacketTypeFlags.Task; // Object updates and everything not on the other categories
|
||||||
case ThrottleOutPacketType.Texture:
|
case ThrottleOutPacketType.Texture:
|
||||||
return ThrottleOutPacketTypeFlags.Texture;
|
return ThrottleOutPacketTypeFlags.Texture; // Textures data (also impacts http texture and mesh by default)
|
||||||
case ThrottleOutPacketType.Asset:
|
case ThrottleOutPacketType.Asset:
|
||||||
return ThrottleOutPacketTypeFlags.Asset;
|
return ThrottleOutPacketTypeFlags.Asset; // Non-texture Assets data
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,6 +256,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
/// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary>
|
/// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary>
|
||||||
public const int MTU = 1400;
|
public const int MTU = 1400;
|
||||||
|
public const int MAXPAYLOAD = 1250;
|
||||||
|
|
||||||
/// <summary>Number of forced client logouts due to no receipt of packets before timeout.</summary>
|
/// <summary>Number of forced client logouts due to no receipt of packets before timeout.</summary>
|
||||||
public int ClientLogoutsDueToNoReceives { get; protected set; }
|
public int ClientLogoutsDueToNoReceives { get; protected set; }
|
||||||
|
@ -274,10 +275,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <summary>The measured resolution of Environment.TickCount</summary>
|
/// <summary>The measured resolution of Environment.TickCount</summary>
|
||||||
public readonly float TickCountResolution;
|
public readonly float TickCountResolution;
|
||||||
|
|
||||||
/// <summary>Number of prim updates to put on the queue each time the
|
|
||||||
/// OnQueueEmpty event is triggered for updates</summary>
|
|
||||||
public readonly int PrimUpdatesPerCallback;
|
|
||||||
|
|
||||||
/// <summary>Number of texture packets to put on the queue each time the
|
/// <summary>Number of texture packets to put on the queue each time the
|
||||||
/// OnQueueEmpty event is triggered for textures</summary>
|
/// OnQueueEmpty event is triggered for textures</summary>
|
||||||
public readonly int TextureSendLimit;
|
public readonly int TextureSendLimit;
|
||||||
|
@ -344,18 +341,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
protected ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
|
protected ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
|
||||||
|
|
||||||
protected Pool<IncomingPacket> m_incomingPacketPool;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Stat for number of packets in the main pool awaiting use.
|
|
||||||
/// </summary>
|
|
||||||
protected Stat m_poolCountStat;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Stat for number of packets in the inbound packet pool awaiting use.
|
|
||||||
/// </summary>
|
|
||||||
protected Stat m_incomingPacketPoolStat;
|
|
||||||
|
|
||||||
protected int m_defaultRTO = 0;
|
protected int m_defaultRTO = 0;
|
||||||
protected int m_maxRTO = 0;
|
protected int m_maxRTO = 0;
|
||||||
protected int m_ackTimeout = 0;
|
protected int m_ackTimeout = 0;
|
||||||
|
@ -452,7 +437,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
|
m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
|
||||||
sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
|
sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
|
||||||
|
|
||||||
PrimUpdatesPerCallback = config.GetInt("PrimUpdatesPerCallback", 100);
|
|
||||||
TextureSendLimit = config.GetInt("TextureSendLimit", 20);
|
TextureSendLimit = config.GetInt("TextureSendLimit", 20);
|
||||||
|
|
||||||
m_defaultRTO = config.GetInt("DefaultRTO", 0);
|
m_defaultRTO = config.GetInt("DefaultRTO", 0);
|
||||||
|
@ -463,7 +447,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PrimUpdatesPerCallback = 100;
|
|
||||||
TextureSendLimit = 20;
|
TextureSendLimit = 20;
|
||||||
m_ackTimeout = 1000 * 60; // 1 minute
|
m_ackTimeout = 1000 * 60; // 1 minute
|
||||||
m_pausedAckTimeout = 1000 * 300; // 5 minutes
|
m_pausedAckTimeout = 1000 * 300; // 5 minutes
|
||||||
|
@ -498,7 +481,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
// if (usePools)
|
// if (usePools)
|
||||||
// EnablePools();
|
// EnablePools();
|
||||||
base.DisablePools();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
|
@ -554,83 +536,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
OqrEngine.Stop();
|
OqrEngine.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool EnablePools()
|
|
||||||
{
|
|
||||||
if (!UsePools)
|
|
||||||
{
|
|
||||||
base.EnablePools();
|
|
||||||
|
|
||||||
m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool DisablePools()
|
|
||||||
{
|
|
||||||
if (UsePools)
|
|
||||||
{
|
|
||||||
base.DisablePools();
|
|
||||||
|
|
||||||
StatsManager.DeregisterStat(m_incomingPacketPoolStat);
|
|
||||||
|
|
||||||
// We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene
|
|
||||||
/// stats.
|
|
||||||
/// </summary>
|
|
||||||
protected internal void EnablePoolStats()
|
|
||||||
{
|
|
||||||
m_poolCountStat
|
|
||||||
= new Stat(
|
|
||||||
"UDPPacketBufferPoolCount",
|
|
||||||
"Objects within the UDPPacketBuffer pool",
|
|
||||||
"The number of objects currently stored within the UDPPacketBuffer pool",
|
|
||||||
"",
|
|
||||||
"clientstack",
|
|
||||||
Scene.Name,
|
|
||||||
StatType.Pull,
|
|
||||||
stat => stat.Value = Pool.Count,
|
|
||||||
StatVerbosity.Debug);
|
|
||||||
|
|
||||||
StatsManager.RegisterStat(m_poolCountStat);
|
|
||||||
|
|
||||||
m_incomingPacketPoolStat
|
|
||||||
= new Stat(
|
|
||||||
"IncomingPacketPoolCount",
|
|
||||||
"Objects within incoming packet pool",
|
|
||||||
"The number of objects currently stored within the incoming packet pool",
|
|
||||||
"",
|
|
||||||
"clientstack",
|
|
||||||
Scene.Name,
|
|
||||||
StatType.Pull,
|
|
||||||
stat => stat.Value = m_incomingPacketPool.Count,
|
|
||||||
StatVerbosity.Debug);
|
|
||||||
|
|
||||||
StatsManager.RegisterStat(m_incomingPacketPoolStat);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Disables pool stats.
|
|
||||||
/// </summary>
|
|
||||||
protected internal void DisablePoolStats()
|
|
||||||
{
|
|
||||||
StatsManager.DeregisterStat(m_poolCountStat);
|
|
||||||
m_poolCountStat = null;
|
|
||||||
|
|
||||||
StatsManager.DeregisterStat(m_incomingPacketPoolStat);
|
|
||||||
m_incomingPacketPoolStat = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
|
/// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -658,8 +563,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
string.Format("Incoming Packet Async Handling Engine ({0})", Scene.Name),
|
string.Format("Incoming Packet Async Handling Engine ({0})", Scene.Name),
|
||||||
"INCOMING PACKET ASYNC HANDLING ENGINE");
|
"INCOMING PACKET ASYNC HANDLING ENGINE");
|
||||||
*/
|
*/
|
||||||
OqrEngine
|
OqrEngine = new JobEngine(
|
||||||
= new JobEngine(
|
|
||||||
string.Format("Outgoing Queue Refill Engine ({0})", Scene.Name),
|
string.Format("Outgoing Queue Refill Engine ({0})", Scene.Name),
|
||||||
"OUTGOING QUEUE REFILL ENGINE");
|
"OUTGOING QUEUE REFILL ENGINE");
|
||||||
|
|
||||||
|
@ -769,15 +673,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
stat => stat.Value = OqrEngine.JobsWaiting,
|
stat => stat.Value = OqrEngine.JobsWaiting,
|
||||||
StatVerbosity.Debug));
|
StatVerbosity.Debug));
|
||||||
|
|
||||||
// We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by
|
StatsManager.RegisterStat(
|
||||||
// scene name
|
new Stat(
|
||||||
if (UsePools)
|
"UDPBuffersPoolCount",
|
||||||
EnablePoolStats();
|
"Buffers in the UDP buffers pool",
|
||||||
|
"The number of buffers currently stored within the UDP buffers pool",
|
||||||
|
"",
|
||||||
|
"clientstack",
|
||||||
|
Scene.Name,
|
||||||
|
StatType.Pull,
|
||||||
|
stat => stat.Value = m_udpBuffersPoolPtr + 1,
|
||||||
|
StatVerbosity.Debug));
|
||||||
|
|
||||||
LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this);
|
LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this);
|
||||||
commands.Register();
|
commands.Register();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HandlesRegion(Location x)
|
public bool HandlesRegion(Location x)
|
||||||
|
@ -939,9 +848,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting
|
// The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting
|
||||||
// there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here
|
// there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here
|
||||||
// to accomodate for both common scenarios and provide ample room for ACK appending in both
|
// to accomodate for both common scenarios and provide ample room for ACK appending in both
|
||||||
int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200;
|
//int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200;
|
||||||
|
|
||||||
UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize);
|
//UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize);
|
||||||
|
UDPPacketBuffer buffer = GetNewUDPBuffer(udpClient.RemoteEndPoint);
|
||||||
|
|
||||||
// Zerocode if needed
|
// Zerocode if needed
|
||||||
if (doZerocode)
|
if (doZerocode)
|
||||||
|
@ -971,7 +881,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// If the packet data wasn't already copied during zerocoding, copy it now
|
// If the packet data wasn't already copied during zerocoding, copy it now
|
||||||
if (doCopy)
|
if (doCopy)
|
||||||
{
|
{
|
||||||
if (dataLength <= buffer.Data.Length)
|
//if (dataLength <= buffer.Data.Length)
|
||||||
|
if (dataLength <= LLUDPServer.MTU)
|
||||||
{
|
{
|
||||||
Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
|
Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
|
||||||
}
|
}
|
||||||
|
@ -979,7 +890,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" +
|
m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" +
|
||||||
type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length);
|
type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length);
|
||||||
buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, dataLength);
|
// buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, dataLength);
|
||||||
|
buffer = GetNewUDPBuffer(udpClient.RemoteEndPoint);
|
||||||
Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
|
Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1017,6 +929,89 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
#endregion Queue or Send
|
#endregion Queue or Send
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public unsafe UDPPacketBuffer ZeroEncode(UDPPacketBuffer input)
|
||||||
|
{
|
||||||
|
UDPPacketBuffer zb = GetNewUDPBuffer(null);
|
||||||
|
int srclen = input.DataLength;
|
||||||
|
byte[] src = input.Data;
|
||||||
|
byte[] dest = zb.Data;
|
||||||
|
|
||||||
|
int zerolen = 6;
|
||||||
|
byte zerocount = 0;
|
||||||
|
|
||||||
|
for (int i = zerolen; i < srclen; i++)
|
||||||
|
{
|
||||||
|
if (src[i] == 0x00)
|
||||||
|
{
|
||||||
|
zerocount++;
|
||||||
|
if (zerocount == 0)
|
||||||
|
{
|
||||||
|
dest[zerolen++] = 0x00;
|
||||||
|
dest[zerolen++] = 0xff;
|
||||||
|
zerocount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (zerocount != 0)
|
||||||
|
{
|
||||||
|
dest[zerolen++] = 0x00;
|
||||||
|
dest[zerolen++] = zerocount;
|
||||||
|
zerocount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest[zerolen++] = src[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zerocount != 0)
|
||||||
|
{
|
||||||
|
dest[zerolen++] = 0x00;
|
||||||
|
dest[zerolen++] = zerocount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(zerolen >= srclen)
|
||||||
|
{
|
||||||
|
FreeUDPBuffer(zb);
|
||||||
|
|
||||||
|
src[0] &= unchecked((byte)~Helpers.MSG_ZEROCODED);
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer.BlockCopy(src, 0, dest, 0, 6);
|
||||||
|
|
||||||
|
zb.RemoteEndPoint = input.RemoteEndPoint;
|
||||||
|
zb.DataLength = zerolen;
|
||||||
|
|
||||||
|
FreeUDPBuffer(input);
|
||||||
|
|
||||||
|
return zb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendUDPPacket(
|
||||||
|
LLUDPClient udpClient, UDPPacketBuffer buffer, ThrottleOutPacketType category, UnackedPacketMethod method, bool forcequeue, bool zerocode)
|
||||||
|
{
|
||||||
|
bool highPriority = false;
|
||||||
|
|
||||||
|
if(zerocode)
|
||||||
|
buffer = ZeroEncode(buffer);
|
||||||
|
|
||||||
|
if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
|
||||||
|
{
|
||||||
|
category = (ThrottleOutPacketType)((int)category & 127);
|
||||||
|
highPriority = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
|
||||||
|
|
||||||
|
// If we were not provided a method for handling unacked, use the UDPServer default method
|
||||||
|
if ((outgoingPacket.Buffer.Data[0] & Helpers.MSG_RELIABLE) != 0)
|
||||||
|
outgoingPacket.UnackedMethod = ((method == null) ? delegate (OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
|
||||||
|
|
||||||
|
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forcequeue, highPriority))
|
||||||
|
SendPacketFinal(outgoingPacket);
|
||||||
|
}
|
||||||
|
|
||||||
public void SendAcks(LLUDPClient udpClient)
|
public void SendAcks(LLUDPClient udpClient)
|
||||||
{
|
{
|
||||||
uint ack;
|
uint ack;
|
||||||
|
@ -1066,7 +1061,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
LLUDPClient udpClient = client.UDPClient;
|
LLUDPClient udpClient = client.UDPClient;
|
||||||
|
|
||||||
if (!udpClient.IsConnected)
|
if (!client.IsActive || !udpClient.IsConnected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Disconnect an agent if no packets are received for some time
|
// Disconnect an agent if no packets are received for some time
|
||||||
|
@ -1136,14 +1131,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
internal void SendPacketFinal(OutgoingPacket outgoingPacket)
|
internal void SendPacketFinal(OutgoingPacket outgoingPacket)
|
||||||
{
|
{
|
||||||
UDPPacketBuffer buffer = outgoingPacket.Buffer;
|
UDPPacketBuffer buffer = outgoingPacket.Buffer;
|
||||||
|
if(buffer == null) // canceled packet
|
||||||
|
return;
|
||||||
|
LLUDPClient udpClient = outgoingPacket.Client;
|
||||||
|
if (!udpClient.IsConnected)
|
||||||
|
return;
|
||||||
|
|
||||||
byte flags = buffer.Data[0];
|
byte flags = buffer.Data[0];
|
||||||
bool isResend = (flags & Helpers.MSG_RESENT) != 0;
|
bool isResend = (flags & Helpers.MSG_RESENT) != 0;
|
||||||
bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0;
|
bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0;
|
||||||
bool isZerocoded = (flags & Helpers.MSG_ZEROCODED) != 0;
|
bool isZerocoded = (flags & Helpers.MSG_ZEROCODED) != 0;
|
||||||
LLUDPClient udpClient = outgoingPacket.Client;
|
|
||||||
|
|
||||||
if (!udpClient.IsConnected)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int dataLength = buffer.DataLength;
|
int dataLength = buffer.DataLength;
|
||||||
|
|
||||||
|
@ -1154,7 +1151,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// no more ACKs to append
|
// no more ACKs to append
|
||||||
int ackCount = 0;
|
int ackCount = 0;
|
||||||
uint ack;
|
uint ack;
|
||||||
while (dataLength + 5 < buffer.Data.Length && ackCount < 256 && udpClient.PendingAcks.Dequeue(out ack))
|
while (dataLength + 5 < MTU && ackCount < 256 && udpClient.PendingAcks.Dequeue(out ack))
|
||||||
{
|
{
|
||||||
Utils.UIntToBytesBig(ack, buffer.Data, dataLength);
|
Utils.UIntToBytesBig(ack, buffer.Data, dataLength);
|
||||||
dataLength += 4;
|
dataLength += 4;
|
||||||
|
@ -1168,9 +1165,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// Set the appended ACKs flag on this packet
|
// Set the appended ACKs flag on this packet
|
||||||
buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS);
|
buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
buffer.DataLength = dataLength;
|
buffer.DataLength = dataLength;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isResend)
|
if (!isResend)
|
||||||
{
|
{
|
||||||
|
@ -1178,12 +1174,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
uint sequenceNumber = (uint)Interlocked.Increment(ref udpClient.CurrentSequence);
|
uint sequenceNumber = (uint)Interlocked.Increment(ref udpClient.CurrentSequence);
|
||||||
Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1);
|
Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1);
|
||||||
outgoingPacket.SequenceNumber = sequenceNumber;
|
outgoingPacket.SequenceNumber = sequenceNumber;
|
||||||
|
|
||||||
if (isReliable)
|
|
||||||
{
|
|
||||||
// Add this packet to the list of ACK responses we are waiting on from the server
|
|
||||||
udpClient.NeedAcks.Add(outgoingPacket);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1196,9 +1186,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
PacketsSentCount++;
|
PacketsSentCount++;
|
||||||
|
|
||||||
SyncSend(buffer);
|
SyncSend(buffer);
|
||||||
|
|
||||||
// Keep track of when this packet was sent out (right now)
|
// Keep track of when this packet was sent out (right now)
|
||||||
outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
|
outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
|
||||||
|
|
||||||
|
if (outgoingPacket.UnackedMethod == null)
|
||||||
|
FreeUDPBuffer(buffer);
|
||||||
|
else if(!isResend)
|
||||||
|
{
|
||||||
|
// Add this packet to the list of ACK responses we are waiting on from the server
|
||||||
|
udpClient.NeedAcks.Add(outgoingPacket);
|
||||||
|
}
|
||||||
|
|
||||||
if (udpClient.DebugDataOutLevel > 0)
|
if (udpClient.DebugDataOutLevel > 0)
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[LLUDPSERVER]: Sending packet #{0} (rel: {1}, res: {2}) to {3} from {4}",
|
"[LLUDPSERVER]: Sending packet #{0} (rel: {1}, res: {2}) to {3} from {4}",
|
||||||
|
@ -1240,7 +1239,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
|
// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
RecordMalformedInboundPacket(endPoint);
|
RecordMalformedInboundPacket(endPoint);
|
||||||
|
FreeUDPBuffer(buffer);
|
||||||
return; // Drop undersized packet
|
return; // Drop undersized packet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1260,21 +1259,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
|
// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
RecordMalformedInboundPacket(endPoint);
|
RecordMalformedInboundPacket(endPoint);
|
||||||
|
FreeUDPBuffer(buffer);
|
||||||
return; // Malformed header
|
return; // Malformed header
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
|
// get a buffer for zero decode using the udp buffers pool
|
||||||
// // Only allocate a buffer for zerodecoding if the packet is zerocoded
|
UDPPacketBuffer zerodecodebufferholder = null;
|
||||||
// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
|
byte[] zerodecodebuffer = null;
|
||||||
|
// only if needed
|
||||||
|
if (((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0))
|
||||||
|
{
|
||||||
|
zerodecodebufferholder = GetNewUDPBuffer(null);
|
||||||
|
zerodecodebuffer = zerodecodebufferholder.Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
packet = Packet.BuildPacket(buffer.Data, ref packetEnd, zerodecodebuffer);
|
||||||
// If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we
|
// If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we
|
||||||
// assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all
|
// assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all
|
||||||
// bytes are copied out).
|
// bytes are copied out).
|
||||||
packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd,
|
// packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, zerodecodebuffer);
|
||||||
// Only allocate a buffer for zerodecoding if the packet is zerocoded
|
if(zerodecodebufferholder != null)
|
||||||
((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
|
FreeUDPBuffer(zerodecodebufferholder);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -1292,7 +1299,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordMalformedInboundPacket(endPoint);
|
RecordMalformedInboundPacket(endPoint);
|
||||||
|
FreeUDPBuffer(buffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1311,17 +1318,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
lock (m_pendingCache)
|
lock (m_pendingCache)
|
||||||
{
|
{
|
||||||
if (m_pendingCache.Contains(endPoint))
|
if (m_pendingCache.Contains(endPoint))
|
||||||
|
{
|
||||||
|
FreeUDPBuffer(buffer);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
|
m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to copy the endpoint so that it doesn't get changed when another thread reuses the
|
Util.FireAndForget(HandleUseCircuitCode, new object[] { endPoint, packet });
|
||||||
// buffer.
|
FreeUDPBuffer(buffer);
|
||||||
object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
|
|
||||||
|
|
||||||
Util.FireAndForget(HandleUseCircuitCode, array);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1336,24 +1342,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
queue.Enqueue(buffer);
|
queue.Enqueue(buffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
else if (packet.Type == PacketType.CompleteAgentMovement)
|
|
||||||
{
|
|
||||||
// Send ack straight away to let the viewer know that we got it.
|
|
||||||
SendAckImmediate(endPoint, packet.Header.Sequence);
|
|
||||||
|
|
||||||
// We need to copy the endpoint so that it doesn't get changed when another thread reuses the
|
|
||||||
// buffer.
|
|
||||||
object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
|
|
||||||
|
|
||||||
Util.FireAndForget(HandleCompleteMovementIntoRegion, array);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FreeUDPBuffer(buffer);
|
||||||
|
|
||||||
// Determine which agent this packet came from
|
// Determine which agent this packet came from
|
||||||
if (client == null || !(client is LLClientView))
|
if (client == null || !(client is LLClientView))
|
||||||
{
|
{
|
||||||
|
@ -1471,10 +1463,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length);
|
LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length);
|
||||||
#endregion BinaryStats
|
#endregion BinaryStats
|
||||||
|
|
||||||
|
|
||||||
//AgentUpdate removed from here
|
|
||||||
|
|
||||||
|
|
||||||
#region Ping Check Handling
|
#region Ping Check Handling
|
||||||
|
|
||||||
if (packet.Type == PacketType.StartPingCheck)
|
if (packet.Type == PacketType.StartPingCheck)
|
||||||
|
@ -1506,17 +1494,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
IncomingPacket incomingPacket;
|
IncomingPacket incomingPacket;
|
||||||
|
|
||||||
// Inbox insertion
|
|
||||||
if (UsePools)
|
|
||||||
{
|
|
||||||
incomingPacket = m_incomingPacketPool.GetObject();
|
|
||||||
incomingPacket.Client = (LLClientView)client;
|
|
||||||
incomingPacket.Packet = packet;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
incomingPacket = new IncomingPacket((LLClientView)client, packet);
|
incomingPacket = new IncomingPacket((LLClientView)client, packet);
|
||||||
}
|
|
||||||
|
|
||||||
// if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
|
// if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
|
||||||
// incomingPacket.Packet.Type == PacketType.ChatFromViewer)
|
// incomingPacket.Packet.Type == PacketType.ChatFromViewer)
|
||||||
|
@ -1525,7 +1503,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// else
|
// else
|
||||||
// packetInbox.Enqueue(incomingPacket);
|
// packetInbox.Enqueue(incomingPacket);
|
||||||
packetInbox.Add(incomingPacket);
|
packetInbox.Add(incomingPacket);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region BinaryStats
|
#region BinaryStats
|
||||||
|
@ -1685,7 +1662,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
|
m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
m_pendingCache.Remove(endPoint);
|
m_pendingCache.Remove(endPoint);
|
||||||
}
|
}
|
||||||
|
@ -1881,13 +1857,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
byte[] packetData = ack.ToBytes();
|
byte[] packetData = ack.ToBytes();
|
||||||
int length = packetData.Length;
|
int length = packetData.Length;
|
||||||
|
|
||||||
UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length);
|
UDPPacketBuffer buffer = GetNewUDPBuffer(remoteEndpoint);
|
||||||
buffer.DataLength = length;
|
buffer.DataLength = length;
|
||||||
|
|
||||||
Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);
|
Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);
|
||||||
|
|
||||||
// AsyncBeginSend(buffer);
|
// AsyncBeginSend(buffer);
|
||||||
SyncSend(buffer);
|
SyncSend(buffer);
|
||||||
|
FreeUDPBuffer(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo)
|
protected bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo)
|
||||||
|
@ -1982,20 +1959,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
Scene.ThreadAlive(1);
|
Scene.ThreadAlive(1);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
packetInbox.TryTake(out incomingPacket, 250);
|
packetInbox.TryTake(out incomingPacket, 4500);
|
||||||
|
|
||||||
if (incomingPacket != null && IsRunningInbound)
|
if (incomingPacket != null && IsRunningInbound)
|
||||||
{
|
{
|
||||||
ProcessInPacket(incomingPacket);
|
ProcessInPacket(incomingPacket);
|
||||||
|
|
||||||
if (UsePools)
|
|
||||||
{
|
|
||||||
incomingPacket.Client = null;
|
|
||||||
m_incomingPacketPool.ReturnObject(incomingPacket);
|
|
||||||
}
|
|
||||||
incomingPacket = null;
|
incomingPacket = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (ThreadAbortException)
|
||||||
|
{
|
||||||
|
Thread.ResetAbort();
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
m_log.Error("[LLUDPSERVER]: Error in the incoming packet handler loop: " + ex.Message, ex);
|
m_log.Error("[LLUDPSERVER]: Error in the incoming packet handler loop: " + ex.Message, ex);
|
||||||
|
@ -2025,7 +2000,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
Scene.ThreadAlive(2);
|
Scene.ThreadAlive(2);
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_packetSent = false;
|
m_packetSent = false;
|
||||||
|
@ -2080,7 +2054,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
else if (!m_packetSent)
|
else if (!m_packetSent)
|
||||||
// Thread.Sleep((int)TickCountResolution); outch this is bad on linux
|
// Thread.Sleep((int)TickCountResolution); outch this is bad on linux
|
||||||
Thread.Sleep(15); // match the 16ms of windows7, dont ask 16 or win may decide to do 32ms.
|
Thread.Sleep(15); // match the 16ms of windows, dont ask 16 or win may decide to do 32ms.
|
||||||
|
|
||||||
Watchdog.UpdateThread();
|
Watchdog.UpdateThread();
|
||||||
}
|
}
|
||||||
|
@ -2104,14 +2078,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
if (udpClient.IsConnected)
|
if (udpClient.IsConnected)
|
||||||
{
|
{
|
||||||
if (m_resendUnacked)
|
if (client.IsActive && m_resendUnacked)
|
||||||
HandleUnacked(llClient);
|
HandleUnacked(llClient);
|
||||||
|
|
||||||
|
if (client.IsActive)
|
||||||
|
{
|
||||||
if (m_sendAcks)
|
if (m_sendAcks)
|
||||||
SendAcks(udpClient);
|
SendAcks(udpClient);
|
||||||
|
|
||||||
if (m_sendPing)
|
if (m_sendPing)
|
||||||
SendPing(udpClient);
|
SendPing(udpClient);
|
||||||
|
}
|
||||||
|
|
||||||
// Dequeue any outgoing packets that are within the throttle limits
|
// Dequeue any outgoing packets that are within the throttle limits
|
||||||
if (udpClient.DequeueOutgoing())
|
if (udpClient.DequeueOutgoing())
|
||||||
|
@ -2124,7 +2101,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_log.Error(
|
m_log.Error(
|
||||||
string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex);
|
string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex);
|
||||||
}
|
}
|
||||||
client = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Emergency Monitoring
|
#region Emergency Monitoring
|
||||||
|
|
|
@ -777,41 +777,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_udpServer.StopOutbound();
|
m_udpServer.StopOutbound();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandlePoolCommand(string module, string[] args)
|
|
||||||
{
|
|
||||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (args.Length != 4)
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string enabled = args[3];
|
|
||||||
|
|
||||||
if (enabled == "on")
|
|
||||||
{
|
|
||||||
if (m_udpServer.EnablePools())
|
|
||||||
{
|
|
||||||
m_udpServer.EnablePoolStats();
|
|
||||||
MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_udpServer.Scene.Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (enabled == "off")
|
|
||||||
{
|
|
||||||
if (m_udpServer.DisablePools())
|
|
||||||
{
|
|
||||||
m_udpServer.DisablePoolStats();
|
|
||||||
MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_udpServer.Scene.Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleAgentUpdateCommand(string module, string[] args)
|
private void HandleAgentUpdateCommand(string module, string[] args)
|
||||||
{
|
{
|
||||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||||
|
@ -834,8 +799,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
MainConsole.Instance.OutputFormat(
|
MainConsole.Instance.OutputFormat(
|
||||||
"OUT LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningOutbound ? "enabled" : "disabled");
|
"OUT LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningOutbound ? "enabled" : "disabled");
|
||||||
|
|
||||||
MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_udpServer.Scene.Name, m_udpServer.UsePools ? "on" : "off");
|
|
||||||
|
|
||||||
MainConsole.Instance.OutputFormat(
|
MainConsole.Instance.OutputFormat(
|
||||||
"Packet debug level for new clients is {0}", m_udpServer.DefaultClientPacketDebugLevel);
|
"Packet debug level for new clients is {0}", m_udpServer.DefaultClientPacketDebugLevel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,279 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim.Framework;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
{
|
||||||
|
public sealed class LLUDPZeroEncoder
|
||||||
|
{
|
||||||
|
private byte[] m_tmp = new byte[16];
|
||||||
|
private byte[] m_dest;
|
||||||
|
private int zerocount;
|
||||||
|
private int pos;
|
||||||
|
|
||||||
|
public LLUDPZeroEncoder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public LLUDPZeroEncoder(byte[] data)
|
||||||
|
{
|
||||||
|
m_dest = data;
|
||||||
|
zerocount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] Data
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_dest;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_dest = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ZeroCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return zerocount;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
zerocount = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Position
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
pos = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe void AddZeros(int len)
|
||||||
|
{
|
||||||
|
zerocount += len;
|
||||||
|
while (zerocount > 255)
|
||||||
|
{
|
||||||
|
m_dest[pos++] = 0x00;
|
||||||
|
m_dest[pos++] = 0xff;
|
||||||
|
zerocount -= 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe int Finish()
|
||||||
|
{
|
||||||
|
if(zerocount > 0)
|
||||||
|
{
|
||||||
|
m_dest[pos++] = 0x00;
|
||||||
|
m_dest[pos++] = (byte)zerocount;
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe void AddBytes(byte[] src, int srclen)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < srclen; ++i)
|
||||||
|
{
|
||||||
|
if (src[i] == 0x00)
|
||||||
|
{
|
||||||
|
zerocount++;
|
||||||
|
if (zerocount == 0)
|
||||||
|
{
|
||||||
|
m_dest[pos++] = 0x00;
|
||||||
|
m_dest[pos++] = 0xff;
|
||||||
|
zerocount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (zerocount != 0)
|
||||||
|
{
|
||||||
|
m_dest[pos++] = 0x00;
|
||||||
|
m_dest[pos++] = (byte)zerocount;
|
||||||
|
zerocount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dest[pos++] = src[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe void AddByte(byte v)
|
||||||
|
{
|
||||||
|
if (v == 0x00)
|
||||||
|
{
|
||||||
|
zerocount++;
|
||||||
|
if (zerocount == 0)
|
||||||
|
{
|
||||||
|
m_dest[pos++] = 0x00;
|
||||||
|
m_dest[pos++] = 0xff;
|
||||||
|
zerocount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (zerocount != 0)
|
||||||
|
{
|
||||||
|
m_dest[pos++] = 0x00;
|
||||||
|
m_dest[pos++] = (byte)zerocount;
|
||||||
|
zerocount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dest[pos++] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddInt16(short v)
|
||||||
|
{
|
||||||
|
if (v == 0)
|
||||||
|
AddZeros(2);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Utils.Int16ToBytes(v, m_tmp, 0);
|
||||||
|
AddBytes(m_tmp, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddUInt16(ushort v)
|
||||||
|
{
|
||||||
|
if (v == 0)
|
||||||
|
AddZeros(2);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Utils.UInt16ToBytes(v, m_tmp, 0);
|
||||||
|
AddBytes(m_tmp, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddInt(int v)
|
||||||
|
{
|
||||||
|
if (v == 0)
|
||||||
|
AddZeros(4);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Utils.IntToBytesSafepos(v, m_tmp, 0);
|
||||||
|
AddBytes(m_tmp, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe void AddUInt(uint v)
|
||||||
|
{
|
||||||
|
if (v == 0)
|
||||||
|
AddZeros(4);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Utils.UIntToBytesSafepos(v, m_tmp, 0);
|
||||||
|
AddBytes(m_tmp, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddFloatToUInt16(float v, float range)
|
||||||
|
{
|
||||||
|
Utils.FloatToUInt16Bytes(v, range, m_tmp, 0);
|
||||||
|
AddBytes(m_tmp, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddFloat(float v)
|
||||||
|
{
|
||||||
|
if (v == 0f)
|
||||||
|
AddZeros(4);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Utils.FloatToBytesSafepos(v, m_tmp, 0);
|
||||||
|
AddBytes(m_tmp, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddInt64(long v)
|
||||||
|
{
|
||||||
|
if (v == 0)
|
||||||
|
AddZeros(8);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Utils.Int64ToBytesSafepos(v, m_tmp, 0);
|
||||||
|
AddBytes(m_tmp, 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddUInt64(ulong v)
|
||||||
|
{
|
||||||
|
if (v == 0)
|
||||||
|
AddZeros(8);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Utils.UInt64ToBytesSafepos(v, m_tmp, 0);
|
||||||
|
AddBytes(m_tmp, 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddVector3(Vector3 v)
|
||||||
|
{
|
||||||
|
if (v == Vector3.Zero)
|
||||||
|
AddZeros(12);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v.ToBytes(m_tmp, 0);
|
||||||
|
AddBytes(m_tmp, 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddVector4(Vector4 v)
|
||||||
|
{
|
||||||
|
if (v == Vector4.Zero)
|
||||||
|
AddZeros(16);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v.ToBytes(m_tmp, 0);
|
||||||
|
AddBytes(m_tmp, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddNormQuat(Quaternion v)
|
||||||
|
{
|
||||||
|
v.ToBytes(m_tmp, 0);
|
||||||
|
AddBytes(m_tmp, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddUUID(UUID v)
|
||||||
|
{
|
||||||
|
v.ToBytes(m_tmp, 0);
|
||||||
|
AddBytes(m_tmp, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,6 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -57,15 +58,9 @@ namespace OpenMetaverse
|
||||||
/// <summary>UDP socket, used in either client or server mode</summary>
|
/// <summary>UDP socket, used in either client or server mode</summary>
|
||||||
private Socket m_udpSocket;
|
private Socket m_udpSocket;
|
||||||
|
|
||||||
/// <summary>
|
public static Object m_udpBuffersPoolLock = new Object();
|
||||||
/// Are we to use object pool(s) to reduce memory churn when receiving data?
|
public static UDPPacketBuffer[] m_udpBuffersPool = new UDPPacketBuffer[1000];
|
||||||
/// </summary>
|
public static int m_udpBuffersPoolPtr = -1;
|
||||||
public bool UsePools { get; protected set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Pool to use for handling data. May be null if UsePools = false;
|
|
||||||
/// </summary>
|
|
||||||
protected OpenSim.Framework.Pool<UDPPacketBuffer> Pool { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary>
|
/// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary>
|
||||||
public bool IsRunningInbound { get; private set; }
|
public bool IsRunningInbound { get; private set; }
|
||||||
|
@ -186,6 +181,37 @@ namespace OpenMetaverse
|
||||||
if(m_udpSocket !=null)
|
if(m_udpSocket !=null)
|
||||||
try { m_udpSocket.Close(); } catch { }
|
try { m_udpSocket.Close(); } catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UDPPacketBuffer GetNewUDPBuffer(IPEndPoint remoteEndpoint)
|
||||||
|
{
|
||||||
|
lock (m_udpBuffersPoolLock)
|
||||||
|
{
|
||||||
|
if (m_udpBuffersPoolPtr >= 0)
|
||||||
|
{
|
||||||
|
UDPPacketBuffer buf = m_udpBuffersPool[m_udpBuffersPoolPtr];
|
||||||
|
m_udpBuffersPool[m_udpBuffersPoolPtr] = null;
|
||||||
|
m_udpBuffersPoolPtr--;
|
||||||
|
buf.RemoteEndPoint = remoteEndpoint;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new UDPPacketBuffer(remoteEndpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FreeUDPBuffer(UDPPacketBuffer buf)
|
||||||
|
{
|
||||||
|
lock (m_udpBuffersPoolLock)
|
||||||
|
{
|
||||||
|
if (m_udpBuffersPoolPtr < 999)
|
||||||
|
{
|
||||||
|
buf.RemoteEndPoint = null;
|
||||||
|
buf.DataLength = 0;
|
||||||
|
m_udpBuffersPoolPtr++;
|
||||||
|
m_udpBuffersPool[m_udpBuffersPoolPtr] = buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start inbound UDP packet handling.
|
/// Start inbound UDP packet handling.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -202,6 +228,7 @@ namespace OpenMetaverse
|
||||||
/// manner (not throwing an exception when the remote side resets the
|
/// manner (not throwing an exception when the remote side resets the
|
||||||
/// connection). This call is ignored on Mono where the flag is not
|
/// connection). This call is ignored on Mono where the flag is not
|
||||||
/// necessary</remarks>
|
/// necessary</remarks>
|
||||||
|
|
||||||
public virtual void StartInbound(int recvBufferSize)
|
public virtual void StartInbound(int recvBufferSize)
|
||||||
{
|
{
|
||||||
if (!IsRunningInbound)
|
if (!IsRunningInbound)
|
||||||
|
@ -306,60 +333,22 @@ namespace OpenMetaverse
|
||||||
IsRunningOutbound = false;
|
IsRunningOutbound = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool EnablePools()
|
|
||||||
{
|
|
||||||
if (!UsePools)
|
|
||||||
{
|
|
||||||
Pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500);
|
|
||||||
|
|
||||||
UsePools = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool DisablePools()
|
|
||||||
{
|
|
||||||
if (UsePools)
|
|
||||||
{
|
|
||||||
UsePools = false;
|
|
||||||
|
|
||||||
// We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AsyncBeginReceive()
|
private void AsyncBeginReceive()
|
||||||
{
|
{
|
||||||
UDPPacketBuffer buf;
|
if (!IsRunningInbound)
|
||||||
|
return;
|
||||||
|
|
||||||
// FIXME: Disabled for now as this causes issues with reused packet objects interfering with each other
|
UDPPacketBuffer buf = GetNewUDPBuffer(new IPEndPoint(IPAddress.Any, 0)); // we need a fresh one here, for now at least
|
||||||
// on Windows with m_asyncPacketHandling = true, though this has not been seen on Linux.
|
|
||||||
// Possibly some unexpected issue with fetching UDP data concurrently with multiple threads. Requires more investigation.
|
|
||||||
// if (UsePools)
|
|
||||||
// buf = Pool.GetObject();
|
|
||||||
// else
|
|
||||||
buf = new UDPPacketBuffer();
|
|
||||||
|
|
||||||
if (IsRunningInbound)
|
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// kick off an async read
|
// kick off an async read
|
||||||
m_udpSocket.BeginReceiveFrom(
|
m_udpSocket.BeginReceiveFrom(
|
||||||
//wrappedBuffer.Instance.Data,
|
|
||||||
buf.Data,
|
buf.Data,
|
||||||
0,
|
0,
|
||||||
UDPPacketBuffer.BUFFER_SIZE,
|
buf.Data.Length,
|
||||||
SocketFlags.None,
|
SocketFlags.None,
|
||||||
ref buf.RemoteEndPoint,
|
ref buf.RemoteEndPoint,
|
||||||
AsyncEndReceive,
|
AsyncEndReceive,
|
||||||
//wrappedBuffer);
|
|
||||||
buf);
|
buf);
|
||||||
}
|
}
|
||||||
catch (SocketException e)
|
catch (SocketException e)
|
||||||
|
@ -373,14 +362,12 @@ namespace OpenMetaverse
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_udpSocket.BeginReceiveFrom(
|
m_udpSocket.BeginReceiveFrom(
|
||||||
//wrappedBuffer.Instance.Data,
|
|
||||||
buf.Data,
|
buf.Data,
|
||||||
0,
|
0,
|
||||||
UDPPacketBuffer.BUFFER_SIZE,
|
buf.Data.Length,
|
||||||
SocketFlags.None,
|
SocketFlags.None,
|
||||||
ref buf.RemoteEndPoint,
|
ref buf.RemoteEndPoint,
|
||||||
AsyncEndReceive,
|
AsyncEndReceive,
|
||||||
//wrappedBuffer);
|
|
||||||
buf);
|
buf);
|
||||||
salvaged = true;
|
salvaged = true;
|
||||||
}
|
}
|
||||||
|
@ -391,18 +378,12 @@ namespace OpenMetaverse
|
||||||
m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort);
|
m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ObjectDisposedException e)
|
|
||||||
{
|
|
||||||
m_log.Error(
|
|
||||||
string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error(
|
m_log.Error(
|
||||||
string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e);
|
string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void AsyncEndReceive(IAsyncResult iar)
|
private void AsyncEndReceive(IAsyncResult iar)
|
||||||
{
|
{
|
||||||
|
@ -453,11 +434,6 @@ namespace OpenMetaverse
|
||||||
UdpReceives, se.ErrorCode),
|
UdpReceives, se.ErrorCode),
|
||||||
se);
|
se);
|
||||||
}
|
}
|
||||||
catch (ObjectDisposedException e)
|
|
||||||
{
|
|
||||||
m_log.Error(
|
|
||||||
string.Format("[UDPBASE]: Error processing UDP end receive {0}. Exception ", UdpReceives), e);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error(
|
m_log.Error(
|
||||||
|
@ -465,14 +441,12 @@ namespace OpenMetaverse
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// if (UsePools)
|
|
||||||
// Pool.ReturnObject(buffer);
|
|
||||||
|
|
||||||
AsyncBeginReceive();
|
AsyncBeginReceive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* not in use
|
||||||
public void AsyncBeginSend(UDPPacketBuffer buf)
|
public void AsyncBeginSend(UDPPacketBuffer buf)
|
||||||
{
|
{
|
||||||
// if (IsRunningOutbound)
|
// if (IsRunningOutbound)
|
||||||
|
@ -511,9 +485,11 @@ namespace OpenMetaverse
|
||||||
catch (SocketException) { }
|
catch (SocketException) { }
|
||||||
catch (ObjectDisposedException) { }
|
catch (ObjectDisposedException) { }
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
public void SyncSend(UDPPacketBuffer buf)
|
public void SyncSend(UDPPacketBuffer buf)
|
||||||
{
|
{
|
||||||
|
if(buf.RemoteEndPoint == null)
|
||||||
|
return; // already expired
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_udpSocket.SendTo(
|
m_udpSocket.SendTo(
|
||||||
|
@ -527,7 +503,7 @@ namespace OpenMetaverse
|
||||||
}
|
}
|
||||||
catch (SocketException e)
|
catch (SocketException e)
|
||||||
{
|
{
|
||||||
m_log.Warn("[UDPBASE]: sync send SocketException {0} " + e.Message);
|
m_log.WarnFormat("[UDPBASE]: sync send SocketException {0} {1}", buf.RemoteEndPoint, e.Message);
|
||||||
}
|
}
|
||||||
catch (ObjectDisposedException) { }
|
catch (ObjectDisposedException) { }
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,9 +66,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Int64 MinimumAdaptiveThrottleRate;
|
public Int64 MinimumAdaptiveThrottleRate;
|
||||||
|
|
||||||
/// <summary>Amount of the texture throttle to steal for the task throttle</summary>
|
|
||||||
public double CannibalizeTextureRate;
|
|
||||||
|
|
||||||
public int ClientMaxRate;
|
public int ClientMaxRate;
|
||||||
public float BrustTime;
|
public float BrustTime;
|
||||||
|
|
||||||
|
@ -104,12 +101,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// AdaptiveThrottlesEnabled = throttleConfig.GetBoolean("enable_adaptive_throttles", false);
|
// AdaptiveThrottlesEnabled = throttleConfig.GetBoolean("enable_adaptive_throttles", false);
|
||||||
AdaptiveThrottlesEnabled = false;
|
AdaptiveThrottlesEnabled = false;
|
||||||
MinimumAdaptiveThrottleRate = throttleConfig.GetInt("adaptive_throttle_min_bps", 32000);
|
MinimumAdaptiveThrottleRate = throttleConfig.GetInt("adaptive_throttle_min_bps", 32000);
|
||||||
|
|
||||||
// http textures do use udp bandwidth setting
|
|
||||||
// CannibalizeTextureRate = (double)throttleConfig.GetFloat("CannibalizeTextureRate", 0.0f);
|
|
||||||
// CannibalizeTextureRate = Util.Clamp<double>(CannibalizeTextureRate,0.0, 0.9);
|
|
||||||
CannibalizeTextureRate = 0f;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception) { }
|
catch (Exception) { }
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,8 +189,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// Process all the pending adds
|
// Process all the pending adds
|
||||||
OutgoingPacket pendingAdd;
|
OutgoingPacket pendingAdd;
|
||||||
while (m_pendingAdds.TryDequeue(out pendingAdd))
|
while (m_pendingAdds.TryDequeue(out pendingAdd))
|
||||||
|
{
|
||||||
if (pendingAdd != null)
|
if (pendingAdd != null)
|
||||||
m_packets[pendingAdd.SequenceNumber] = pendingAdd;
|
m_packets[pendingAdd.SequenceNumber] = pendingAdd;
|
||||||
|
}
|
||||||
|
|
||||||
// Process all the pending removes, including updating statistics and round-trip times
|
// Process all the pending removes, including updating statistics and round-trip times
|
||||||
PendingAck pendingAcknowledgement;
|
PendingAck pendingAcknowledgement;
|
||||||
|
@ -204,13 +206,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
m_packets.Remove(pendingAcknowledgement.SequenceNumber);
|
m_packets.Remove(pendingAcknowledgement.SequenceNumber);
|
||||||
|
|
||||||
|
// Update stats
|
||||||
|
Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength);
|
||||||
|
|
||||||
|
ackedPacket.Client.FreeUDPBuffer(ackedPacket.Buffer);
|
||||||
|
ackedPacket.Buffer = null;
|
||||||
|
|
||||||
// As with other network applications, assume that an acknowledged packet is an
|
// As with other network applications, assume that an acknowledged packet is an
|
||||||
// indication that the network can handle a little more load, speed up the transmission
|
// indication that the network can handle a little more load, speed up the transmission
|
||||||
ackedPacket.Client.FlowThrottle.AcknowledgePackets(1);
|
ackedPacket.Client.FlowThrottle.AcknowledgePackets(1);
|
||||||
|
|
||||||
// Update stats
|
|
||||||
Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength);
|
|
||||||
|
|
||||||
if (!pendingAcknowledgement.FromResend)
|
if (!pendingAcknowledgement.FromResend)
|
||||||
{
|
{
|
||||||
// Calculate the round-trip time for this packet and its ACK
|
// Calculate the round-trip time for this packet and its ACK
|
||||||
|
@ -244,6 +249,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
// Update stats
|
// Update stats
|
||||||
Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength);
|
Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength);
|
||||||
|
|
||||||
|
removedPacket.Client.FreeUDPBuffer(removedPacket.Buffer);
|
||||||
|
removedPacket.Buffer = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -953,13 +953,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Saving attachments for NPCs messes them up for the real owner!
|
if(sp.IsNPC)
|
||||||
INPCModule module = m_scene.RequestModuleInterface<INPCModule>();
|
|
||||||
if (module != null)
|
|
||||||
{
|
|
||||||
if (module.IsNPC(sp.UUID, m_scene))
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (grp.HasGroupChanged)
|
if (grp.HasGroupChanged)
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,7 +77,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.EventManager.OnAvatarKilled += KillAvatar;
|
scene.EventManager.OnAvatarKilled += KillAvatar;
|
||||||
scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
public void RemoveRegion(Scene scene)
|
||||||
|
@ -86,7 +85,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
|
||||||
m_scenel.Remove(scene.RegionInfo.RegionHandle);
|
m_scenel.Remove(scene.RegionInfo.RegionHandle);
|
||||||
|
|
||||||
scene.EventManager.OnAvatarKilled -= KillAvatar;
|
scene.EventManager.OnAvatarKilled -= KillAvatar;
|
||||||
scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegionLoaded(Scene scene)
|
public void RegionLoaded(Scene scene)
|
||||||
|
@ -177,31 +175,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
|
||||||
deadAvatar.setHealthWithUpdate(100.0f);
|
deadAvatar.setHealthWithUpdate(100.0f);
|
||||||
deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient);
|
deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, UUID regionID)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
|
|
||||||
if (obj == null)
|
|
||||||
return;
|
|
||||||
if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0
|
|
||||||
|| avatar.Scene.RegionInfo.RegionSettings.AllowDamage)
|
|
||||||
{
|
|
||||||
avatar.Invulnerable = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
avatar.Invulnerable = true;
|
|
||||||
if (avatar.Health < 100.0f)
|
|
||||||
{
|
|
||||||
avatar.setHealthWithUpdate(100.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -526,16 +526,23 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
item.AssetType = (int)AssetType.Object;
|
item.AssetType = (int)AssetType.Object;
|
||||||
item.AssetID = asset.FullID;
|
item.AssetID = asset.FullID;
|
||||||
|
|
||||||
if (DeRezAction.SaveToExistingUserInventoryItem == action)
|
if (action == DeRezAction.SaveToExistingUserInventoryItem)
|
||||||
{
|
{
|
||||||
m_Scene.InventoryService.UpdateItem(item);
|
m_Scene.InventoryService.UpdateItem(item);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
bool isowner = remoteClient != null && item.Owner == remoteClient.AgentId;
|
||||||
|
if(action == DeRezAction.Return)
|
||||||
|
AddPermissions(item, objlist[0], objlist, null);
|
||||||
|
else if(action == DeRezAction.Delete && !isowner)
|
||||||
|
AddPermissions(item, objlist[0], objlist, null);
|
||||||
|
else
|
||||||
AddPermissions(item, objlist[0], objlist, remoteClient);
|
AddPermissions(item, objlist[0], objlist, remoteClient);
|
||||||
|
|
||||||
m_Scene.AddInventoryItem(item);
|
m_Scene.AddInventoryItem(item);
|
||||||
|
|
||||||
if (remoteClient != null && item.Owner == remoteClient.AgentId)
|
if (isowner)
|
||||||
{
|
{
|
||||||
remoteClient.SendInventoryItemCreateUpdate(item, 0);
|
remoteClient.SendInventoryItemCreateUpdate(item, 0);
|
||||||
}
|
}
|
||||||
|
@ -1010,7 +1017,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
|
group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
|
||||||
rootPart.ParentGroup.ResumeScripts();
|
rootPart.ParentGroup.ResumeScripts();
|
||||||
|
|
||||||
group.ScheduleGroupForFullUpdate();
|
group.ScheduleGroupForFullAnimUpdate();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_Scene.AddNewSceneObject(group, true, false);
|
m_Scene.AddNewSceneObject(group, true, false);
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Mail;
|
using System.Net.Mail;
|
||||||
|
@ -94,18 +95,31 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private object HttpListLock = new object();
|
private object m_httpListLock = new object();
|
||||||
private int httpTimeout = 30000;
|
private int m_httpTimeout = 30000;
|
||||||
private string m_name = "HttpScriptRequests";
|
private string m_name = "HttpScriptRequests";
|
||||||
|
|
||||||
private OutboundUrlFilter m_outboundUrlFilter;
|
private OutboundUrlFilter m_outboundUrlFilter;
|
||||||
private string m_proxyurl = "";
|
private string m_proxyurl = "";
|
||||||
private string m_proxyexcepts = "";
|
private string m_proxyexcepts = "";
|
||||||
|
|
||||||
|
private float m_primPerSec = 1.0f;
|
||||||
|
private float m_primBurst = 3.0f;
|
||||||
|
private float m_primOwnerPerSec = 25.0f;
|
||||||
|
private float m_primOwnerBurst = 5.0f;
|
||||||
|
|
||||||
|
private struct ThrottleData
|
||||||
|
{
|
||||||
|
public double lastTime;
|
||||||
|
public float count;
|
||||||
|
}
|
||||||
|
|
||||||
// <request id, HttpRequestClass>
|
// <request id, HttpRequestClass>
|
||||||
private Dictionary<UUID, HttpRequestClass> m_pendingRequests;
|
private Dictionary<UUID, HttpRequestClass> m_pendingRequests;
|
||||||
private Scene m_scene;
|
private ConcurrentQueue<HttpRequestClass> m_CompletedRequests;
|
||||||
// private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>();
|
private ConcurrentDictionary<uint, ThrottleData> m_RequestsThrottle;
|
||||||
|
private ConcurrentDictionary<UUID, ThrottleData> m_OwnerRequestsThrottle;
|
||||||
|
|
||||||
public static SmartThreadPool ThreadPool = null;
|
public static SmartThreadPool ThreadPool = null;
|
||||||
|
|
||||||
public HttpRequestModule()
|
public HttpRequestModule()
|
||||||
|
@ -119,10 +133,77 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
return UUID.Zero;
|
return UUID.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool CheckThrottle(uint localID, UUID ownerID)
|
||||||
|
{
|
||||||
|
ThrottleData th;
|
||||||
|
double now = Util.GetTimeStamp();
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
if (m_RequestsThrottle.TryGetValue(localID, out th))
|
||||||
|
{
|
||||||
|
double delta = now - th.lastTime;
|
||||||
|
th.lastTime = now;
|
||||||
|
|
||||||
|
float add = (float)(m_primPerSec * delta);
|
||||||
|
th.count += add;
|
||||||
|
if (th.count > m_primBurst)
|
||||||
|
th.count = m_primBurst;
|
||||||
|
|
||||||
|
ret = th.count > 0;
|
||||||
|
if (ret)
|
||||||
|
th.count--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
th = new ThrottleData()
|
||||||
|
{
|
||||||
|
lastTime = now,
|
||||||
|
count = m_primBurst - 1
|
||||||
|
};
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
m_RequestsThrottle[localID] = th;
|
||||||
|
|
||||||
|
if(!ret)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (m_OwnerRequestsThrottle.TryGetValue(ownerID, out th))
|
||||||
|
{
|
||||||
|
double delta = now - th.lastTime;
|
||||||
|
th.lastTime = now;
|
||||||
|
|
||||||
|
float add = (float)(m_primOwnerPerSec * delta);
|
||||||
|
th.count += add;
|
||||||
|
if (th.count > m_primOwnerBurst)
|
||||||
|
th.count = m_primOwnerBurst;
|
||||||
|
|
||||||
|
ret = th.count > 0;
|
||||||
|
if (ret)
|
||||||
|
th.count--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
th = new ThrottleData()
|
||||||
|
{
|
||||||
|
lastTime = now,
|
||||||
|
count = m_primOwnerBurst - 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
m_OwnerRequestsThrottle[ownerID] = th;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
public UUID StartHttpRequest(
|
public UUID StartHttpRequest(
|
||||||
uint localID, UUID itemID, string url, List<string> parameters, Dictionary<string, string> headers, string body,
|
uint localID, UUID itemID, string url, List<string> parameters, Dictionary<string, string> headers, string body,
|
||||||
out HttpInitialRequestStatus status)
|
out HttpInitialRequestStatus status)
|
||||||
{
|
{
|
||||||
|
if (!CheckAllowed(new Uri(url)))
|
||||||
|
{
|
||||||
|
status = HttpInitialRequestStatus.DISALLOWED_BY_FILTER;
|
||||||
|
return UUID.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
UUID reqID = UUID.Random();
|
UUID reqID = UUID.Random();
|
||||||
HttpRequestClass htc = new HttpRequestClass();
|
HttpRequestClass htc = new HttpRequestClass();
|
||||||
|
|
||||||
|
@ -207,7 +288,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
htc.ItemID = itemID;
|
htc.ItemID = itemID;
|
||||||
htc.Url = url;
|
htc.Url = url;
|
||||||
htc.ReqID = reqID;
|
htc.ReqID = reqID;
|
||||||
htc.HttpTimeout = httpTimeout;
|
htc.HttpTimeout = m_httpTimeout;
|
||||||
htc.OutboundBody = body;
|
htc.OutboundBody = body;
|
||||||
htc.ResponseHeaders = headers;
|
htc.ResponseHeaders = headers;
|
||||||
htc.proxyurl = m_proxyurl;
|
htc.proxyurl = m_proxyurl;
|
||||||
|
@ -216,16 +297,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
// Same number as default HttpWebRequest.MaximumAutomaticRedirections
|
// Same number as default HttpWebRequest.MaximumAutomaticRedirections
|
||||||
htc.MaxRedirects = 50;
|
htc.MaxRedirects = 50;
|
||||||
|
|
||||||
if (StartHttpRequest(htc))
|
lock (m_httpListLock)
|
||||||
{
|
m_pendingRequests.Add(reqID, htc);
|
||||||
|
|
||||||
|
htc.Process();
|
||||||
status = HttpInitialRequestStatus.OK;
|
status = HttpInitialRequestStatus.OK;
|
||||||
return htc.ReqID;
|
return reqID;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = HttpInitialRequestStatus.DISALLOWED_BY_FILTER;
|
|
||||||
return UUID.Zero;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -237,34 +314,21 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
return m_outboundUrlFilter.CheckAllowed(url);
|
return m_outboundUrlFilter.CheckAllowed(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool StartHttpRequest(HttpRequestClass req)
|
|
||||||
{
|
|
||||||
if (!CheckAllowed(new Uri(req.Url)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
lock (HttpListLock)
|
|
||||||
{
|
|
||||||
m_pendingRequests.Add(req.ReqID, req);
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Process();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StopHttpRequest(uint m_localID, UUID m_itemID)
|
public void StopHttpRequest(uint m_localID, UUID m_itemID)
|
||||||
{
|
{
|
||||||
if (m_pendingRequests != null)
|
List<UUID> toremove = new List<UUID>();
|
||||||
|
lock (m_httpListLock)
|
||||||
{
|
{
|
||||||
lock (HttpListLock)
|
foreach (HttpRequestClass tmpReq in m_pendingRequests.Values)
|
||||||
{
|
{
|
||||||
HttpRequestClass tmpReq;
|
if(tmpReq.ItemID == m_itemID)
|
||||||
if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
|
|
||||||
{
|
{
|
||||||
tmpReq.Stop();
|
tmpReq.Stop();
|
||||||
m_pendingRequests.Remove(m_itemID);
|
toremove.Add(tmpReq.ReqID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
foreach(UUID id in toremove)
|
||||||
|
m_pendingRequests.Remove(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,37 +340,35 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
* finished. I thought about setting up a queue for this, but
|
* finished. I thought about setting up a queue for this, but
|
||||||
* it will need some refactoring and this works 'enough' right now
|
* it will need some refactoring and this works 'enough' right now
|
||||||
*/
|
*/
|
||||||
|
public void GotCompletedRequest(HttpRequestClass req)
|
||||||
|
{
|
||||||
|
lock (m_httpListLock)
|
||||||
|
{
|
||||||
|
if (req.Removed)
|
||||||
|
return;
|
||||||
|
m_pendingRequests.Remove(req.ReqID);
|
||||||
|
m_CompletedRequests.Enqueue(req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public IServiceRequest GetNextCompletedRequest()
|
public IServiceRequest GetNextCompletedRequest()
|
||||||
{
|
{
|
||||||
lock (HttpListLock)
|
HttpRequestClass req;
|
||||||
{
|
if(m_CompletedRequests.TryDequeue(out req))
|
||||||
foreach (UUID luid in m_pendingRequests.Keys)
|
return req;
|
||||||
{
|
|
||||||
HttpRequestClass tmpReq;
|
|
||||||
|
|
||||||
if (m_pendingRequests.TryGetValue(luid, out tmpReq))
|
|
||||||
{
|
|
||||||
if (tmpReq.Finished)
|
|
||||||
{
|
|
||||||
return tmpReq;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveCompletedRequest(UUID id)
|
public void RemoveCompletedRequest(UUID reqId)
|
||||||
{
|
{
|
||||||
lock (HttpListLock)
|
lock (m_httpListLock)
|
||||||
{
|
{
|
||||||
HttpRequestClass tmpReq;
|
HttpRequestClass tmpReq;
|
||||||
if (m_pendingRequests.TryGetValue(id, out tmpReq))
|
if (m_pendingRequests.TryGetValue(reqId, out tmpReq))
|
||||||
{
|
{
|
||||||
tmpReq.Stop();
|
tmpReq.Stop();
|
||||||
tmpReq = null;
|
m_pendingRequests.Remove(reqId);
|
||||||
m_pendingRequests.Remove(id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,17 +384,28 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
|
|
||||||
HttpRequestClass.HttpBodyMaxLenMAX = config.Configs["Network"].GetInt("HttpBodyMaxLenMAX", 16384);
|
HttpRequestClass.HttpBodyMaxLenMAX = config.Configs["Network"].GetInt("HttpBodyMaxLenMAX", 16384);
|
||||||
|
|
||||||
|
|
||||||
m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config);
|
m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config);
|
||||||
int maxThreads = 15;
|
|
||||||
|
|
||||||
IConfig httpConfig = config.Configs["HttpRequestModule"];
|
int maxThreads = 8;
|
||||||
|
IConfig httpConfig = config.Configs["ScriptsHttpRequestModule"];
|
||||||
if (httpConfig != null)
|
if (httpConfig != null)
|
||||||
{
|
{
|
||||||
maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads);
|
maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads);
|
||||||
|
m_primBurst = httpConfig.GetFloat("PrimRequestsBurst", m_primBurst);
|
||||||
|
m_primPerSec = httpConfig.GetFloat("PrimRequestsPerSec", m_primPerSec);
|
||||||
|
m_primOwnerBurst = httpConfig.GetFloat("PrimOwnerRequestsBurst", m_primOwnerBurst);
|
||||||
|
m_primOwnerPerSec = httpConfig.GetFloat("PrimOwnerRequestsPerSec", m_primOwnerPerSec);
|
||||||
|
m_httpTimeout = httpConfig.GetInt("RequestsTimeOut", m_httpTimeout);
|
||||||
|
if(m_httpTimeout > 60000)
|
||||||
|
m_httpTimeout = 60000;
|
||||||
|
else if(m_httpTimeout < 200)
|
||||||
|
m_httpTimeout = 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pendingRequests = new Dictionary<UUID, HttpRequestClass>();
|
m_pendingRequests = new Dictionary<UUID, HttpRequestClass>();
|
||||||
|
m_CompletedRequests = new ConcurrentQueue<HttpRequestClass>();
|
||||||
|
m_RequestsThrottle = new ConcurrentDictionary<uint, ThrottleData>();
|
||||||
|
m_OwnerRequestsThrottle = new ConcurrentDictionary<UUID, ThrottleData>();
|
||||||
|
|
||||||
// First instance sets this up for all sims
|
// First instance sets this up for all sims
|
||||||
if (ThreadPool == null)
|
if (ThreadPool == null)
|
||||||
|
@ -352,16 +425,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
|
|
||||||
public void AddRegion(Scene scene)
|
public void AddRegion(Scene scene)
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
scene.RegisterModuleInterface<IHttpRequestModule>(this);
|
||||||
|
|
||||||
m_scene.RegisterModuleInterface<IHttpRequestModule>(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
public void RemoveRegion(Scene scene)
|
||||||
{
|
{
|
||||||
scene.UnregisterModuleInterface<IHttpRequestModule>(this);
|
scene.UnregisterModuleInterface<IHttpRequestModule>(this);
|
||||||
if (scene == m_scene)
|
|
||||||
m_scene = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostInitialise()
|
public void PostInitialise()
|
||||||
|
@ -406,11 +475,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public HttpRequestModule RequestModule { get; set; }
|
public HttpRequestModule RequestModule { get; set; }
|
||||||
|
|
||||||
private bool _finished;
|
public bool Finished { get; private set;}
|
||||||
public bool Finished
|
public bool Removed{ get; set;}
|
||||||
{
|
|
||||||
get { return _finished; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int HttpBodyMaxLenMAX = 16384;
|
public static int HttpBodyMaxLenMAX = 16384;
|
||||||
|
|
||||||
|
@ -427,19 +493,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
public bool HttpPragmaNoCache = true;
|
public bool HttpPragmaNoCache = true;
|
||||||
|
|
||||||
// Request info
|
// Request info
|
||||||
private UUID _itemID;
|
public UUID ReqID { get; set; }
|
||||||
public UUID ItemID
|
public UUID ItemID { get; set;}
|
||||||
{
|
public uint LocalID { get; set;}
|
||||||
get { return _itemID; }
|
|
||||||
set { _itemID = value; }
|
|
||||||
}
|
|
||||||
private uint _localID;
|
|
||||||
public uint LocalID
|
|
||||||
{
|
|
||||||
get { return _localID; }
|
|
||||||
set { _localID = value; }
|
|
||||||
}
|
|
||||||
public DateTime Next;
|
|
||||||
public string proxyurl;
|
public string proxyurl;
|
||||||
public string proxyexcepts;
|
public string proxyexcepts;
|
||||||
|
|
||||||
|
@ -454,12 +511,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
public int MaxRedirects { get; set; }
|
public int MaxRedirects { get; set; }
|
||||||
|
|
||||||
public string OutboundBody;
|
public string OutboundBody;
|
||||||
private UUID _reqID;
|
|
||||||
public UUID ReqID
|
|
||||||
{
|
|
||||||
get { return _reqID; }
|
|
||||||
set { _reqID = value; }
|
|
||||||
}
|
|
||||||
public HttpWebRequest Request;
|
public HttpWebRequest Request;
|
||||||
public string ResponseBody;
|
public string ResponseBody;
|
||||||
public List<string> ResponseMetadata;
|
public List<string> ResponseMetadata;
|
||||||
|
@ -469,9 +521,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
|
|
||||||
public void Process()
|
public void Process()
|
||||||
{
|
{
|
||||||
_finished = false;
|
|
||||||
|
|
||||||
lock (HttpRequestModule.ThreadPool)
|
|
||||||
WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null);
|
WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,6 +570,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
|
|
||||||
public void SendRequest()
|
public void SendRequest()
|
||||||
{
|
{
|
||||||
|
if(Removed)
|
||||||
|
return;
|
||||||
|
|
||||||
HttpWebResponse response = null;
|
HttpWebResponse response = null;
|
||||||
Stream resStream = null;
|
Stream resStream = null;
|
||||||
byte[] buf = new byte[HttpBodyMaxLenMAX + 16];
|
byte[] buf = new byte[HttpBodyMaxLenMAX + 16];
|
||||||
|
@ -534,6 +586,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
|
|
||||||
Request.AllowAutoRedirect = false;
|
Request.AllowAutoRedirect = false;
|
||||||
Request.KeepAlive = false;
|
Request.KeepAlive = false;
|
||||||
|
Request.Timeout = HttpTimeout;
|
||||||
|
|
||||||
//This works around some buggy HTTP Servers like Lighttpd
|
//This works around some buggy HTTP Servers like Lighttpd
|
||||||
Request.ServicePoint.Expect100Continue = false;
|
Request.ServicePoint.Expect100Continue = false;
|
||||||
|
@ -593,7 +646,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
bstream.Write(data, 0, data.Length);
|
bstream.Write(data, 0, data.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
Request.Timeout = HttpTimeout;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// execute the request
|
// execute the request
|
||||||
|
@ -672,7 +724,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
if (response != null)
|
if (response != null)
|
||||||
response.Close();
|
response.Close();
|
||||||
|
|
||||||
|
|
||||||
// We need to resubmit
|
// We need to resubmit
|
||||||
if (
|
if (
|
||||||
(Status == (int)HttpStatusCode.MovedPermanently
|
(Status == (int)HttpStatusCode.MovedPermanently
|
||||||
|
@ -684,7 +735,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
{
|
{
|
||||||
Status = (int)OSHttpStatusCode.ClientErrorJoker;
|
Status = (int)OSHttpStatusCode.ClientErrorJoker;
|
||||||
ResponseBody = "Number of redirects exceeded max redirects";
|
ResponseBody = "Number of redirects exceeded max redirects";
|
||||||
_finished = true;
|
WorkItem = null;
|
||||||
|
RequestModule.GotCompletedRequest(this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -694,13 +746,15 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
{
|
{
|
||||||
Status = (int)OSHttpStatusCode.ClientErrorJoker;
|
Status = (int)OSHttpStatusCode.ClientErrorJoker;
|
||||||
ResponseBody = "HTTP redirect code but no location header";
|
ResponseBody = "HTTP redirect code but no location header";
|
||||||
_finished = true;
|
WorkItem = null;
|
||||||
|
RequestModule.GotCompletedRequest(this);
|
||||||
}
|
}
|
||||||
else if (!RequestModule.CheckAllowed(new Uri(location)))
|
else if (!RequestModule.CheckAllowed(new Uri(location)))
|
||||||
{
|
{
|
||||||
Status = (int)OSHttpStatusCode.ClientErrorJoker;
|
Status = (int)OSHttpStatusCode.ClientErrorJoker;
|
||||||
ResponseBody = "URL from HTTP redirect blocked: " + location;
|
ResponseBody = "URL from HTTP redirect blocked: " + location;
|
||||||
_finished = true;
|
WorkItem = null;
|
||||||
|
RequestModule.GotCompletedRequest(this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -717,9 +771,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_finished = true;
|
WorkItem = null;
|
||||||
if (ResponseBody == null)
|
if (ResponseBody == null)
|
||||||
ResponseBody = String.Empty;
|
ResponseBody = String.Empty;
|
||||||
|
RequestModule.GotCompletedRequest(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -728,11 +783,13 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Removed = true;
|
||||||
|
if(WorkItem == null)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!WorkItem.Cancel())
|
if (!WorkItem.Cancel())
|
||||||
{
|
|
||||||
WorkItem.Cancel(true);
|
WorkItem.Cancel(true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -1204,28 +1204,33 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey)
|
private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey, bool kick)
|
||||||
{
|
{
|
||||||
|
if (prey == UUID.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
EstateTeleportOneUserHomeRequest evOverride = OnEstateTeleportOneUserHomeRequest;
|
EstateTeleportOneUserHomeRequest evOverride = OnEstateTeleportOneUserHomeRequest;
|
||||||
if(evOverride != null)
|
if(evOverride != null)
|
||||||
{
|
{
|
||||||
evOverride(remover_client, invoice, senderID, prey);
|
evOverride(remover_client, invoice, senderID, prey, kick);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Scene.Permissions.CanIssueEstateCommand(remover_client.AgentId, false))
|
if (!Scene.Permissions.CanIssueEstateCommand(remover_client.AgentId, false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (prey != UUID.Zero)
|
|
||||||
{
|
|
||||||
ScenePresence s = Scene.GetScenePresence(prey);
|
ScenePresence s = Scene.GetScenePresence(prey);
|
||||||
if (s != null && !s.IsDeleted && !s.IsInTransit)
|
if (s != null && !s.IsDeleted && !s.IsInTransit)
|
||||||
{
|
{
|
||||||
if (!Scene.TeleportClientHome(prey, s.ControllingClient))
|
if (kick)
|
||||||
{
|
{
|
||||||
s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
|
s.ControllingClient.Kick("You have been kicked");
|
||||||
Scene.CloseAgent(s.UUID, false);
|
Scene.CloseAgent(s.UUID, false);
|
||||||
}
|
}
|
||||||
|
else if (!Scene.TeleportClientHome(prey, s.ControllingClient))
|
||||||
|
{
|
||||||
|
s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed ");
|
||||||
|
Scene.CloseAgent(s.UUID, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,7 +204,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||||
m_EstateConnector.SendEstateMessage(estateID, FromID, FromName, Message);
|
m_EstateConnector.SendEstateMessage(estateID, FromID, FromName, Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEstateTeleportOneUserHomeRequest(IClientAPI client, UUID invoice, UUID senderID, UUID prey)
|
private void OnEstateTeleportOneUserHomeRequest(IClientAPI client, UUID invoice, UUID senderID, UUID prey, bool kick)
|
||||||
{
|
{
|
||||||
if (prey == UUID.Zero)
|
if (prey == UUID.Zero)
|
||||||
return;
|
return;
|
||||||
|
@ -226,9 +226,21 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||||
|
|
||||||
ScenePresence p = scene.GetScenePresence(prey);
|
ScenePresence p = scene.GetScenePresence(prey);
|
||||||
if (p != null && !p.IsChildAgent && !p.IsDeleted && !p.IsInTransit)
|
if (p != null && !p.IsChildAgent && !p.IsDeleted && !p.IsInTransit)
|
||||||
|
{
|
||||||
|
if (kick)
|
||||||
|
{
|
||||||
|
p.ControllingClient.Kick("You have been kicked out");
|
||||||
|
s.CloseAgent(p.UUID, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
p.ControllingClient.SendTeleportStart(16);
|
p.ControllingClient.SendTeleportStart(16);
|
||||||
scene.TeleportClientHome(prey, client);
|
if (!s.TeleportClientHome(prey, client))
|
||||||
|
{
|
||||||
|
p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed");
|
||||||
|
s.CloseAgent(p.UUID, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,6 +271,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||||
{
|
{
|
||||||
p.ControllingClient.SendTeleportStart(16);
|
p.ControllingClient.SendTeleportStart(16);
|
||||||
scene.TeleportClientHome(p.ControllingClient.AgentId, client);
|
scene.TeleportClientHome(p.ControllingClient.AgentId, client);
|
||||||
|
if (!s.TeleportClientHome(p.ControllingClient.AgentId, client))
|
||||||
|
{
|
||||||
|
p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
|
||||||
|
s.CloseAgent(p.UUID, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,5 +87,6 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
void StopHttpRequest(uint m_localID, UUID m_itemID);
|
void StopHttpRequest(uint m_localID, UUID m_itemID);
|
||||||
IServiceRequest GetNextCompletedRequest();
|
IServiceRequest GetNextCompletedRequest();
|
||||||
void RemoveCompletedRequest(UUID id);
|
void RemoveCompletedRequest(UUID id);
|
||||||
|
bool CheckThrottle(uint localID, UUID onerID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,19 +94,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_inventoryDeletes.Enqueue(dtis);
|
m_inventoryDeletes.Enqueue(dtis);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Enabled)
|
|
||||||
lock (m_inventoryTicker)
|
|
||||||
m_inventoryTicker.Start();
|
|
||||||
|
|
||||||
// Visually remove it, even if it isnt really gone yet. This means that if we crash before the object
|
|
||||||
// has gone to inventory, it will reappear in the region again on restart instead of being lost.
|
|
||||||
// This is not ideal since the object will still be available for manipulation when it should be, but it's
|
|
||||||
// better than losing the object for now.
|
|
||||||
if (permissionToDelete)
|
if (permissionToDelete)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectGroup g in objectGroups)
|
foreach (SceneObjectGroup g in objectGroups)
|
||||||
g.DeleteGroupFromScene(false);
|
g.DeleteGroupFromScene(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Enabled)
|
||||||
|
lock (m_inventoryTicker)
|
||||||
|
m_inventoryTicker.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e)
|
private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e)
|
||||||
|
|
|
@ -539,7 +539,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <see cref="SceneObjectPart.TriggerScriptChangedEvent"/>
|
/// <see cref="SceneObjectPart.TriggerScriptChangedEvent"/>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public event ScriptChangedEvent OnScriptChangedEvent;
|
public event ScriptChangedEvent OnScriptChangedEvent;
|
||||||
public delegate void ScriptChangedEvent(uint localID, uint change);
|
public delegate void ScriptChangedEvent(uint localID, uint change, object data);
|
||||||
|
|
||||||
public delegate void ScriptControlEvent(UUID item, UUID avatarID, uint held, uint changed);
|
public delegate void ScriptControlEvent(UUID item, UUID avatarID, uint held, uint changed);
|
||||||
|
|
||||||
|
@ -1185,7 +1185,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TriggerOnScriptChangedEvent(uint localID, uint change)
|
public void TriggerOnScriptChangedEvent(uint localID, uint change, object parameter = null)
|
||||||
{
|
{
|
||||||
ScriptChangedEvent handlerScriptChangedEvent = OnScriptChangedEvent;
|
ScriptChangedEvent handlerScriptChangedEvent = OnScriptChangedEvent;
|
||||||
if (handlerScriptChangedEvent != null)
|
if (handlerScriptChangedEvent != null)
|
||||||
|
@ -1194,7 +1194,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
d(localID, change);
|
d(localID, change, parameter);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2110,7 +2110,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// build a list of eligible objects
|
// build a list of eligible objects
|
||||||
List<uint> deleteIDs = new List<uint>();
|
List<uint> deleteIDs = new List<uint>();
|
||||||
List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>();
|
List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>();
|
||||||
List<SceneObjectGroup> takeGroups = new List<SceneObjectGroup>();
|
List<SceneObjectGroup> takeCopyGroups = new List<SceneObjectGroup>();
|
||||||
List<SceneObjectGroup> takeDeleteGroups = new List<SceneObjectGroup>();
|
List<SceneObjectGroup> takeDeleteGroups = new List<SceneObjectGroup>();
|
||||||
|
|
||||||
ScenePresence sp = null;
|
ScenePresence sp = null;
|
||||||
|
@ -2119,11 +2119,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
else if(action != DeRezAction.Return)
|
else if(action != DeRezAction.Return)
|
||||||
return; // only Return can be called without a client
|
return; // only Return can be called without a client
|
||||||
|
|
||||||
// Start with true for both, then remove the flags if objects
|
// this is not as 0.8x code
|
||||||
// that we can't derez are part of the selection
|
// 0.8x did refuse all operation is not allowed on all objects
|
||||||
bool permissionToTake = true;
|
// this will do it on allowed objects
|
||||||
bool permissionToTakeCopy = true;
|
// current viewers only ask if all allowed
|
||||||
bool permissionToDelete = true;
|
|
||||||
|
|
||||||
foreach (uint localID in localIDs)
|
foreach (uint localID in localIDs)
|
||||||
{
|
{
|
||||||
|
@ -2136,8 +2135,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Already deleted by someone else
|
SceneObjectGroup grp = part.ParentGroup;
|
||||||
if (part.ParentGroup.IsDeleted)
|
if (grp == null || grp.IsDeleted)
|
||||||
{
|
{
|
||||||
//Client still thinks the object exists, kill it
|
//Client still thinks the object exists, kill it
|
||||||
deleteIDs.Add(localID);
|
deleteIDs.Add(localID);
|
||||||
|
@ -2145,90 +2144,69 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't delete child prims
|
// Can't delete child prims
|
||||||
if (part != part.ParentGroup.RootPart)
|
if (part != grp.RootPart)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SceneObjectGroup grp = part.ParentGroup;
|
|
||||||
if (grp.IsAttachment)
|
if (grp.IsAttachment)
|
||||||
|
{
|
||||||
|
if(!sp.IsGod || action != DeRezAction.Return || action != DeRezAction.Delete)
|
||||||
continue;
|
continue;
|
||||||
|
// this may break the attachment, but its a security action
|
||||||
|
// viewers don't allow it anyways
|
||||||
|
}
|
||||||
|
|
||||||
// If child prims have invalid perms, fix them
|
// If child prims have invalid perms, fix them
|
||||||
grp.AdjustChildPrimPermissions(false);
|
grp.AdjustChildPrimPermissions(false);
|
||||||
|
|
||||||
if (remoteClient == null)
|
switch (action)
|
||||||
{
|
{
|
||||||
// Autoreturn has a null client. Nothing else does. So
|
case DeRezAction.SaveToExistingUserInventoryItem:
|
||||||
// allow only returns
|
|
||||||
if (action != DeRezAction.Return)
|
|
||||||
{
|
{
|
||||||
m_log.WarnFormat(
|
if (Permissions.CanTakeCopyObject(grp, sp))
|
||||||
"[AGENT INVENTORY]: Ignoring attempt to {0} {1} {2} without a client",
|
takeCopyGroups.Add(grp);
|
||||||
action, grp.Name, grp.UUID);
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
permissionToTakeCopy = false;
|
case DeRezAction.TakeCopy:
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (action == DeRezAction.TakeCopy)
|
if (Permissions.CanTakeCopyObject(grp, sp))
|
||||||
{
|
takeCopyGroups.Add(grp);
|
||||||
if (!Permissions.CanTakeCopyObject(grp, sp))
|
break;
|
||||||
permissionToTakeCopy = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
permissionToTakeCopy = false;
|
|
||||||
}
|
|
||||||
if (!Permissions.CanTakeObject(grp, sp))
|
|
||||||
permissionToTake = false;
|
|
||||||
|
|
||||||
if (!Permissions.CanDeleteObject(grp, remoteClient))
|
|
||||||
permissionToDelete = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle god perms
|
case DeRezAction.Take:
|
||||||
|
{
|
||||||
|
if (Permissions.CanTakeObject(grp, sp))
|
||||||
|
takeDeleteGroups.Add(grp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DeRezAction.GodTakeCopy:
|
||||||
|
{
|
||||||
if((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId))
|
if((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId))
|
||||||
{
|
takeCopyGroups.Add(grp);
|
||||||
permissionToTake = true;
|
break;
|
||||||
permissionToTakeCopy = true;
|
|
||||||
permissionToDelete = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're re-saving, we don't even want to delete
|
case DeRezAction.Delete:
|
||||||
if (action == DeRezAction.SaveToExistingUserInventoryItem)
|
|
||||||
permissionToDelete = false;
|
|
||||||
|
|
||||||
// if we want to take a copy, we also don't want to delete
|
|
||||||
// Note: after this point, the permissionToTakeCopy flag
|
|
||||||
// becomes irrelevant. It already includes the permissionToTake
|
|
||||||
// permission and after excluding no copy items here, we can
|
|
||||||
// just use that.
|
|
||||||
if (action == DeRezAction.TakeCopy)
|
|
||||||
{
|
{
|
||||||
// If we don't have permission, stop right here
|
if (Permissions.CanDeleteObject(grp, remoteClient))
|
||||||
if (!permissionToTakeCopy)
|
|
||||||
{
|
{
|
||||||
remoteClient.SendAlertMessage("You don't have permission to take the object");
|
if(m_useTrashOnDelete || (sp.IsGod && grp.OwnerID != sp.UUID))
|
||||||
return;
|
takeDeleteGroups.Add(grp);
|
||||||
|
else
|
||||||
|
deleteGroups.Add(grp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
permissionToTake = true;
|
case DeRezAction.Return:
|
||||||
// Don't delete
|
|
||||||
permissionToDelete = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action == DeRezAction.Return)
|
|
||||||
{
|
{
|
||||||
if (remoteClient != null)
|
if (remoteClient != null)
|
||||||
{
|
{
|
||||||
if (Permissions.CanReturnObjects(
|
if (Permissions.CanReturnObjects( null, remoteClient, new List<SceneObjectGroup>() {grp}))
|
||||||
null,
|
|
||||||
remoteClient,
|
|
||||||
new List<SceneObjectGroup>() {grp}))
|
|
||||||
{
|
{
|
||||||
permissionToTake = true;
|
takeDeleteGroups.Add(grp);
|
||||||
permissionToDelete = true;
|
|
||||||
if (AddToReturns)
|
if (AddToReturns)
|
||||||
AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition,
|
AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition,
|
||||||
"parcel owner return");
|
"parcel owner return");
|
||||||
|
@ -2236,41 +2214,35 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
else // Auto return passes through here with null agent
|
else // Auto return passes through here with null agent
|
||||||
{
|
{
|
||||||
permissionToTake = true;
|
|
||||||
permissionToDelete = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (permissionToDelete)
|
|
||||||
{
|
|
||||||
if (permissionToTake)
|
|
||||||
takeDeleteGroups.Add(grp);
|
takeDeleteGroups.Add(grp);
|
||||||
else
|
|
||||||
deleteGroups.Add(grp);
|
|
||||||
deleteIDs.Add(grp.LocalId);
|
|
||||||
}
|
}
|
||||||
else if(permissionToTake)
|
break;
|
||||||
takeGroups.Add(grp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(deleteIDs.Count > 0)
|
||||||
SendKillObject(deleteIDs);
|
SendKillObject(deleteIDs);
|
||||||
|
|
||||||
if (takeDeleteGroups.Count > 0)
|
if (takeDeleteGroups.Count > 0)
|
||||||
{
|
{
|
||||||
m_asyncSceneObjectDeleter.DeleteToInventory(
|
m_asyncSceneObjectDeleter.DeleteToInventory(action, destinationID, takeDeleteGroups,
|
||||||
action, destinationID, takeDeleteGroups, remoteClient,
|
remoteClient, true);
|
||||||
true);
|
|
||||||
}
|
}
|
||||||
if (takeGroups.Count > 0)
|
|
||||||
|
if (takeCopyGroups.Count > 0)
|
||||||
{
|
{
|
||||||
m_asyncSceneObjectDeleter.DeleteToInventory(
|
m_asyncSceneObjectDeleter.DeleteToInventory(action, destinationID, takeCopyGroups,
|
||||||
action, destinationID, takeGroups, remoteClient,
|
remoteClient, false);
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deleteGroups.Count > 0)
|
if (deleteGroups.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectGroup g in deleteGroups)
|
foreach (SceneObjectGroup g in deleteGroups)
|
||||||
DeleteSceneObject(g, true);
|
DeleteSceneObject(g, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1913,9 +1913,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
if (parentGroup.OwnerID == child.OwnerID)
|
if (parentGroup.OwnerID == child.OwnerID)
|
||||||
{
|
{
|
||||||
parentGroup.LinkToGroup(child);
|
|
||||||
|
|
||||||
child.DetachFromBackup();
|
child.DetachFromBackup();
|
||||||
|
parentGroup.LinkToGroup(child);
|
||||||
|
|
||||||
// this is here so physics gets updated!
|
// this is here so physics gets updated!
|
||||||
// Don't remove! Bad juju! Stay away! or fix physics!
|
// Don't remove! Bad juju! Stay away! or fix physics!
|
||||||
|
@ -1943,7 +1942,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
*/
|
*/
|
||||||
parentGroup.AdjustChildPrimPermissions(false);
|
parentGroup.AdjustChildPrimPermissions(false);
|
||||||
parentGroup.HasGroupChanged = true;
|
parentGroup.HasGroupChanged = true;
|
||||||
parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true);
|
|
||||||
parentGroup.ScheduleGroupForFullAnimUpdate();
|
parentGroup.ScheduleGroupForFullAnimUpdate();
|
||||||
Monitor.Exit(m_linkLock);
|
Monitor.Exit(m_linkLock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,7 +154,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// We're adding this to a prim we don't own. Force
|
// We're adding this to a prim we don't own. Force
|
||||||
// owner change
|
// owner change
|
||||||
taskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
|
taskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
|
||||||
|
taskItem.LastOwnerID = item.Owner;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -3242,8 +3242,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (ParentGroup.Scene.GetNumberOfClients() == 0)
|
if (ParentGroup.Scene.GetNumberOfClients() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ParentGroup.QueueForUpdateCheck();
|
|
||||||
|
|
||||||
bool isfull = false;
|
bool isfull = false;
|
||||||
if (ParentGroup.IsAttachment)
|
if (ParentGroup.IsAttachment)
|
||||||
{
|
{
|
||||||
|
@ -3254,6 +3252,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
lock (UpdateFlagLock)
|
lock (UpdateFlagLock)
|
||||||
UpdateFlag |= update;
|
UpdateFlag |= update;
|
||||||
|
|
||||||
|
ParentGroup.QueueForUpdateCheck();
|
||||||
|
|
||||||
ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, isfull);
|
ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, isfull);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4439,10 +4439,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
SceneObjectSerializer.SOPToXml2(xmlWriter, this, new Dictionary<string, object>());
|
SceneObjectSerializer.SOPToXml2(xmlWriter, this, new Dictionary<string, object>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TriggerScriptChangedEvent(Changed val)
|
public void TriggerScriptChangedEvent(Changed val, object data = null)
|
||||||
{
|
{
|
||||||
if (ParentGroup != null && ParentGroup.Scene != null)
|
if (ParentGroup != null && ParentGroup.Scene != null)
|
||||||
ParentGroup.Scene.EventManager.TriggerOnScriptChangedEvent(LocalId, (uint)val);
|
ParentGroup.Scene.EventManager.TriggerOnScriptChangedEvent(LocalId, (uint)val, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TrimPermissions()
|
public void TrimPermissions()
|
||||||
|
@ -5130,11 +5130,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (changeFlags == 0)
|
if (changeFlags == 0)
|
||||||
return;
|
return;
|
||||||
m_shape.TextureEntry = newTex.GetBytes();
|
m_shape.TextureEntry = newTex.GetBytes(9);
|
||||||
TriggerScriptChangedEvent(changeFlags);
|
TriggerScriptChangedEvent(changeFlags);
|
||||||
ParentGroup.HasGroupChanged = true;
|
ParentGroup.HasGroupChanged = true;
|
||||||
ScheduleFullUpdate();
|
ScheduleUpdate(PrimUpdateFlags.Textures);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -5160,10 +5159,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (changeFlags == 0)
|
if (changeFlags == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_shape.TextureEntry = newTex.GetBytes();
|
m_shape.TextureEntry = newTex.GetBytes(9);
|
||||||
TriggerScriptChangedEvent(changeFlags);
|
TriggerScriptChangedEvent(changeFlags);
|
||||||
ParentGroup.HasGroupChanged = true;
|
ParentGroup.HasGroupChanged = true;
|
||||||
ScheduleFullUpdate();
|
ScheduleUpdate(PrimUpdateFlags.Textures);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void UpdatePhysicsSubscribedEvents()
|
internal void UpdatePhysicsSubscribedEvents()
|
||||||
|
@ -5575,16 +5574,22 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// handle osVolumeDetect
|
// handle osVolumeDetect
|
||||||
public void ScriptSetVolumeDetect(bool makeVolumeDetect)
|
public void ScriptSetVolumeDetect(bool makeVolumeDetect)
|
||||||
{
|
{
|
||||||
|
if(ParentGroup.IsDeleted)
|
||||||
|
return;
|
||||||
|
|
||||||
if(_parentID == 0)
|
if(_parentID == 0)
|
||||||
{
|
{
|
||||||
// if root prim do it via SOG
|
// if root prim do it is like llVolumeDetect
|
||||||
ParentGroup.ScriptSetVolumeDetect(makeVolumeDetect);
|
ParentGroup.ScriptSetVolumeDetect(makeVolumeDetect);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
|
if(ParentGroup.IsVolumeDetect)
|
||||||
bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
|
return; // entire linkset is phantom already
|
||||||
bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0);
|
|
||||||
|
bool wasUsingPhysics = ParentGroup.UsesPhysics;
|
||||||
|
bool wasTemporary = ParentGroup.IsTemporary;
|
||||||
|
bool wasPhantom = ParentGroup.IsPhantom;
|
||||||
|
|
||||||
if(PhysActor != null)
|
if(PhysActor != null)
|
||||||
PhysActor.Building = true;
|
PhysActor.Building = true;
|
||||||
|
|
|
@ -816,7 +816,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_items.Add(item.ItemID, item);
|
m_items.Add(item.ItemID, item);
|
||||||
m_items.LockItemsForWrite(false);
|
m_items.LockItemsForWrite(false);
|
||||||
if (allowedDrop)
|
if (allowedDrop)
|
||||||
m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
|
m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP, item.ItemID);
|
||||||
else
|
else
|
||||||
m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
|
m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
|
||||||
|
|
||||||
|
|
|
@ -507,7 +507,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Physical scene representation of this Avatar.
|
/// Physical scene representation of this Avatar.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PhysicsActor PhysicsActor { get; private set; }
|
|
||||||
|
PhysicsActor m_physActor;
|
||||||
|
public PhysicsActor PhysicsActor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_physActor;
|
||||||
|
}
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
m_physActor = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Record user movement inputs.
|
/// Record user movement inputs.
|
||||||
|
@ -523,7 +535,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public bool Invulnerable
|
public bool Invulnerable
|
||||||
{
|
{
|
||||||
set { m_invulnerable = value; }
|
set
|
||||||
|
{
|
||||||
|
m_invulnerable = value;
|
||||||
|
if(value && Health != 100.0f)
|
||||||
|
Health = 100.0f;
|
||||||
|
}
|
||||||
get { return m_invulnerable; }
|
get { return m_invulnerable; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1636,15 +1653,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void RemoveFromPhysicalScene()
|
public void RemoveFromPhysicalScene()
|
||||||
{
|
{
|
||||||
if (PhysicsActor != null)
|
PhysicsActor pa = Interlocked.Exchange(ref m_physActor, null);
|
||||||
|
if (pa != null)
|
||||||
{
|
{
|
||||||
// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
|
// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
|
||||||
|
|
||||||
PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
|
pa.OnOutOfBounds -= OutOfBoundsCall;
|
||||||
PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
|
pa.OnCollisionUpdate -= PhysicsCollisionUpdate;
|
||||||
PhysicsActor.UnSubscribeEvents();
|
pa.UnSubscribeEvents();
|
||||||
m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
|
m_scene.PhysicsScene.RemoveAvatar(pa);
|
||||||
PhysicsActor = null;
|
|
||||||
}
|
}
|
||||||
// else
|
// else
|
||||||
// {
|
// {
|
||||||
|
@ -2537,7 +2554,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_pos.X = 127f;
|
m_pos.X = 127f;
|
||||||
m_pos.Y = 127f;
|
m_pos.Y = 127f;
|
||||||
m_pos.Z = 127f;
|
m_pos.Z = 127f;
|
||||||
m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903");
|
m_log.Error("[AVATAR]: NonFinite Avatar on lastFiniteposition also. Reset Position. Mantis this please. Error #9999903");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isphysical)
|
if(isphysical)
|
||||||
|
@ -5007,16 +5024,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
PhysicsScene scene = m_scene.PhysicsScene;
|
PhysicsScene scene = m_scene.PhysicsScene;
|
||||||
Vector3 pVec = AbsolutePosition;
|
Vector3 pVec = AbsolutePosition;
|
||||||
|
|
||||||
PhysicsActor = scene.AddAvatar(
|
PhysicsActor pa = scene.AddAvatar(
|
||||||
LocalId, Firstname + "." + Lastname, pVec,
|
LocalId, Firstname + "." + Lastname, pVec,
|
||||||
Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
|
Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
|
||||||
PhysicsActor.Orientation = m_bodyRot;
|
pa.Orientation = m_bodyRot;
|
||||||
//PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
|
//PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
|
||||||
PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
|
pa.OnCollisionUpdate += PhysicsCollisionUpdate;
|
||||||
PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
|
pa.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
|
||||||
PhysicsActor.SubscribeEvents(100);
|
pa.SubscribeEvents(100);
|
||||||
PhysicsActor.LocalID = LocalId;
|
pa.LocalID = LocalId;
|
||||||
PhysicsActor.SetAlwaysRun = m_setAlwaysRun;
|
pa.SetAlwaysRun = m_setAlwaysRun;
|
||||||
|
PhysicsActor = pa;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OutOfBoundsCall(Vector3 pos)
|
private void OutOfBoundsCall(Vector3 pos)
|
||||||
|
|
|
@ -155,6 +155,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return iout;
|
return iout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// new using terrain data and patchs indexes
|
// new using terrain data and patchs indexes
|
||||||
public static List<LayerDataPacket> CreateLayerDataPackets(TerrainData terrData, int[] map)
|
public static List<LayerDataPacket> CreateLayerDataPackets(TerrainData terrData, int[] map)
|
||||||
{
|
{
|
||||||
|
@ -213,6 +214,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
public static void CreatePatchFromTerrainData(BitPack output, TerrainData terrData, int patchX, int patchY)
|
public static void CreatePatchFromTerrainData(BitPack output, TerrainData terrData, int patchX, int patchY)
|
||||||
{
|
{
|
||||||
|
|
|
@ -323,7 +323,7 @@ namespace OpenSim.Region.OptionalModules.Materials
|
||||||
}
|
}
|
||||||
|
|
||||||
if(facechanged)
|
if(facechanged)
|
||||||
part.Shape.TextureEntry = te.GetBytes();
|
part.Shape.TextureEntry = te.GetBytes(9);
|
||||||
|
|
||||||
if(facechanged || partchanged)
|
if(facechanged || partchanged)
|
||||||
{
|
{
|
||||||
|
@ -632,7 +632,7 @@ namespace OpenSim.Region.OptionalModules.Materials
|
||||||
faceEntry.MaterialID = id;
|
faceEntry.MaterialID = id;
|
||||||
//m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id);
|
//m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id);
|
||||||
// We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually
|
// We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually
|
||||||
sop.Shape.TextureEntry = te.GetBytes();
|
sop.Shape.TextureEntry = te.GetBytes(9);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(oldid != UUID.Zero)
|
if(oldid != UUID.Zero)
|
||||||
|
|
|
@ -47,9 +47,9 @@ public class BSActorAvatarMove : BSActor
|
||||||
// The amount the step up is applying. Used to smooth stair walking.
|
// The amount the step up is applying. Used to smooth stair walking.
|
||||||
float m_lastStepUp;
|
float m_lastStepUp;
|
||||||
|
|
||||||
// There are times the velocity is set but we don't want to inforce stationary until the
|
// There are times the velocity or force is set but we don't want to inforce
|
||||||
// real velocity drops.
|
// stationary until some tick in the future and the real velocity drops.
|
||||||
bool m_waitingForLowVelocityForStationary = false;
|
int m_waitingForLowVelocityForStationary = 0;
|
||||||
|
|
||||||
public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName)
|
public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName)
|
||||||
: base(physicsScene, pObj, actorName)
|
: base(physicsScene, pObj, actorName)
|
||||||
|
@ -114,14 +114,18 @@ public class BSActorAvatarMove : BSActor
|
||||||
m_velocityMotor.Enabled = true;
|
m_velocityMotor.Enabled = true;
|
||||||
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,SetVelocityAndTarget,vel={1}, targ={2}",
|
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,SetVelocityAndTarget,vel={1}, targ={2}",
|
||||||
m_controllingPrim.LocalID, vel, targ);
|
m_controllingPrim.LocalID, vel, targ);
|
||||||
m_waitingForLowVelocityForStationary = false;
|
m_waitingForLowVelocityForStationary = 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SuppressStationayCheckUntilLowVelocity()
|
public void SuppressStationayCheckUntilLowVelocity()
|
||||||
{
|
{
|
||||||
m_waitingForLowVelocityForStationary = true;
|
m_waitingForLowVelocityForStationary = 1;
|
||||||
|
}
|
||||||
|
public void SuppressStationayCheckUntilLowVelocity(int waitTicks)
|
||||||
|
{
|
||||||
|
m_waitingForLowVelocityForStationary = waitTicks;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a movement motor has not been created, create one and start the movement
|
// If a movement motor has not been created, create one and start the movement
|
||||||
|
@ -143,7 +147,7 @@ public class BSActorAvatarMove : BSActor
|
||||||
m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty;
|
m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty;
|
||||||
|
|
||||||
m_walkingUpStairs = 0;
|
m_walkingUpStairs = 0;
|
||||||
m_waitingForLowVelocityForStationary = false;
|
m_waitingForLowVelocityForStationary = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,15 +198,17 @@ public class BSActorAvatarMove : BSActor
|
||||||
// if colliding with something stationary and we're not doing volume detect .
|
// if colliding with something stationary and we're not doing volume detect .
|
||||||
if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect)
|
if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect)
|
||||||
{
|
{
|
||||||
if (m_waitingForLowVelocityForStationary)
|
if (m_waitingForLowVelocityForStationary-- <= 0)
|
||||||
{
|
{
|
||||||
// if waiting for velocity to drop and it has finally dropped, we can be stationary
|
// if waiting for velocity to drop and it has finally dropped, we can be stationary
|
||||||
|
// m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,waitingForLowVelocity {1}",
|
||||||
|
// m_controllingPrim.LocalID, m_waitingForLowVelocityForStationary);
|
||||||
if (m_controllingPrim.RawVelocity.LengthSquared() < BSParam.AvatarStopZeroThresholdSquared)
|
if (m_controllingPrim.RawVelocity.LengthSquared() < BSParam.AvatarStopZeroThresholdSquared)
|
||||||
{
|
{
|
||||||
m_waitingForLowVelocityForStationary = false;
|
m_waitingForLowVelocityForStationary = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!m_waitingForLowVelocityForStationary)
|
if (m_waitingForLowVelocityForStationary <= 0)
|
||||||
{
|
{
|
||||||
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID);
|
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID);
|
||||||
m_controllingPrim.IsStationary = true;
|
m_controllingPrim.IsStationary = true;
|
||||||
|
|
|
@ -701,7 +701,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
}
|
}
|
||||||
if (m_moveActor != null)
|
if (m_moveActor != null)
|
||||||
{
|
{
|
||||||
m_moveActor.SuppressStationayCheckUntilLowVelocity();
|
m_moveActor.SuppressStationayCheckUntilLowVelocity(BSParam.AvatarAddForceFrames);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,6 +149,7 @@ public static class BSParam
|
||||||
public static float AvatarHeightHighFudge { get; private set; }
|
public static float AvatarHeightHighFudge { get; private set; }
|
||||||
public static float AvatarFlyingGroundMargin { get; private set; }
|
public static float AvatarFlyingGroundMargin { get; private set; }
|
||||||
public static float AvatarFlyingGroundUpForce { get; private set; }
|
public static float AvatarFlyingGroundUpForce { get; private set; }
|
||||||
|
public static int AvatarAddForceFrames { get; private set; }
|
||||||
public static float AvatarTerminalVelocity { get; private set; }
|
public static float AvatarTerminalVelocity { get; private set; }
|
||||||
public static float AvatarContactProcessingThreshold { get; private set; }
|
public static float AvatarContactProcessingThreshold { get; private set; }
|
||||||
public static float AvatarAddForcePushFactor { get; private set; }
|
public static float AvatarAddForcePushFactor { get; private set; }
|
||||||
|
@ -634,6 +635,8 @@ public static class BSParam
|
||||||
5f ),
|
5f ),
|
||||||
new ParameterDefn<float>("AvatarFlyingGroundUpForce", "Upward force applied to the avatar to keep it at flying ground margin",
|
new ParameterDefn<float>("AvatarFlyingGroundUpForce", "Upward force applied to the avatar to keep it at flying ground margin",
|
||||||
2.0f ),
|
2.0f ),
|
||||||
|
new ParameterDefn<int>("AvatarAddForceFrames", "Frames to allow AddForce to apply before checking for stationary",
|
||||||
|
10 ),
|
||||||
new ParameterDefn<float>("AvatarTerminalVelocity", "Terminal Velocity of falling avatar",
|
new ParameterDefn<float>("AvatarTerminalVelocity", "Terminal Velocity of falling avatar",
|
||||||
-54.0f ),
|
-54.0f ),
|
||||||
new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
|
new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
|
||||||
|
|
9
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
Normal file → Executable file
9
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
Normal file → Executable file
|
@ -221,7 +221,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void CmdHandlerThreadLoop()
|
private static void CmdHandlerThreadLoop()
|
||||||
{
|
{
|
||||||
while (true)
|
bool running = true;
|
||||||
|
while (running)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -230,7 +231,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
DoOneCmdHandlerPass();
|
DoOneCmdHandlerPass();
|
||||||
Watchdog.UpdateThread();
|
Watchdog.UpdateThread();
|
||||||
}
|
}
|
||||||
catch ( System.Threading.ThreadAbortException) { }
|
catch ( System.Threading.ThreadAbortException)
|
||||||
|
{
|
||||||
|
Thread.ResetAbort();
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error("[ASYNC COMMAND MANAGER]: Exception in command handler pass: ", e);
|
m_log.Error("[ASYNC COMMAND MANAGER]: Exception in command handler pass: ", e);
|
||||||
|
|
|
@ -1936,45 +1936,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
|
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Primitive.TextureEntry tex = part.Shape.Textures;
|
|
||||||
int nsides = GetNumberOfSides(part);
|
|
||||||
Color4 texcolor;
|
|
||||||
|
|
||||||
if (face >= 0 && face < nsides)
|
|
||||||
{
|
|
||||||
texcolor = tex.CreateFace((uint)face).RGBA;
|
|
||||||
texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
|
|
||||||
texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
|
|
||||||
texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
|
|
||||||
tex.FaceTextures[face].RGBA = texcolor;
|
|
||||||
part.UpdateTextureEntry(tex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (face == ScriptBaseClass.ALL_SIDES)
|
|
||||||
{
|
|
||||||
for (uint i = 0; i < nsides; i++)
|
|
||||||
{
|
|
||||||
if (tex.FaceTextures[i] != null)
|
|
||||||
{
|
|
||||||
texcolor = tex.FaceTextures[i].RGBA;
|
|
||||||
texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
|
|
||||||
texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
|
|
||||||
texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
|
|
||||||
tex.FaceTextures[i].RGBA = texcolor;
|
|
||||||
}
|
|
||||||
texcolor = tex.DefaultTexture.RGBA;
|
|
||||||
texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
|
|
||||||
texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
|
|
||||||
texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
|
|
||||||
tex.DefaultTexture.RGBA = texcolor;
|
|
||||||
}
|
|
||||||
part.UpdateTextureEntry(tex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (face == ScriptBaseClass.ALL_SIDES)
|
|
||||||
face = SceneObjectPart.ALL_SIDES;
|
|
||||||
|
|
||||||
m_host.SetFaceColorAlpha(face, color, null);
|
m_host.SetFaceColorAlpha(face, color, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3577,7 +3538,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
public void doObjectRez(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param, bool atRoot)
|
public void doObjectRez(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param, bool atRoot)
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
|
if (string.IsNullOrEmpty(inventory) || Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float dist = (float)llVecDist(llGetPos(), pos);
|
float dist = (float)llVecDist(llGetPos(), pos);
|
||||||
|
@ -10653,7 +10614,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
texface.MaterialID = id;
|
texface.MaterialID = id;
|
||||||
part.Shape.TextureEntry = tex.GetBytes();
|
part.Shape.TextureEntry = tex.GetBytes(9);
|
||||||
m_materialsModule.RemoveMaterial(oldid);
|
m_materialsModule.RemoveMaterial(oldid);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -10710,7 +10671,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
texface.MaterialID = id;
|
texface.MaterialID = id;
|
||||||
part.Shape.TextureEntry = tex.GetBytes();
|
part.Shape.TextureEntry = tex.GetBytes(9);
|
||||||
m_materialsModule.RemoveMaterial(oldid);
|
m_materialsModule.RemoveMaterial(oldid);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -10777,7 +10738,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
texface.MaterialID = id;
|
texface.MaterialID = id;
|
||||||
part.Shape.TextureEntry = tex.GetBytes();
|
part.Shape.TextureEntry = tex.GetBytes(9);
|
||||||
m_materialsModule.RemoveMaterial(oldid);
|
m_materialsModule.RemoveMaterial(oldid);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -13945,14 +13906,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
public LSL_Key llHTTPRequest(string url, LSL_List parameters, string body)
|
public LSL_Key llHTTPRequest(string url, LSL_List parameters, string body)
|
||||||
{
|
{
|
||||||
// Partial implementation: support for parameter flags needed
|
|
||||||
// see http://wiki.secondlife.com/wiki/LlHTTPRequest
|
|
||||||
// parameter flags support are implemented in ScriptsHttpRequests.cs
|
|
||||||
// in StartHttpRequest
|
|
||||||
|
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
IHttpRequestModule httpScriptMod =
|
IHttpRequestModule httpScriptMod = m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
|
||||||
m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
|
if(httpScriptMod == null)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
if(!httpScriptMod.CheckThrottle(m_host.LocalId, m_host.OwnerID))
|
||||||
|
return UUID.Zero.ToString();
|
||||||
|
|
||||||
List<string> param = new List<string>();
|
List<string> param = new List<string>();
|
||||||
bool ok;
|
bool ok;
|
||||||
Int32 flag;
|
Int32 flag;
|
||||||
|
@ -14123,8 +14084,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpInitialRequestStatus status;
|
HttpInitialRequestStatus status;
|
||||||
UUID reqID
|
UUID reqID = httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body, out status);
|
||||||
= httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body, out status);
|
|
||||||
|
|
||||||
if (status == HttpInitialRequestStatus.DISALLOWED_BY_FILTER)
|
if (status == HttpInitialRequestStatus.DISALLOWED_BY_FILTER)
|
||||||
Error("llHttpRequest", string.Format("Request to {0} disallowed by filter", url));
|
Error("llHttpRequest", string.Format("Request to {0} disallowed by filter", url));
|
||||||
|
@ -14132,7 +14092,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
if (reqID != UUID.Zero)
|
if (reqID != UUID.Zero)
|
||||||
return reqID.ToString();
|
return reqID.ToString();
|
||||||
else
|
else
|
||||||
return null;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3643,18 +3643,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public LSL_Float osGetHealth(string avatar)
|
public void osKickAvatar(LSL_Key agentKey, string alert)
|
||||||
|
{
|
||||||
|
CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
|
||||||
|
|
||||||
|
UUID id;
|
||||||
|
if (!UUID.TryParse(agentKey, out id) || id == UUID.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ScenePresence sp = World.GetScenePresence(id);
|
||||||
|
if(sp == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// kick client...
|
||||||
|
if (alert != null)
|
||||||
|
sp.ControllingClient.Kick(alert);
|
||||||
|
|
||||||
|
// ...and close on our side
|
||||||
|
sp.Scene.CloseAgent(id, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LSL_Float osGetHealth(LSL_Key agentKey)
|
||||||
{
|
{
|
||||||
CheckThreatLevel(ThreatLevel.None, "osGetHealth");
|
CheckThreatLevel(ThreatLevel.None, "osGetHealth");
|
||||||
|
|
||||||
LSL_Float health = new LSL_Float(-1);
|
LSL_Float health = new LSL_Float(-1);
|
||||||
ScenePresence presence = World.GetScenePresence(new UUID(avatar));
|
|
||||||
|
UUID id;
|
||||||
|
if (!UUID.TryParse(agentKey, out id) || id == UUID.Zero)
|
||||||
|
return health;
|
||||||
|
|
||||||
|
ScenePresence presence = World.GetScenePresence(id);
|
||||||
if (presence != null)
|
if (presence != null)
|
||||||
health = presence.Health;
|
health = presence.Health;
|
||||||
return health;
|
return health;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void osCauseDamage(string avatar, double damage)
|
public void osCauseDamage(LSL_Key avatar, LSL_Float damage)
|
||||||
{
|
{
|
||||||
CheckThreatLevel(ThreatLevel.High, "osCauseDamage");
|
CheckThreatLevel(ThreatLevel.High, "osCauseDamage");
|
||||||
|
|
||||||
|
@ -3683,7 +3708,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void osCauseHealing(string avatar, double healing)
|
public void osCauseHealing(LSL_Key avatar, LSL_Float healing)
|
||||||
{
|
{
|
||||||
CheckThreatLevel(ThreatLevel.High, "osCauseHealing");
|
CheckThreatLevel(ThreatLevel.High, "osCauseHealing");
|
||||||
|
|
||||||
|
@ -3704,7 +3729,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
presence.setHealthWithUpdate(health);
|
presence.setHealthWithUpdate(health);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void osSetHealth(string avatar, double health)
|
public void osSetHealth(LSL_Key avatar, LSL_Float health)
|
||||||
{
|
{
|
||||||
CheckThreatLevel(ThreatLevel.High, "osSetHealth");
|
CheckThreatLevel(ThreatLevel.High, "osSetHealth");
|
||||||
|
|
||||||
|
@ -3722,7 +3747,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void osSetHealRate(string avatar, double healrate)
|
public void osSetHealRate(LSL_Key avatar, LSL_Float healrate)
|
||||||
{
|
{
|
||||||
CheckThreatLevel(ThreatLevel.High, "osSetHealRate");
|
CheckThreatLevel(ThreatLevel.High, "osSetHealRate");
|
||||||
|
|
||||||
|
@ -3737,7 +3762,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
presence.HealRate = (float)healrate;
|
presence.HealRate = (float)healrate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LSL_Float osGetHealRate(string avatar)
|
public LSL_Float osGetHealRate(LSL_Key avatar)
|
||||||
{
|
{
|
||||||
CheckThreatLevel(ThreatLevel.None, "osGetHealRate");
|
CheckThreatLevel(ThreatLevel.None, "osGetHealRate");
|
||||||
|
|
||||||
|
@ -3864,29 +3889,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
|
return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the description from an inventory item
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="inventoryName"></param>
|
|
||||||
/// <returns>Item description</returns>
|
|
||||||
public LSL_String osGetInventoryDesc(string item)
|
|
||||||
{
|
|
||||||
CheckThreatLevel();
|
|
||||||
|
|
||||||
lock (m_host.TaskInventory)
|
|
||||||
{
|
|
||||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
|
|
||||||
{
|
|
||||||
if (inv.Value.Name == item)
|
|
||||||
{
|
|
||||||
return inv.Value.Description.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return String.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invite user to the group this object is set to
|
/// Invite user to the group this object is set to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -4849,8 +4851,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return Math.Atan2(mcross, dot);
|
return Math.Atan2(mcross, dot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//******* link sound
|
|
||||||
public void osAdjustSoundVolume(LSL_Integer linknum, LSL_Float volume)
|
public void osAdjustSoundVolume(LSL_Integer linknum, LSL_Float volume)
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
@ -5381,5 +5381,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LSL_Key osGetInventoryLastOwner(LSL_String itemNameorid)
|
||||||
|
{
|
||||||
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
|
TaskInventoryItem item = null;
|
||||||
|
UUID itemID;
|
||||||
|
if (UUID.TryParse(itemNameorid, out itemID))
|
||||||
|
item = m_host.Inventory.GetInventoryItem(itemID);
|
||||||
|
else
|
||||||
|
item = m_host.Inventory.GetInventoryItem(itemNameorid);
|
||||||
|
|
||||||
|
if (item == null)
|
||||||
|
return UUID.Zero.ToString();
|
||||||
|
|
||||||
|
UUID id = item.LastOwnerID;
|
||||||
|
if(id == UUID.Zero)
|
||||||
|
id= item.OwnerID;
|
||||||
|
return id.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LSL_String osGetInventoryName(LSL_Key itemId)
|
||||||
|
{
|
||||||
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
|
TaskInventoryItem item = null;
|
||||||
|
UUID itemID;
|
||||||
|
if (UUID.TryParse(itemId, out itemID))
|
||||||
|
item = m_host.Inventory.GetInventoryItem(itemID);
|
||||||
|
|
||||||
|
if (item == null)
|
||||||
|
return String.Empty;
|
||||||
|
|
||||||
|
return item.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LSL_String osGetInventoryDesc(LSL_String itemNameorid)
|
||||||
|
{
|
||||||
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
|
TaskInventoryItem item = null;
|
||||||
|
UUID itemID;
|
||||||
|
if (UUID.TryParse(itemNameorid, out itemID))
|
||||||
|
item = m_host.Inventory.GetInventoryItem(itemID);
|
||||||
|
else
|
||||||
|
item = m_host.Inventory.GetInventoryItem(itemNameorid);
|
||||||
|
|
||||||
|
if (item == null)
|
||||||
|
return String.Empty;
|
||||||
|
|
||||||
|
return item.Description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LSL_Key osGetLastChangedEventKey()
|
||||||
|
{
|
||||||
|
m_host.AddScriptLPS(1);
|
||||||
|
DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
|
||||||
|
if (detectedParams == null)
|
||||||
|
return String.Empty;
|
||||||
|
return detectedParams.Key.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -48,14 +48,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||||
if (m_CmdManager.m_ScriptEngine.World == null)
|
if (m_CmdManager.m_ScriptEngine.World == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IHttpRequestModule iHttpReq =
|
IHttpRequestModule iHttpReq = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
|
||||||
m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
|
if(iHttpReq == null)
|
||||||
|
return;
|
||||||
HttpRequestClass httpInfo = null;
|
|
||||||
|
|
||||||
if (iHttpReq != null)
|
|
||||||
httpInfo = (HttpRequestClass)iHttpReq.GetNextCompletedRequest();
|
|
||||||
|
|
||||||
|
HttpRequestClass httpInfo = (HttpRequestClass)iHttpReq.GetNextCompletedRequest();
|
||||||
while (httpInfo != null)
|
while (httpInfo != null)
|
||||||
{
|
{
|
||||||
//m_log.Debug("[AsyncLSL]:" + httpInfo.response_body + httpInfo.status);
|
//m_log.Debug("[AsyncLSL]:" + httpInfo.response_body + httpInfo.status);
|
||||||
|
@ -67,8 +64,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||||
// implemented here yet anyway. Should be fixed if/when maxsize
|
// implemented here yet anyway. Should be fixed if/when maxsize
|
||||||
// is supported
|
// is supported
|
||||||
|
|
||||||
iHttpReq.RemoveCompletedRequest(httpInfo.ReqID);
|
|
||||||
|
|
||||||
object[] resobj = new object[]
|
object[] resobj = new object[]
|
||||||
{
|
{
|
||||||
new LSL_Types.LSLString(httpInfo.ReqID.ToString()),
|
new LSL_Types.LSLString(httpInfo.ReqID.ToString()),
|
||||||
|
|
|
@ -380,14 +380,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||||
int osGetSimulatorMemory();
|
int osGetSimulatorMemory();
|
||||||
int osGetSimulatorMemoryKB();
|
int osGetSimulatorMemoryKB();
|
||||||
void osKickAvatar(string FirstName, string SurName, string alert);
|
void osKickAvatar(string FirstName, string SurName, string alert);
|
||||||
|
void osKickAvatar(LSL_Key agentId, string alert);
|
||||||
void osSetSpeed(string UUID, LSL_Float SpeedModifier);
|
void osSetSpeed(string UUID, LSL_Float SpeedModifier);
|
||||||
void osSetOwnerSpeed(LSL_Float SpeedModifier);
|
void osSetOwnerSpeed(LSL_Float SpeedModifier);
|
||||||
LSL_Float osGetHealth(string avatar);
|
LSL_Float osGetHealth(key agentId);
|
||||||
void osCauseHealing(string avatar, double healing);
|
void osCauseHealing(key agentId, LSL_Float healing);
|
||||||
void osSetHealth(string avatar, double health);
|
void osSetHealth(key agentId, LSL_Float health);
|
||||||
void osSetHealRate(string avatar, double health);
|
void osSetHealRate(key agentId, LSL_Float health);
|
||||||
LSL_Float osGetHealRate(string avatar);
|
LSL_Float osGetHealRate(key agentId);
|
||||||
void osCauseDamage(string avatar, double damage);
|
void osCauseDamage(key avatar, LSL_Float damage);
|
||||||
void osForceOtherSit(string avatar);
|
void osForceOtherSit(string avatar);
|
||||||
void osForceOtherSit(string avatar, string target);
|
void osForceOtherSit(string avatar, string target);
|
||||||
LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules);
|
LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules);
|
||||||
|
@ -400,8 +401,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||||
|
|
||||||
LSL_String osUnixTimeToTimestamp(LSL_Integer time);
|
LSL_String osUnixTimeToTimestamp(LSL_Integer time);
|
||||||
|
|
||||||
LSL_String osGetInventoryDesc(string item);
|
|
||||||
|
|
||||||
LSL_Integer osInviteToGroup(LSL_Key agentId);
|
LSL_Integer osInviteToGroup(LSL_Key agentId);
|
||||||
LSL_Integer osEjectFromGroup(LSL_Key agentId);
|
LSL_Integer osEjectFromGroup(LSL_Key agentId);
|
||||||
|
|
||||||
|
@ -546,5 +545,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||||
LSL_Integer osApproxEquals(vector va, vector vb, LSL_Float margin);
|
LSL_Integer osApproxEquals(vector va, vector vb, LSL_Float margin);
|
||||||
LSL_Integer osApproxEquals(rotation ra, rotation rb);
|
LSL_Integer osApproxEquals(rotation ra, rotation rb);
|
||||||
LSL_Integer osApproxEquals(rotation ra, rotation rb, LSL_Float margin);
|
LSL_Integer osApproxEquals(rotation ra, rotation rb, LSL_Float margin);
|
||||||
|
LSL_Key osGetInventoryLastOwner(LSL_String itemNameOrId);
|
||||||
|
LSL_String osGetInventoryName(LSL_Key itemId);
|
||||||
|
LSL_String osGetInventoryDesc(LSL_String itemNameOrId);
|
||||||
|
LSL_Key osGetLastChangedEventKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||||
public partial class ScriptBaseClass
|
public partial class ScriptBaseClass
|
||||||
{
|
{
|
||||||
// SCRIPTS CONSTANTS
|
// SCRIPTS CONSTANTS
|
||||||
public static readonly LSLInteger OS_APIVERSION = 2;
|
public static readonly LSLInteger OS_APIVERSION = 3;
|
||||||
|
|
||||||
public static readonly LSLInteger TRUE = 1;
|
public static readonly LSLInteger TRUE = 1;
|
||||||
public static readonly LSLInteger FALSE = 0;
|
public static readonly LSLInteger FALSE = 0;
|
||||||
|
|
|
@ -970,6 +970,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||||
m_OSSL_Functions.osKickAvatar(FirstName, SurName, alert);
|
m_OSSL_Functions.osKickAvatar(FirstName, SurName, alert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void osKickAvatar(LSL_Key agentId, string alert)
|
||||||
|
{
|
||||||
|
m_OSSL_Functions.osKickAvatar(agentId, alert);
|
||||||
|
}
|
||||||
|
|
||||||
public void osSetSpeed(string UUID, LSL_Float SpeedModifier)
|
public void osSetSpeed(string UUID, LSL_Float SpeedModifier)
|
||||||
{
|
{
|
||||||
m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier);
|
m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier);
|
||||||
|
@ -980,32 +985,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||||
m_OSSL_Functions.osSetOwnerSpeed(SpeedModifier);
|
m_OSSL_Functions.osSetOwnerSpeed(SpeedModifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LSL_Float osGetHealth(string avatar)
|
public LSL_Float osGetHealth(key avatar)
|
||||||
{
|
{
|
||||||
return m_OSSL_Functions.osGetHealth(avatar);
|
return m_OSSL_Functions.osGetHealth(avatar);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void osCauseDamage(string avatar, double damage)
|
public void osCauseDamage(key avatar, LSL_Float damage)
|
||||||
{
|
{
|
||||||
m_OSSL_Functions.osCauseDamage(avatar, damage);
|
m_OSSL_Functions.osCauseDamage(avatar, damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void osCauseHealing(string avatar, double healing)
|
public void osCauseHealing(key avatar, LSL_Float healing)
|
||||||
{
|
{
|
||||||
m_OSSL_Functions.osCauseHealing(avatar, healing);
|
m_OSSL_Functions.osCauseHealing(avatar, healing);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void osSetHealth(string avatar, double health)
|
public void osSetHealth(key avatar, LSL_Float health)
|
||||||
{
|
{
|
||||||
m_OSSL_Functions.osSetHealth(avatar, health);
|
m_OSSL_Functions.osSetHealth(avatar, health);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void osSetHealRate(string avatar, double health)
|
public void osSetHealRate(key avatar, LSL_Float health)
|
||||||
{
|
{
|
||||||
m_OSSL_Functions.osSetHealRate(avatar, health);
|
m_OSSL_Functions.osSetHealRate(avatar, health);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LSL_Float osGetHealRate(string avatar)
|
public LSL_Float osGetHealRate(key avatar)
|
||||||
{
|
{
|
||||||
return m_OSSL_Functions.osGetHealRate(avatar);
|
return m_OSSL_Functions.osGetHealRate(avatar);
|
||||||
}
|
}
|
||||||
|
@ -1055,11 +1060,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||||
return m_OSSL_Functions.osUnixTimeToTimestamp(time);
|
return m_OSSL_Functions.osUnixTimeToTimestamp(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LSL_String osGetInventoryDesc(string item)
|
|
||||||
{
|
|
||||||
return m_OSSL_Functions.osGetInventoryDesc(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LSL_Integer osInviteToGroup(LSL_Key agentId)
|
public LSL_Integer osInviteToGroup(LSL_Key agentId)
|
||||||
{
|
{
|
||||||
return m_OSSL_Functions.osInviteToGroup(agentId);
|
return m_OSSL_Functions.osInviteToGroup(agentId);
|
||||||
|
@ -1361,5 +1361,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||||
{
|
{
|
||||||
return m_OSSL_Functions.osApproxEquals(ra, rb, margin);
|
return m_OSSL_Functions.osApproxEquals(ra, rb, margin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LSL_Key osGetInventoryLastOwner(LSL_String itemNameOrId)
|
||||||
|
{
|
||||||
|
return m_OSSL_Functions.osGetInventoryLastOwner(itemNameOrId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LSL_String osGetInventoryName(LSL_Key itemId)
|
||||||
|
{
|
||||||
|
return m_OSSL_Functions.osGetInventoryName(itemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LSL_String osGetInventoryDesc(LSL_String itemNameOrId)
|
||||||
|
{
|
||||||
|
return m_OSSL_Functions.osGetInventoryDesc(itemNameOrId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LSL_Key osGetLastChangedEventKey()
|
||||||
|
{
|
||||||
|
return m_OSSL_Functions.osGetLastChangedEventKey();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -699,7 +699,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
// If min event delay is set then ignore any events untill the time has expired
|
// If min event delay is set then ignore any events untill the time has expired
|
||||||
// This currently only allows 1 event of any type in the given time period.
|
// This currently only allows 1 event of any type in the given time period.
|
||||||
// This may need extending to allow for a time for each individual event type.
|
// This may need extending to allow for a time for each individual event type.
|
||||||
if (m_eventDelayTicks != 0)
|
if (m_eventDelayTicks != 0 &&
|
||||||
|
data.EventName != "state" && data.EventName != "state_entry" && data.EventName != "state_exit"
|
||||||
|
&& data.EventName != "run_time_permissions" && data.EventName != "http_request" && data.EventName != "link_message")
|
||||||
{
|
{
|
||||||
if (DateTime.Now.Ticks < m_nextEventTimeTicks)
|
if (DateTime.Now.Ticks < m_nextEventTimeTicks)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -215,12 +215,25 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
det));
|
det));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changed(uint localID, uint change)
|
public void changed(uint localID, uint change, object parameter)
|
||||||
{
|
{
|
||||||
// Add to queue for all scripts in localID, Object pass change.
|
// Add to queue for all scripts in localID, Object pass change.
|
||||||
|
if(parameter == null)
|
||||||
|
{
|
||||||
myScriptEngine.PostObjectEvent(localID, new EventParams(
|
myScriptEngine.PostObjectEvent(localID, new EventParams(
|
||||||
"changed", new object[] { new LSL_Types.LSLInteger(change) },
|
"changed", new object[] { new LSL_Types.LSLInteger(change) },
|
||||||
new DetectParams[0]));
|
new DetectParams[0]));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (parameter is UUID)
|
||||||
|
{
|
||||||
|
DetectParams det = new DetectParams();
|
||||||
|
det.Key = (UUID)parameter;
|
||||||
|
myScriptEngine.PostObjectEvent(localID, new EventParams(
|
||||||
|
"changed", new object[] { new LSL_Types.LSLInteger(change) },
|
||||||
|
new DetectParams[] { det }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// state_entry: not processed here
|
// state_entry: not processed here
|
||||||
|
|
|
@ -88,10 +88,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
|
|
||||||
path_update = 40,
|
path_update = 40,
|
||||||
|
|
||||||
// XMRE specific
|
|
||||||
region_cross = 63,
|
|
||||||
|
|
||||||
// marks highest numbered event, ie, number of columns in seht.
|
// marks highest numbered event, ie, number of columns in seht.
|
||||||
Size = 64
|
Size = 41
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -930,6 +930,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
|
|
||||||
public void SetMinEventDelay(UUID itemID, double delay)
|
public void SetMinEventDelay(UUID itemID, double delay)
|
||||||
{
|
{
|
||||||
|
XMRInstance instance = GetInstance(itemID);
|
||||||
|
if (instance != null)
|
||||||
|
instance.MinEventDelay = delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetStartParameter(UUID itemID)
|
public int GetStartParameter(UUID itemID)
|
||||||
|
|
|
@ -182,13 +182,26 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
new DetectParams[] { det }));
|
new DetectParams[] { det }));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changed(uint localID, uint change)
|
public void changed(uint localID, uint change, object parameter)
|
||||||
{
|
{
|
||||||
int ch = (int)change;
|
int ch = (int)change;
|
||||||
// Add to queue for all scripts in localID, Object pass change.
|
// Add to queue for all scripts in localID, Object pass change.
|
||||||
this.PostObjectEvent(localID, new EventParams(
|
if(parameter == null)
|
||||||
|
{
|
||||||
|
PostObjectEvent(localID, new EventParams(
|
||||||
"changed", new object[] { ch },
|
"changed", new object[] { ch },
|
||||||
zeroDetectParams));
|
zeroDetectParams));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( parameter is UUID)
|
||||||
|
{
|
||||||
|
DetectParams det = new DetectParams();
|
||||||
|
det.Key = (UUID)parameter;
|
||||||
|
PostObjectEvent(localID, new EventParams(
|
||||||
|
"changed", new object[] { ch },
|
||||||
|
new DetectParams[] { det }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// state_entry: not processed here
|
// state_entry: not processed here
|
||||||
|
|
|
@ -422,9 +422,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
object[] saveEHArgs = this.ehArgs;
|
object[] saveEHArgs = this.ehArgs;
|
||||||
ScriptEventCode saveEventCode = this.eventCode;
|
ScriptEventCode saveEventCode = this.eventCode;
|
||||||
|
|
||||||
this.m_DetectParams = evt.DetectParams;
|
m_DetectParams = evt.DetectParams;
|
||||||
this.ehArgs = evt.Params;
|
ehArgs = evt.Params;
|
||||||
this.eventCode = evc;
|
eventCode = evc;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -432,9 +432,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
this.m_DetectParams = saveDetParams;
|
m_DetectParams = saveDetParams;
|
||||||
this.ehArgs = saveEHArgs;
|
ehArgs = saveEHArgs;
|
||||||
this.eventCode = saveEventCode;
|
eventCode = saveEventCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep waiting until we find a returnable event or timeout.
|
// Keep waiting until we find a returnable event or timeout.
|
||||||
|
|
|
@ -115,6 +115,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
m_RunOnePhase = "GetExecutionState D";
|
m_RunOnePhase = "GetExecutionState D";
|
||||||
CheckRunLockInvariants(true);
|
CheckRunLockInvariants(true);
|
||||||
|
|
||||||
|
if (m_minEventDelay != 0.0)
|
||||||
|
{
|
||||||
|
XmlElement minEventDelayN = doc.CreateElement("", "mEvtDly", "");
|
||||||
|
minEventDelayN.AppendChild(doc.CreateTextNode(m_minEventDelay.ToString()));
|
||||||
|
scriptStateN.AppendChild(minEventDelayN);
|
||||||
|
m_RunOnePhase = "GetExecutionState D";
|
||||||
|
CheckRunLockInvariants(true);
|
||||||
|
}
|
||||||
|
|
||||||
// More misc data.
|
// More misc data.
|
||||||
XmlNode permissionsN = doc.CreateElement("", "Permissions", "");
|
XmlNode permissionsN = doc.CreateElement("", "Permissions", "");
|
||||||
scriptStateN.AppendChild(permissionsN);
|
scriptStateN.AppendChild(permissionsN);
|
||||||
|
|
|
@ -527,6 +527,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
XmlElement doGblInitN = (XmlElement)scriptStateN.SelectSingleNode("DoGblInit");
|
XmlElement doGblInitN = (XmlElement)scriptStateN.SelectSingleNode("DoGblInit");
|
||||||
doGblInit = bool.Parse(doGblInitN.InnerText);
|
doGblInit = bool.Parse(doGblInitN.InnerText);
|
||||||
|
|
||||||
|
double minEventDelay = 0.0;
|
||||||
|
XmlElement minEventDelayN = (XmlElement)scriptStateN.SelectSingleNode("mEvtDly");
|
||||||
|
if(minEventDelayN != null)
|
||||||
|
minEventDelay = Double.Parse(minEventDelayN.InnerText);
|
||||||
|
|
||||||
// get values used by stuff like llDetectedGrab, etc.
|
// get values used by stuff like llDetectedGrab, etc.
|
||||||
DetectParams[] detParams = RestoreDetectParams(scriptStateN.SelectSingleNode("DetectArray"));
|
DetectParams[] detParams = RestoreDetectParams(scriptStateN.SelectSingleNode("DetectArray"));
|
||||||
|
|
||||||
|
@ -576,6 +581,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
AsyncCommandManager.CreateFromData(m_Engine,
|
AsyncCommandManager.CreateFromData(m_Engine,
|
||||||
m_LocalID, m_ItemID, m_Part.UUID,
|
m_LocalID, m_ItemID, m_Part.UUID,
|
||||||
pluginData);
|
pluginData);
|
||||||
|
|
||||||
|
MinEventDelay = minEventDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processXstate(XmlDocument doc)
|
private void processXstate(XmlDocument doc)
|
||||||
|
@ -919,6 +926,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
|
|
||||||
AsyncCommandManager.CreateFromData(m_Engine,
|
AsyncCommandManager.CreateFromData(m_Engine,
|
||||||
m_LocalID, m_ItemID, m_Part.UUID, pluginData);
|
m_LocalID, m_ItemID, m_Part.UUID, pluginData);
|
||||||
|
|
||||||
|
MinEventDelay = minEventDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void getvarNames(Dictionary<int, string> s, Dictionary<string, int> d)
|
private static void getvarNames(Dictionary<int, string> s, Dictionary<string, int> d)
|
||||||
|
|
|
@ -215,5 +215,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
// It's born ready, but will be reset when the detach is posted.
|
// It's born ready, but will be reset when the detach is posted.
|
||||||
// It will then be set again on suspend/completion
|
// It will then be set again on suspend/completion
|
||||||
private ManualResetEvent m_DetachReady = new ManualResetEvent(true);
|
private ManualResetEvent m_DetachReady = new ManualResetEvent(true);
|
||||||
|
|
||||||
|
// llmineventdelay support
|
||||||
|
double m_minEventDelay = 0.0;
|
||||||
|
double m_nextEventTime = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,6 +298,24 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double MinEventDelay
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_minEventDelay;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value > 0.001)
|
||||||
|
m_minEventDelay = value;
|
||||||
|
else
|
||||||
|
m_minEventDelay = 0.0;
|
||||||
|
|
||||||
|
m_nextEventTime = 0.0; // reset it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public SceneObjectPart SceneObject
|
public SceneObjectPart SceneObject
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
@ -63,8 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
*/
|
*/
|
||||||
public void PostEvent(EventParams evt)
|
public void PostEvent(EventParams evt)
|
||||||
{
|
{
|
||||||
ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
|
ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), evt.EventName);
|
||||||
evt.EventName);
|
|
||||||
|
|
||||||
// Put event on end of event queue.
|
// Put event on end of event queue.
|
||||||
bool startIt = false;
|
bool startIt = false;
|
||||||
|
@ -86,6 +85,47 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
if(!m_Running && !construct)
|
if(!m_Running && !construct)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if(m_minEventDelay != 0)
|
||||||
|
{
|
||||||
|
switch (evc)
|
||||||
|
{
|
||||||
|
// ignore some events by time set by llMinEventDelay
|
||||||
|
case ScriptEventCode.collision:
|
||||||
|
case ScriptEventCode.land_collision:
|
||||||
|
case ScriptEventCode.listen:
|
||||||
|
case ScriptEventCode.not_at_target:
|
||||||
|
case ScriptEventCode.not_at_rot_target:
|
||||||
|
case ScriptEventCode.no_sensor:
|
||||||
|
case ScriptEventCode.sensor:
|
||||||
|
case ScriptEventCode.timer:
|
||||||
|
case ScriptEventCode.touch:
|
||||||
|
{
|
||||||
|
double now = Util.GetTimeStamp();
|
||||||
|
if (now < m_nextEventTime)
|
||||||
|
return;
|
||||||
|
m_nextEventTime = now + m_minEventDelay;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ScriptEventCode.changed:
|
||||||
|
{
|
||||||
|
const int canignore = ~(CHANGED_SCALE | CHANGED_POSITION);
|
||||||
|
int change = (int)evt.Params[0];
|
||||||
|
if(change == 0) // what?
|
||||||
|
return;
|
||||||
|
if((change & canignore) == 0)
|
||||||
|
{
|
||||||
|
double now = Util.GetTimeStamp();
|
||||||
|
if (now < m_nextEventTime)
|
||||||
|
return;
|
||||||
|
m_nextEventTime = now + m_minEventDelay;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only so many of each event type allowed to queue.
|
// Only so many of each event type allowed to queue.
|
||||||
if((uint)evc < (uint)m_EventCounts.Length)
|
if((uint)evc < (uint)m_EventCounts.Length)
|
||||||
{
|
{
|
||||||
|
@ -124,10 +164,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
for(lln2 = m_EventQueue.First; lln2 != null; lln2 = lln2.Next)
|
for(lln2 = m_EventQueue.First; lln2 != null; lln2 = lln2.Next)
|
||||||
{
|
{
|
||||||
EventParams evt2 = lln2.Value;
|
EventParams evt2 = lln2.Value;
|
||||||
ScriptEventCode evc2 = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
|
ScriptEventCode evc2 = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), evt2.EventName);
|
||||||
evt2.EventName);
|
if((evc2 != ScriptEventCode.state_entry) && (evc2 != ScriptEventCode.attach))
|
||||||
if((evc2 != ScriptEventCode.state_entry) &&
|
|
||||||
(evc2 != ScriptEventCode.attach))
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(lln2 == null)
|
if(lln2 == null)
|
||||||
|
|
|
@ -757,6 +757,14 @@ namespace OpenSim.Services.LLLoginService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//find a exact match
|
||||||
|
foreach(GridRegion r in regions)
|
||||||
|
{
|
||||||
|
if(string.Equals(regionName, r.RegionName, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
// else, whatever
|
||||||
return regions[0];
|
return regions[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Binary file not shown.
|
@ -661,6 +661,25 @@
|
||||||
; many simultaneous requests, default is 30 and is currently applied only to assets
|
; many simultaneous requests, default is 30 and is currently applied only to assets
|
||||||
;MaxRequestConcurrency = 30
|
;MaxRequestConcurrency = 30
|
||||||
|
|
||||||
|
[ScriptsHttpRequestModule]
|
||||||
|
; options for llHttpRequest
|
||||||
|
|
||||||
|
; max number of concurrent connections per instance (all scenes), default 8
|
||||||
|
; MaxPoolThreads = 8
|
||||||
|
|
||||||
|
; max requests per second for all scripts on a prim, default 1
|
||||||
|
;PrimRequestsPerSec = 1.0
|
||||||
|
; initial unthrottled burst for all scripts on a prim, default 3
|
||||||
|
;PrimRequestsBurst = 3.0
|
||||||
|
|
||||||
|
; max requests per second for the objects owner (per instance), default 25
|
||||||
|
;PrimOwnerRequestsPerSec = 25.0
|
||||||
|
; initial unthrottled burst for the objects owner (per instance), default 5
|
||||||
|
;PrimOwnerRequestsBurst = 5.0
|
||||||
|
|
||||||
|
; requests timeout in miliseconds, range 200 to 60000, default 30000
|
||||||
|
;RequestsTimeOut = 30000
|
||||||
|
|
||||||
[AccessControl]
|
[AccessControl]
|
||||||
; Viewer-based access control. |-separated list of allowed viewers.
|
; Viewer-based access control. |-separated list of allowed viewers.
|
||||||
; AllowedClients = ""
|
; AllowedClients = ""
|
||||||
|
@ -728,17 +747,6 @@
|
||||||
;texture_default = 18500
|
;texture_default = 18500
|
||||||
;asset_default = 10500
|
;asset_default = 10500
|
||||||
|
|
||||||
; Configures how ObjectUpdates are aggregated. These numbers
|
|
||||||
; do not literally mean how many updates will be put in each
|
|
||||||
; packet that goes over the wire, as packets are
|
|
||||||
; automatically split on a 1400 byte boundary. These control
|
|
||||||
; the balance between responsiveness of interest list updates
|
|
||||||
; and total throughput. Higher numbers will ensure more full-
|
|
||||||
; sized packets and faster sending of data, but more delay in
|
|
||||||
; updating interest lists
|
|
||||||
;
|
|
||||||
;PrimUpdatesPerCallback = 100
|
|
||||||
|
|
||||||
; TextureSendLimit determines how many packets will be put on
|
; TextureSendLimit determines how many packets will be put on
|
||||||
; the outgoing queue each cycle. Like the settings above, this
|
; the outgoing queue each cycle. Like the settings above, this
|
||||||
; is a balance between responsiveness to priority updates and
|
; is a balance between responsiveness to priority updates and
|
||||||
|
@ -748,16 +756,6 @@
|
||||||
;
|
;
|
||||||
;TextureSendLimit = 20
|
;TextureSendLimit = 20
|
||||||
|
|
||||||
; CannibalizeTextureRate allows bandwidth to be moved from the
|
|
||||||
; UDP texture throttle to the task throttle. Since most viewers
|
|
||||||
; use HTTP textures, this provides a means of using what is largely
|
|
||||||
; unused bandwidth in the total throttle. The value is the proportion
|
|
||||||
; of the texture rate to move to the task queue. It must be between
|
|
||||||
; 0.0 (none of the bandwidth is cannibalized) and 0.9 (90% of the
|
|
||||||
; bandwidth is grabbed)
|
|
||||||
;
|
|
||||||
; CannibalizeTextureRate = 0.5
|
|
||||||
|
|
||||||
; Quash and remove any light properties from attachments not on the
|
; Quash and remove any light properties from attachments not on the
|
||||||
; hands. This allows flashlights and lanterns to function, but kills
|
; hands. This allows flashlights and lanterns to function, but kills
|
||||||
; silly vanity "Facelights" dead. Sorry, head mounted miner's lamps
|
; silly vanity "Facelights" dead. Sorry, head mounted miner's lamps
|
||||||
|
@ -802,6 +800,7 @@
|
||||||
Cap_GetTexture = "localhost"
|
Cap_GetTexture = "localhost"
|
||||||
Cap_GetMesh = "localhost"
|
Cap_GetMesh = "localhost"
|
||||||
Cap_GetMesh2 = "localhost"
|
Cap_GetMesh2 = "localhost"
|
||||||
|
; Cap_GetAsset = "localhost" DO not ucoment this line. Some popular viewers still dont do it right for opensim. Here to easy testing
|
||||||
Cap_GetObjectCost = ""
|
Cap_GetObjectCost = ""
|
||||||
Cap_GetObjectPhysicsData = ""
|
Cap_GetObjectPhysicsData = ""
|
||||||
Cap_GroupProposalBallot = ""
|
Cap_GroupProposalBallot = ""
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
20392e48-fad2-094e-bc5b-cda003a1e940
|
||||||
<llsd><map><key>llsd-lsl-syntax-version</key><integer>2</integer>
|
<llsd><map><key>llsd-lsl-syntax-version</key><integer>2</integer>
|
||||||
<key>controls</key>
|
<key>controls</key>
|
||||||
<map>
|
<map>
|
||||||
|
@ -1513,7 +1513,7 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
</map>
|
</map>
|
||||||
<key>OS_APIVERSION</key><map>
|
<key>OS_APIVERSION</key><map>
|
||||||
<key>type</key><string>integer</string>
|
<key>type</key><string>integer</string>
|
||||||
<key>value</key><string>2</string>
|
<key>value</key><string>3</string>
|
||||||
</map>
|
</map>
|
||||||
<key>OS_ATTACH_MSG_ALL</key><map>
|
<key>OS_ATTACH_MSG_ALL</key><map>
|
||||||
<key>type</key><string>integer</string>
|
<key>type</key><string>integer</string>
|
||||||
|
@ -6114,17 +6114,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<map>
|
<map>
|
||||||
<key>return</key><string>integer</string>
|
<key>return</key><string>integer</string>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>va</key><map><key>type</key><string>vector</string></map></map>
|
<map><key>a</key><map><key>type</key><string>float</string></map></map>
|
||||||
<map><key>vb</key><map><key>type</key><string>vector</string></map></map>
|
<map><key>b</key><map><key>type</key><string>float</string></map></map>
|
||||||
<map><key>margin</key><map><key>type</key><string>float</string></map></map>
|
|
||||||
</array>
|
|
||||||
</map>
|
|
||||||
<key>osApproxEquals</key>
|
|
||||||
<map>
|
|
||||||
<key>return</key><string>integer</string>
|
|
||||||
<key>arguments</key><array>
|
|
||||||
<map><key>va</key><map><key>type</key><string>vector</string></map></map>
|
|
||||||
<map><key>vb</key><map><key>type</key><string>vector</string></map></map>
|
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
<key>osApproxEquals</key>
|
<key>osApproxEquals</key>
|
||||||
|
@ -6140,8 +6131,17 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<map>
|
<map>
|
||||||
<key>return</key><string>integer</string>
|
<key>return</key><string>integer</string>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>a</key><map><key>type</key><string>float</string></map></map>
|
<map><key>ra</key><map><key>type</key><string>rotation</string></map></map>
|
||||||
<map><key>b</key><map><key>type</key><string>float</string></map></map>
|
<map><key>rb</key><map><key>type</key><string>rotation</string></map></map>
|
||||||
|
</array>
|
||||||
|
</map>
|
||||||
|
<key>osApproxEquals</key>
|
||||||
|
<map>
|
||||||
|
<key>return</key><string>integer</string>
|
||||||
|
<key>arguments</key><array>
|
||||||
|
<map><key>va</key><map><key>type</key><string>vector</string></map></map>
|
||||||
|
<map><key>vb</key><map><key>type</key><string>vector</string></map></map>
|
||||||
|
<map><key>margin</key><map><key>type</key><string>float</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
<key>osApproxEquals</key>
|
<key>osApproxEquals</key>
|
||||||
|
@ -6157,8 +6157,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<map>
|
<map>
|
||||||
<key>return</key><string>integer</string>
|
<key>return</key><string>integer</string>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>ra</key><map><key>type</key><string>rotation</string></map></map>
|
<map><key>va</key><map><key>type</key><string>vector</string></map></map>
|
||||||
<map><key>rb</key><map><key>type</key><string>rotation</string></map></map>
|
<map><key>vb</key><map><key>type</key><string>vector</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
<key>osAvatarName2Key</key>
|
<key>osAvatarName2Key</key>
|
||||||
|
@ -6186,14 +6186,14 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<key>osCauseDamage</key>
|
<key>osCauseDamage</key>
|
||||||
<map>
|
<map>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>avatar</key><map><key>type</key><string>string</string></map></map>
|
<map><key>avatar</key><map><key>type</key><string>key</string></map></map>
|
||||||
<map><key>damage</key><map><key>type</key><string>float</string></map></map>
|
<map><key>damage</key><map><key>type</key><string>float</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
<key>osCauseHealing</key>
|
<key>osCauseHealing</key>
|
||||||
<map>
|
<map>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>avatar</key><map><key>type</key><string>string</string></map></map>
|
<map><key>agentId</key><map><key>type</key><string>key</string></map></map>
|
||||||
<map><key>healing</key><map><key>type</key><string>float</string></map></map>
|
<map><key>healing</key><map><key>type</key><string>float</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
|
@ -6284,8 +6284,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<key>return</key><string>string</string>
|
<key>return</key><string>string</string>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>drawList</key><map><key>type</key><string>string</string></map></map>
|
<map><key>drawList</key><map><key>type</key><string>string</string></map></map>
|
||||||
<map><key>startX</key><map><key>type</key><string>integer</string></map></map>
|
|
||||||
<map><key>startY</key><map><key>type</key><string>integer</string></map></map>
|
|
||||||
<map><key>endX</key><map><key>type</key><string>integer</string></map></map>
|
<map><key>endX</key><map><key>type</key><string>integer</string></map></map>
|
||||||
<map><key>endY</key><map><key>type</key><string>integer</string></map></map>
|
<map><key>endY</key><map><key>type</key><string>integer</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
|
@ -6295,6 +6293,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<key>return</key><string>string</string>
|
<key>return</key><string>string</string>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>drawList</key><map><key>type</key><string>string</string></map></map>
|
<map><key>drawList</key><map><key>type</key><string>string</string></map></map>
|
||||||
|
<map><key>startX</key><map><key>type</key><string>integer</string></map></map>
|
||||||
|
<map><key>startY</key><map><key>type</key><string>integer</string></map></map>
|
||||||
<map><key>endX</key><map><key>type</key><string>integer</string></map></map>
|
<map><key>endX</key><map><key>type</key><string>integer</string></map></map>
|
||||||
<map><key>endY</key><map><key>type</key><string>integer</string></map></map>
|
<map><key>endY</key><map><key>type</key><string>integer</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
|
@ -6539,14 +6539,14 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<map>
|
<map>
|
||||||
<key>return</key><string>float</string>
|
<key>return</key><string>float</string>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>avatar</key><map><key>type</key><string>string</string></map></map>
|
<map><key>agentId</key><map><key>type</key><string>key</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
<key>osGetHealth</key>
|
<key>osGetHealth</key>
|
||||||
<map>
|
<map>
|
||||||
<key>return</key><string>float</string>
|
<key>return</key><string>float</string>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>avatar</key><map><key>type</key><string>string</string></map></map>
|
<map><key>agentId</key><map><key>type</key><string>key</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
<key>osGetInertiaData</key>
|
<key>osGetInertiaData</key>
|
||||||
|
@ -6558,9 +6558,28 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<map>
|
<map>
|
||||||
<key>return</key><string>string</string>
|
<key>return</key><string>string</string>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>item</key><map><key>type</key><string>string</string></map></map>
|
<map><key>itemNameOrId</key><map><key>type</key><string>string</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
|
<key>osGetInventoryLastOwner</key>
|
||||||
|
<map>
|
||||||
|
<key>return</key><string>key</string>
|
||||||
|
<key>arguments</key><array>
|
||||||
|
<map><key>itemNameOrId</key><map><key>type</key><string>string</string></map></map>
|
||||||
|
</array>
|
||||||
|
</map>
|
||||||
|
<key>osGetInventoryName</key>
|
||||||
|
<map>
|
||||||
|
<key>return</key><string>string</string>
|
||||||
|
<key>arguments</key><array>
|
||||||
|
<map><key>itemId</key><map><key>type</key><string>key</string></map></map>
|
||||||
|
</array>
|
||||||
|
</map>
|
||||||
|
<key>osGetLastChangedEventKey</key>
|
||||||
|
<map>
|
||||||
|
<key>return</key><string>key</string>
|
||||||
|
<key>arguments</key><undef/>
|
||||||
|
</map>
|
||||||
<key>osGetLinkNumber</key>
|
<key>osGetLinkNumber</key>
|
||||||
<map>
|
<map>
|
||||||
<key>return</key><string>integer</string>
|
<key>return</key><string>integer</string>
|
||||||
|
@ -6735,6 +6754,13 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<map><key>alert</key><map><key>type</key><string>string</string></map></map>
|
<map><key>alert</key><map><key>type</key><string>string</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
|
<key>osKickAvatar</key>
|
||||||
|
<map>
|
||||||
|
<key>arguments</key><array>
|
||||||
|
<map><key>agentId</key><map><key>type</key><string>key</string></map></map>
|
||||||
|
<map><key>alert</key><map><key>type</key><string>string</string></map></map>
|
||||||
|
</array>
|
||||||
|
</map>
|
||||||
<key>osLoadedCreationDate</key>
|
<key>osLoadedCreationDate</key>
|
||||||
<map>
|
<map>
|
||||||
<key>return</key><string>string</string>
|
<key>return</key><string>string</string>
|
||||||
|
@ -6839,7 +6865,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<map><key>name</key><map><key>type</key><string>string</string></map></map>
|
<map><key>name</key><map><key>type</key><string>string</string></map></map>
|
||||||
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
|
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
|
||||||
<map><key>notecard</key><map><key>type</key><string>string</string></map></map>
|
<map><key>notecard</key><map><key>type</key><string>string</string></map></map>
|
||||||
<map><key>options</key><map><key>type</key><string>integer</string></map></map>
|
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
<key>osNpcCreate</key>
|
<key>osNpcCreate</key>
|
||||||
|
@ -6850,6 +6875,7 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<map><key>name</key><map><key>type</key><string>string</string></map></map>
|
<map><key>name</key><map><key>type</key><string>string</string></map></map>
|
||||||
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
|
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
|
||||||
<map><key>notecard</key><map><key>type</key><string>string</string></map></map>
|
<map><key>notecard</key><map><key>type</key><string>string</string></map></map>
|
||||||
|
<map><key>options</key><map><key>type</key><string>integer</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
<key>osNpcGetOwner</key>
|
<key>osNpcGetOwner</key>
|
||||||
|
@ -7089,7 +7115,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<key>return</key><string>integer</string>
|
<key>return</key><string>integer</string>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>seconds</key><map><key>type</key><string>float</string></map></map>
|
<map><key>seconds</key><map><key>type</key><string>float</string></map></map>
|
||||||
<map><key>msg</key><map><key>type</key><string>string</string></map></map>
|
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
<key>osRegionRestart</key>
|
<key>osRegionRestart</key>
|
||||||
|
@ -7097,6 +7122,7 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<key>return</key><string>integer</string>
|
<key>return</key><string>integer</string>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>seconds</key><map><key>type</key><string>float</string></map></map>
|
<map><key>seconds</key><map><key>type</key><string>float</string></map></map>
|
||||||
|
<map><key>msg</key><map><key>type</key><string>string</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
<key>osReplaceString</key>
|
<key>osReplaceString</key>
|
||||||
|
@ -7199,14 +7225,14 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<key>osSetHealRate</key>
|
<key>osSetHealRate</key>
|
||||||
<map>
|
<map>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>avatar</key><map><key>type</key><string>string</string></map></map>
|
<map><key>agentId</key><map><key>type</key><string>key</string></map></map>
|
||||||
<map><key>health</key><map><key>type</key><string>float</string></map></map>
|
<map><key>health</key><map><key>type</key><string>float</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
<key>osSetHealth</key>
|
<key>osSetHealth</key>
|
||||||
<map>
|
<map>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>avatar</key><map><key>type</key><string>string</string></map></map>
|
<map><key>agentId</key><map><key>type</key><string>key</string></map></map>
|
||||||
<map><key>health</key><map><key>type</key><string>float</string></map></map>
|
<map><key>health</key><map><key>type</key><string>float</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
|
@ -7432,6 +7458,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>src</key><map><key>type</key><string>string</string></map></map>
|
<map><key>src</key><map><key>type</key><string>string</string></map></map>
|
||||||
<map><key>value</key><map><key>type</key><string>string</string></map></map>
|
<map><key>value</key><map><key>type</key><string>string</string></map></map>
|
||||||
|
<map><key>start</key><map><key>type</key><string>integer</string></map></map>
|
||||||
|
<map><key>count</key><map><key>type</key><string>integer</string></map></map>
|
||||||
<map><key>ignorecase</key><map><key>type</key><string>integer</string></map></map>
|
<map><key>ignorecase</key><map><key>type</key><string>integer</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
|
@ -7441,8 +7469,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>src</key><map><key>type</key><string>string</string></map></map>
|
<map><key>src</key><map><key>type</key><string>string</string></map></map>
|
||||||
<map><key>value</key><map><key>type</key><string>string</string></map></map>
|
<map><key>value</key><map><key>type</key><string>string</string></map></map>
|
||||||
<map><key>start</key><map><key>type</key><string>integer</string></map></map>
|
|
||||||
<map><key>count</key><map><key>type</key><string>integer</string></map></map>
|
|
||||||
<map><key>ignorecase</key><map><key>type</key><string>integer</string></map></map>
|
<map><key>ignorecase</key><map><key>type</key><string>integer</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
|
@ -7525,15 +7551,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
<key>osTeleportAgent</key>
|
<key>osTeleportAgent</key>
|
||||||
<map>
|
|
||||||
<key>arguments</key><array>
|
|
||||||
<map><key>agent</key><map><key>type</key><string>string</string></map></map>
|
|
||||||
<map><key>regionName</key><map><key>type</key><string>string</string></map></map>
|
|
||||||
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
|
|
||||||
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
|
|
||||||
</array>
|
|
||||||
</map>
|
|
||||||
<key>osTeleportAgent</key>
|
|
||||||
<map>
|
<map>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>agent</key><map><key>type</key><string>string</string></map></map>
|
<map><key>agent</key><map><key>type</key><string>string</string></map></map>
|
||||||
|
@ -7551,6 +7568,15 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
|
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
|
<key>osTeleportAgent</key>
|
||||||
|
<map>
|
||||||
|
<key>arguments</key><array>
|
||||||
|
<map><key>agent</key><map><key>type</key><string>string</string></map></map>
|
||||||
|
<map><key>regionName</key><map><key>type</key><string>string</string></map></map>
|
||||||
|
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
|
||||||
|
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
|
||||||
|
</array>
|
||||||
|
</map>
|
||||||
<key>osTeleportObject</key>
|
<key>osTeleportObject</key>
|
||||||
<map>
|
<map>
|
||||||
<key>return</key><string>integer</string>
|
<key>return</key><string>integer</string>
|
||||||
|
@ -7564,8 +7590,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<key>osTeleportOwner</key>
|
<key>osTeleportOwner</key>
|
||||||
<map>
|
<map>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
<map><key>regionX</key><map><key>type</key><string>integer</string></map></map>
|
|
||||||
<map><key>regionY</key><map><key>type</key><string>integer</string></map></map>
|
|
||||||
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
|
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
|
||||||
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
|
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
|
@ -7581,6 +7605,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
|
||||||
<key>osTeleportOwner</key>
|
<key>osTeleportOwner</key>
|
||||||
<map>
|
<map>
|
||||||
<key>arguments</key><array>
|
<key>arguments</key><array>
|
||||||
|
<map><key>regionX</key><map><key>type</key><string>integer</string></map></map>
|
||||||
|
<map><key>regionY</key><map><key>type</key><string>integer</string></map></map>
|
||||||
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
|
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
|
||||||
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
|
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
|
||||||
</array>
|
</array>
|
||||||
|
|
|
@ -155,7 +155,6 @@
|
||||||
Allow_osForceDropAttachmentAt = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
Allow_osForceDropAttachmentAt = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
||||||
Allow_osGetLinkPrimitiveParams = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
Allow_osGetLinkPrimitiveParams = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
||||||
Allow_osGetPhysicsEngineType = true
|
Allow_osGetPhysicsEngineType = true
|
||||||
Allow_osGetPrimitiveParams = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
|
||||||
Allow_osGetRegionMapTexture = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
Allow_osGetRegionMapTexture = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
||||||
Allow_osGetScriptEngineName = true
|
Allow_osGetScriptEngineName = true
|
||||||
Allow_osGetSimulatorVersion = true
|
Allow_osGetSimulatorVersion = true
|
||||||
|
@ -185,7 +184,6 @@
|
||||||
Allow_osParcelSubdivide = ESTATE_MANAGER,ESTATE_OWNER
|
Allow_osParcelSubdivide = ESTATE_MANAGER,ESTATE_OWNER
|
||||||
Allow_osRegionRestart = ESTATE_MANAGER,ESTATE_OWNER
|
Allow_osRegionRestart = ESTATE_MANAGER,ESTATE_OWNER
|
||||||
Allow_osRegionNotice = ESTATE_MANAGER,ESTATE_OWNER
|
Allow_osRegionNotice = ESTATE_MANAGER,ESTATE_OWNER
|
||||||
Allow_osSetPrimitiveParams = false
|
|
||||||
Allow_osSetProjectionParams = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
Allow_osSetProjectionParams = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||||
Allow_osSetRegionWaterHeight = ESTATE_MANAGER,ESTATE_OWNER
|
Allow_osSetRegionWaterHeight = ESTATE_MANAGER,ESTATE_OWNER
|
||||||
Allow_osSetStateEvents = false ; deprecated
|
Allow_osSetStateEvents = false ; deprecated
|
||||||
|
@ -250,6 +248,7 @@
|
||||||
; Allow_osGetLinkNumber = true
|
; Allow_osGetLinkNumber = true
|
||||||
; Allow_osGetMapTexture = true
|
; Allow_osGetMapTexture = true
|
||||||
; Allow_osGetPhysicsEngineName = true
|
; Allow_osGetPhysicsEngineName = true
|
||||||
|
; Allow_osGetPrimitiveParams = true
|
||||||
; Allow_osGetRegionSize = true
|
; Allow_osGetRegionSize = true
|
||||||
; Allow_osGetSunParam = true
|
; Allow_osGetSunParam = true
|
||||||
; Allow_osGetTerrainHeight = true
|
; Allow_osGetTerrainHeight = true
|
||||||
|
@ -275,6 +274,7 @@
|
||||||
; Allow_osSetPenCap = true
|
; Allow_osSetPenCap = true
|
||||||
; Allow_osSetPenColor = true
|
; Allow_osSetPenColor = true
|
||||||
; Allow_osSetPenSize = true
|
; Allow_osSetPenSize = true
|
||||||
|
; Allow_osSetPrimitiveParams = true
|
||||||
; Allow_osSetSoundRadius = true
|
; Allow_osSetSoundRadius = true
|
||||||
; Allow_osStopSound = true
|
; Allow_osStopSound = true
|
||||||
; Allow_osStringSubString = true
|
; Allow_osStringSubString = true
|
||||||
|
|
Loading…
Reference in New Issue