* Change Util.FireAndForget to use ThreadPool.UnsafeQueueUserWorkItem(). This avoids .NET remoting and a managed->unmanaged->managed jump. Overall, a night and day performance difference
* Initialize the LLClientView prim full update queue to the number of prims in the scene for a big performance boost * Reordered some comparisons on hot code paths for a minor speed boost * Removed an unnecessary call to the expensive DateTime.Now function (if you *have* to get the current time as opposed to Environment.TickCount, always use DateTime.UtcNow) * Don't fire the queue empty callback for the Resend category * Run the outgoing packet handler thread loop for each client synchronously. It seems like more time was being spent doing the execution asynchronously, and it made deadlocks very difficult to track down * Rewrote some expensive math in LandObject.cs * Optimized EntityManager to only lock on operations that need locking, and use TryGetValue() where possible * Only update the attachment database when an object is attached or detached * Other small misc. performance improvementsprioritization
parent
6d04a213d6
commit
142008121e
|
@ -1273,7 +1273,7 @@ namespace OpenSim.Framework
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Created to work around a limitation in Mono with nested delegates
|
/// Created to work around a limitation in Mono with nested delegates
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private class FireAndForgetWrapper
|
/*private class FireAndForgetWrapper
|
||||||
{
|
{
|
||||||
public void FireAndForget(System.Threading.WaitCallback callback)
|
public void FireAndForget(System.Threading.WaitCallback callback)
|
||||||
{
|
{
|
||||||
|
@ -1284,21 +1284,23 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
callback.BeginInvoke(obj, EndFireAndForget, callback);
|
callback.BeginInvoke(obj, EndFireAndForget, callback);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
public static void FireAndForget(System.Threading.WaitCallback callback)
|
public static void FireAndForget(System.Threading.WaitCallback callback)
|
||||||
{
|
{
|
||||||
FireAndForgetWrapper wrapper = Singleton.GetInstance<FireAndForgetWrapper>();
|
//FireAndForgetWrapper wrapper = Singleton.GetInstance<FireAndForgetWrapper>();
|
||||||
wrapper.FireAndForget(callback);
|
//wrapper.FireAndForget(callback);
|
||||||
|
System.Threading.ThreadPool.UnsafeQueueUserWorkItem(callback, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FireAndForget(System.Threading.WaitCallback callback, object obj)
|
public static void FireAndForget(System.Threading.WaitCallback callback, object obj)
|
||||||
{
|
{
|
||||||
FireAndForgetWrapper wrapper = Singleton.GetInstance<FireAndForgetWrapper>();
|
//FireAndForgetWrapper wrapper = Singleton.GetInstance<FireAndForgetWrapper>();
|
||||||
wrapper.FireAndForget(callback, obj);
|
//wrapper.FireAndForget(callback, obj);
|
||||||
|
System.Threading.ThreadPool.UnsafeQueueUserWorkItem(callback, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EndFireAndForget(IAsyncResult ar)
|
/*private static void EndFireAndForget(IAsyncResult ar)
|
||||||
{
|
{
|
||||||
System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState;
|
System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState;
|
||||||
|
|
||||||
|
@ -1306,7 +1308,7 @@ namespace OpenSim.Framework
|
||||||
catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); }
|
catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); }
|
||||||
|
|
||||||
ar.AsyncWaitHandle.Close();
|
ar.AsyncWaitHandle.Close();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
#endregion FireAndForget Threading Pattern
|
#endregion FireAndForget Threading Pattern
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,12 +321,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
private readonly IGroupsModule m_GroupsModule;
|
private readonly IGroupsModule m_GroupsModule;
|
||||||
|
|
||||||
private int m_cachedTextureSerial;
|
private int m_cachedTextureSerial;
|
||||||
private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates =
|
private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates;
|
||||||
new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
|
private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates;
|
||||||
private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates =
|
private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates;
|
||||||
new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
|
|
||||||
private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates =
|
|
||||||
new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>();
|
|
||||||
private int m_moneyBalance;
|
private int m_moneyBalance;
|
||||||
private int m_animationSequenceNumber = 1;
|
private int m_animationSequenceNumber = 1;
|
||||||
private bool m_SendLogoutPacketWhenClosing = true;
|
private bool m_SendLogoutPacketWhenClosing = true;
|
||||||
|
@ -335,7 +332,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
protected Dictionary<PacketType, PacketMethod> m_packetHandlers = new Dictionary<PacketType, PacketMethod>();
|
protected Dictionary<PacketType, PacketMethod> m_packetHandlers = new Dictionary<PacketType, PacketMethod>();
|
||||||
protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
|
protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
|
||||||
protected IScene m_scene;
|
protected Scene m_scene;
|
||||||
protected LLImageManager m_imageManager;
|
protected LLImageManager m_imageManager;
|
||||||
protected string m_firstName;
|
protected string m_firstName;
|
||||||
protected string m_lastName;
|
protected string m_lastName;
|
||||||
|
@ -408,7 +405,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LLClientView(EndPoint remoteEP, IScene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo,
|
public LLClientView(EndPoint remoteEP, Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo,
|
||||||
UUID agentId, UUID sessionId, uint circuitCode)
|
UUID agentId, UUID sessionId, uint circuitCode)
|
||||||
{
|
{
|
||||||
RegisterInterface<IClientIM>(this);
|
RegisterInterface<IClientIM>(this);
|
||||||
|
@ -418,6 +415,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
InitDefaultAnimations();
|
InitDefaultAnimations();
|
||||||
|
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
|
|
||||||
|
m_avatarTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
|
||||||
|
m_primTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
|
||||||
|
m_primFullUpdates = new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>(m_scene.Entities.Count);
|
||||||
|
|
||||||
m_assetService = m_scene.RequestModuleInterface<IAssetService>();
|
m_assetService = m_scene.RequestModuleInterface<IAssetService>();
|
||||||
m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>();
|
m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>();
|
||||||
m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>();
|
m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>();
|
||||||
|
@ -3288,10 +3290,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
|
|
||||||
Quaternion rotation = data.Rotation;
|
Quaternion rotation = data.Rotation;
|
||||||
|
if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
|
||||||
if (rotation.X == rotation.Y &&
|
|
||||||
rotation.Y == rotation.Z &&
|
|
||||||
rotation.Z == rotation.W && rotation.W == 0.0f)
|
|
||||||
rotation = Quaternion.Identity;
|
rotation = Quaternion.Identity;
|
||||||
|
|
||||||
ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data);
|
ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data);
|
||||||
|
@ -3377,15 +3376,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
|
|
||||||
Quaternion rotation = data.rotation;
|
Quaternion rotation = data.rotation;
|
||||||
|
if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
|
||||||
|
rotation = Quaternion.Identity;
|
||||||
|
|
||||||
if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD
|
if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD
|
||||||
return;
|
return;
|
||||||
if (data.primShape.PCode == 9 && data.primShape.State != 0 && data.parentID == 0)
|
if (data.primShape.State != 0 && data.parentID == 0 && data.primShape.PCode == 9)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0.0f)
|
|
||||||
rotation = Quaternion.Identity;
|
|
||||||
|
|
||||||
ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data);
|
ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data);
|
||||||
|
|
||||||
lock (m_primFullUpdates.SyncRoot)
|
lock (m_primFullUpdates.SyncRoot)
|
||||||
|
@ -3397,7 +3395,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
|
ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
|
||||||
outPacket.Header.Zerocoded = true;
|
outPacket.Header.Zerocoded = true;
|
||||||
|
|
||||||
//outPacket.RegionData = new ObjectUpdatePacket.RegionDataBlock();
|
|
||||||
outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
|
outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
|
||||||
outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
|
outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
|
||||||
|
|
||||||
|
@ -3424,13 +3421,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
|
|
||||||
Quaternion rotation = data.Rotation;
|
Quaternion rotation = data.Rotation;
|
||||||
|
if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
|
||||||
|
rotation = Quaternion.Identity;
|
||||||
|
|
||||||
if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD
|
if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0)
|
|
||||||
rotation = Quaternion.Identity;
|
|
||||||
|
|
||||||
ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data);
|
ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data);
|
||||||
|
|
||||||
lock (m_primTerseUpdates.SyncRoot)
|
lock (m_primTerseUpdates.SyncRoot)
|
||||||
|
@ -10238,10 +10234,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id);
|
internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id);
|
||||||
|
|
||||||
private MinHeap<MinHeapItem>[] heaps = new MinHeap<MinHeapItem>[1];
|
private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[1];
|
||||||
private Dictionary<uint, LookupItem> lookup_table = new Dictionary<uint, LookupItem>();
|
private Dictionary<uint, LookupItem> m_lookupTable;
|
||||||
private Comparison<TPriority> comparison;
|
private Comparison<TPriority> m_comparison;
|
||||||
private object sync_root = new object();
|
private object m_syncRoot = new object();
|
||||||
|
|
||||||
internal PriorityQueue() :
|
internal PriorityQueue() :
|
||||||
this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, Comparer<TPriority>.Default) { }
|
this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, Comparer<TPriority>.Default) { }
|
||||||
|
@ -10255,19 +10251,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
this(capacity, new Comparison<TPriority>(comparer.Compare)) { }
|
this(capacity, new Comparison<TPriority>(comparer.Compare)) { }
|
||||||
internal PriorityQueue(int capacity, Comparison<TPriority> comparison)
|
internal PriorityQueue(int capacity, Comparison<TPriority> comparison)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < heaps.Length; ++i)
|
m_lookupTable = new Dictionary<uint, LookupItem>(capacity);
|
||||||
heaps[i] = new MinHeap<MinHeapItem>(capacity);
|
|
||||||
this.comparison = comparison;
|
for (int i = 0; i < m_heaps.Length; ++i)
|
||||||
|
m_heaps[i] = new MinHeap<MinHeapItem>(capacity);
|
||||||
|
this.m_comparison = comparison;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal object SyncRoot { get { return this.sync_root; } }
|
internal object SyncRoot { get { return this.m_syncRoot; } }
|
||||||
internal int Count
|
internal int Count
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < heaps.Length; ++i)
|
for (int i = 0; i < m_heaps.Length; ++i)
|
||||||
count = heaps[i].Count;
|
count = m_heaps[i].Count;
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10276,36 +10274,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
LookupItem item;
|
LookupItem item;
|
||||||
|
|
||||||
if (lookup_table.TryGetValue(local_id, out item))
|
if (m_lookupTable.TryGetValue(local_id, out item))
|
||||||
{
|
{
|
||||||
item.Heap[item.Handle] = new MinHeapItem(priority, value, local_id, this.comparison);
|
item.Heap[item.Handle] = new MinHeapItem(priority, value, local_id, this.m_comparison);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item.Heap = heaps[0];
|
item.Heap = m_heaps[0];
|
||||||
item.Heap.Add(new MinHeapItem(priority, value, local_id, this.comparison), ref item.Handle);
|
item.Heap.Add(new MinHeapItem(priority, value, local_id, this.m_comparison), ref item.Handle);
|
||||||
lookup_table.Add(local_id, item);
|
m_lookupTable.Add(local_id, item);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TValue Peek()
|
internal TValue Peek()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < heaps.Length; ++i)
|
for (int i = 0; i < m_heaps.Length; ++i)
|
||||||
if (heaps[i].Count > 0)
|
if (m_heaps[i].Count > 0)
|
||||||
return heaps[i].Min().Value;
|
return m_heaps[i].Min().Value;
|
||||||
throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
|
throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TValue Dequeue()
|
internal TValue Dequeue()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < heaps.Length; ++i)
|
for (int i = 0; i < m_heaps.Length; ++i)
|
||||||
{
|
{
|
||||||
if (heaps[i].Count > 0)
|
if (m_heaps[i].Count > 0)
|
||||||
{
|
{
|
||||||
MinHeapItem item = heaps[i].RemoveMin();
|
MinHeapItem item = m_heaps[i].RemoveMin();
|
||||||
lookup_table.Remove(item.LocalID);
|
m_lookupTable.Remove(item.LocalID);
|
||||||
return item.Value;
|
return item.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10317,7 +10315,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
MinHeapItem item;
|
MinHeapItem item;
|
||||||
TPriority priority;
|
TPriority priority;
|
||||||
|
|
||||||
foreach (LookupItem lookup in new List<LookupItem>(this.lookup_table.Values))
|
foreach (LookupItem lookup in new List<LookupItem>(this.m_lookupTable.Values))
|
||||||
{
|
{
|
||||||
if (lookup.Heap.TryGetValue(lookup.Handle, out item))
|
if (lookup.Heap.TryGetValue(lookup.Handle, out item))
|
||||||
{
|
{
|
||||||
|
@ -10332,7 +10330,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
m_log.Warn("[LLCLIENTVIEW]: UpdatePriorityHandler returned false, dropping update");
|
m_log.Warn("[LLCLIENTVIEW]: UpdatePriorityHandler returned false, dropping update");
|
||||||
lookup.Heap.Remove(lookup.Handle);
|
lookup.Heap.Remove(lookup.Handle);
|
||||||
this.lookup_table.Remove(item.LocalID);
|
this.m_lookupTable.Remove(item.LocalID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private bool m_shuttingdown;
|
private bool m_shuttingdown;
|
||||||
private long m_lastloopprocessed;
|
|
||||||
private AssetBase m_missingImage;
|
private AssetBase m_missingImage;
|
||||||
private LLClientView m_client; //Client we're assigned to
|
private LLClientView m_client; //Client we're assigned to
|
||||||
private IAssetService m_assetCache; //Asset Cache
|
private IAssetService m_assetCache; //Asset Cache
|
||||||
|
@ -169,7 +168,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
public bool ProcessImageQueue(int packetsToSend)
|
public bool ProcessImageQueue(int packetsToSend)
|
||||||
{
|
{
|
||||||
m_lastloopprocessed = DateTime.Now.Ticks;
|
|
||||||
int packetsSent = 0;
|
int packetsSent = 0;
|
||||||
|
|
||||||
while (packetsSent < packetsToSend)
|
while (packetsSent < packetsToSend)
|
||||||
|
|
|
@ -505,10 +505,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <param name="throttleIndex">Throttle category to fire the callback
|
/// <param name="throttleIndex">Throttle category to fire the callback
|
||||||
/// for</param>
|
/// for</param>
|
||||||
private void BeginFireQueueEmpty(int throttleIndex)
|
private void BeginFireQueueEmpty(int throttleIndex)
|
||||||
|
{
|
||||||
|
// Unknown is -1 and Resend is 0. Make sure we are only firing the
|
||||||
|
// callback for categories other than those
|
||||||
|
if (throttleIndex > 0)
|
||||||
{
|
{
|
||||||
if (!m_onQueueEmptyRunning[throttleIndex])
|
if (!m_onQueueEmptyRunning[throttleIndex])
|
||||||
Util.FireAndForget(FireQueueEmpty, throttleIndex);
|
Util.FireAndForget(FireQueueEmpty, throttleIndex);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks to see if this queue empty callback is already running,
|
/// Checks to see if this queue empty callback is already running,
|
||||||
|
|
|
@ -107,7 +107,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <summary>Manages authentication for agent circuits</summary>
|
/// <summary>Manages authentication for agent circuits</summary>
|
||||||
private AgentCircuitManager m_circuitManager;
|
private AgentCircuitManager m_circuitManager;
|
||||||
/// <summary>Reference to the scene this UDP server is attached to</summary>
|
/// <summary>Reference to the scene this UDP server is attached to</summary>
|
||||||
private IScene m_scene;
|
private Scene m_scene;
|
||||||
/// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary>
|
/// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary>
|
||||||
private Location m_location;
|
private Location m_location;
|
||||||
/// <summary>The measured resolution of Environment.TickCount</summary>
|
/// <summary>The measured resolution of Environment.TickCount</summary>
|
||||||
|
@ -184,15 +184,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
public void AddScene(IScene scene)
|
public void AddScene(IScene scene)
|
||||||
{
|
{
|
||||||
if (m_scene == null)
|
if (m_scene != null)
|
||||||
{
|
|
||||||
m_scene = scene;
|
|
||||||
m_location = new Location(m_scene.RegionInfo.RegionHandle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
m_log.Error("[LLUDPSERVER]: AddScene() called on an LLUDPServer that already has a scene");
|
m_log.Error("[LLUDPSERVER]: AddScene() called on an LLUDPServer that already has a scene");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(scene is Scene))
|
||||||
|
{
|
||||||
|
m_log.Error("[LLUDPSERVER]: AddScene() called with an unrecognized scene type " + scene.GetType());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_scene = (Scene)scene;
|
||||||
|
m_location = new Location(m_scene.RegionInfo.RegionHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HandlesRegion(Location x)
|
public bool HandlesRegion(Location x)
|
||||||
|
@ -794,7 +799,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
elapsed500MS = 0;
|
elapsed500MS = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_scene.ClientManager.ForEach(
|
m_scene.ClientManager.ForEachSync(
|
||||||
delegate(IClientAPI client)
|
delegate(IClientAPI client)
|
||||||
{
|
{
|
||||||
if (client is LLClientView)
|
if (client is LLClientView)
|
||||||
|
|
|
@ -147,9 +147,10 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
client.OnParcelDwellRequest += ClientOnParcelDwellRequest;
|
client.OnParcelDwellRequest += ClientOnParcelDwellRequest;
|
||||||
client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup;
|
client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup;
|
||||||
|
|
||||||
if (m_scene.Entities.ContainsKey(client.AgentId))
|
EntityBase presenceEntity;
|
||||||
|
if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
|
||||||
{
|
{
|
||||||
SendLandUpdate((ScenePresence)m_scene.Entities[client.AgentId], true);
|
SendLandUpdate((ScenePresence)presenceEntity, true);
|
||||||
SendParcelOverlay(client);
|
SendParcelOverlay(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,9 +140,7 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Normal Calculations
|
// Normal Calculations
|
||||||
return Convert.ToInt32(
|
return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.objectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus);
|
||||||
Math.Round((Convert.ToDecimal(LandData.Area) / Convert.ToDecimal(65536)) * m_scene.objectCapacity *
|
|
||||||
Convert.ToDecimal(m_scene.RegionInfo.RegionSettings.ObjectBonus))); ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public int GetSimulatorMaxPrimCount(ILandObject thisObject)
|
public int GetSimulatorMaxPrimCount(ILandObject thisObject)
|
||||||
|
|
|
@ -92,17 +92,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public int Count
|
public int Count
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
|
||||||
lock (m_lock)
|
|
||||||
{
|
{
|
||||||
return m_eb_uuid.Count;
|
return m_eb_uuid.Count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public bool ContainsKey(UUID id)
|
public bool ContainsKey(UUID id)
|
||||||
{
|
|
||||||
lock (m_lock)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -113,11 +108,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public bool ContainsKey(uint localID)
|
public bool ContainsKey(uint localID)
|
||||||
{
|
|
||||||
lock (m_lock)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -128,7 +120,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public bool Remove(uint localID)
|
public bool Remove(uint localID)
|
||||||
{
|
{
|
||||||
|
@ -136,7 +127,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool a = m_eb_uuid.Remove(m_eb_localID[localID].UUID);
|
bool a = false;
|
||||||
|
EntityBase entity;
|
||||||
|
if (m_eb_localID.TryGetValue(localID, out entity))
|
||||||
|
a = m_eb_uuid.Remove(entity.UUID);
|
||||||
|
|
||||||
bool b = m_eb_localID.Remove(localID);
|
bool b = m_eb_localID.Remove(localID);
|
||||||
return a && b;
|
return a && b;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +149,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool a = m_eb_localID.Remove(m_eb_uuid[id].LocalId);
|
bool a = false;
|
||||||
|
EntityBase entity;
|
||||||
|
if (m_eb_uuid.TryGetValue(id, out entity))
|
||||||
|
a = m_eb_localID.Remove(entity.LocalId);
|
||||||
|
|
||||||
bool b = m_eb_uuid.Remove(id);
|
bool b = m_eb_uuid.Remove(id);
|
||||||
return a && b;
|
return a && b;
|
||||||
}
|
}
|
||||||
|
@ -206,16 +205,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
lock (m_lock)
|
lock (m_lock)
|
||||||
{
|
{
|
||||||
try
|
EntityBase entity;
|
||||||
{
|
if (m_eb_uuid.TryGetValue(id, out entity))
|
||||||
return m_eb_uuid[id];
|
return entity;
|
||||||
}
|
else
|
||||||
catch
|
|
||||||
{
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
InsertOrReplace(value);
|
InsertOrReplace(value);
|
||||||
|
@ -228,16 +224,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
lock (m_lock)
|
lock (m_lock)
|
||||||
{
|
{
|
||||||
try
|
EntityBase entity;
|
||||||
{
|
if (m_eb_localID.TryGetValue(localID, out entity))
|
||||||
return m_eb_localID[localID];
|
return entity;
|
||||||
}
|
else
|
||||||
catch
|
|
||||||
{
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
InsertOrReplace(value);
|
InsertOrReplace(value);
|
||||||
|
|
|
@ -2351,12 +2351,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
item = InventoryService.GetItem(item);
|
item = InventoryService.GetItem(item);
|
||||||
|
|
||||||
presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/);
|
presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/);
|
||||||
IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>();
|
|
||||||
if (ava != null)
|
|
||||||
{
|
|
||||||
ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return att.UUID;
|
return att.UUID;
|
||||||
}
|
}
|
||||||
|
@ -2402,12 +2396,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
|
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
|
||||||
item = InventoryService.GetItem(item);
|
item = InventoryService.GetItem(item);
|
||||||
presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/);
|
presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/);
|
||||||
|
|
||||||
if (m_AvatarFactory != null)
|
|
||||||
{
|
|
||||||
m_log.InfoFormat("[SCENE INVENTORY]: Saving avatar attachment. AgentID:{0} ItemID:{1} AttachmentPoint:{2}", remoteClient.AgentId, itemID, AttachmentPt);
|
|
||||||
m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2447,12 +2435,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (TryGetAvatar(remoteClient.AgentId, out presence))
|
if (TryGetAvatar(remoteClient.AgentId, out presence))
|
||||||
{
|
{
|
||||||
presence.Appearance.DetachAttachment(itemID);
|
presence.Appearance.DetachAttachment(itemID);
|
||||||
IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>();
|
|
||||||
if (ava != null)
|
|
||||||
{
|
|
||||||
ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Save avatar attachment information
|
||||||
|
if (m_AvatarFactory != null)
|
||||||
|
{
|
||||||
|
m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", ItemID: " + itemID);
|
||||||
|
m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sceneGraph.DetachSingleAttachmentToInv(itemID, remoteClient);
|
m_sceneGraph.DetachSingleAttachmentToInv(itemID, remoteClient);
|
||||||
|
|
|
@ -228,6 +228,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
protected IXMLRPC m_xmlrpcModule;
|
protected IXMLRPC m_xmlrpcModule;
|
||||||
protected IWorldComm m_worldCommModule;
|
protected IWorldComm m_worldCommModule;
|
||||||
protected IAvatarFactory m_AvatarFactory;
|
protected IAvatarFactory m_AvatarFactory;
|
||||||
|
public IAvatarFactory AvatarFactory
|
||||||
|
{
|
||||||
|
get { return m_AvatarFactory; }
|
||||||
|
}
|
||||||
protected IConfigSource m_config;
|
protected IConfigSource m_config;
|
||||||
protected IRegionSerialiserModule m_serialiser;
|
protected IRegionSerialiserModule m_serialiser;
|
||||||
protected IInterregionCommsOut m_interregionCommsOut;
|
protected IInterregionCommsOut m_interregionCommsOut;
|
||||||
|
|
|
@ -467,7 +467,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent)
|
protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent)
|
||||||
{
|
{
|
||||||
// If we can't take it, we can't attach it!
|
// If we can't take it, we can't attach it!
|
||||||
//
|
|
||||||
SceneObjectPart part = m_parentScene.GetSceneObjectPart(objectLocalID);
|
SceneObjectPart part = m_parentScene.GetSceneObjectPart(objectLocalID);
|
||||||
if (part == null)
|
if (part == null)
|
||||||
return;
|
return;
|
||||||
|
@ -477,9 +476,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Calls attach with a Zero position
|
// Calls attach with a Zero position
|
||||||
//
|
|
||||||
AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false);
|
AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false);
|
||||||
m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
|
m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
|
||||||
|
|
||||||
|
// Save avatar attachment information
|
||||||
|
ScenePresence presence;
|
||||||
|
if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence))
|
||||||
|
{
|
||||||
|
m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", AttachmentPoint: " + AttachmentPt);
|
||||||
|
m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SceneObjectGroup RezSingleAttachment(
|
public SceneObjectGroup RezSingleAttachment(
|
||||||
|
@ -574,7 +580,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
group.SetAttachmentPoint(Convert.ToByte(AttachmentPt));
|
group.SetAttachmentPoint((byte)AttachmentPt);
|
||||||
group.AbsolutePosition = attachPos;
|
group.AbsolutePosition = attachPos;
|
||||||
|
|
||||||
// Saves and gets itemID
|
// Saves and gets itemID
|
||||||
|
|
|
@ -899,7 +899,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
SetAttachmentPoint(Convert.ToByte(attachmentpoint));
|
SetAttachmentPoint(Convert.ToByte(attachmentpoint));
|
||||||
|
|
||||||
avatar.AddAttachment(this);
|
avatar.AddAttachment(this);
|
||||||
m_log.DebugFormat("[SOG]: Added att {0} to avie {1}", UUID, avatar.UUID);
|
m_log.Debug("[SOG]: Added attachment " + UUID + " to avatar " + avatar.UUID);
|
||||||
|
|
||||||
if (!silent)
|
if (!silent)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue