Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
commit
cade717b5f
|
@ -56,22 +56,25 @@ namespace OpenSim.Framework.Monitoring
|
||||||
Math.Round((MemoryWatchdog.AverageHeapAllocationRate * 1000) / 1024.0 / 1024, 3));
|
Math.Round((MemoryWatchdog.AverageHeapAllocationRate * 1000) / 1024.0 / 1024, 3));
|
||||||
|
|
||||||
Process myprocess = Process.GetCurrentProcess();
|
Process myprocess = Process.GetCurrentProcess();
|
||||||
if (!myprocess.HasExited)
|
// if (!myprocess.HasExited)
|
||||||
|
try
|
||||||
{
|
{
|
||||||
myprocess.Refresh();
|
myprocess.Refresh();
|
||||||
sb.AppendFormat(
|
sb.AppendFormat(
|
||||||
"Process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n",
|
"Process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n",
|
||||||
Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0),
|
Math.Round(myprocess.WorkingSet64 / 1024.0 / 1024.0),
|
||||||
Math.Round(Process.GetCurrentProcess().PagedMemorySize64 / 1024.0 / 1024.0),
|
Math.Round(myprocess.PagedMemorySize64 / 1024.0 / 1024.0),
|
||||||
Math.Round(Process.GetCurrentProcess().VirtualMemorySize64 / 1024.0 / 1024.0));
|
Math.Round(myprocess.VirtualMemorySize64 / 1024.0 / 1024.0));
|
||||||
sb.AppendFormat(
|
sb.AppendFormat(
|
||||||
"Peak process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n",
|
"Peak process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n",
|
||||||
Math.Round(Process.GetCurrentProcess().PeakWorkingSet64 / 1024.0 / 1024.0),
|
Math.Round(myprocess.PeakWorkingSet64 / 1024.0 / 1024.0),
|
||||||
Math.Round(Process.GetCurrentProcess().PeakPagedMemorySize64 / 1024.0 / 1024.0),
|
Math.Round(myprocess.PeakPagedMemorySize64 / 1024.0 / 1024.0),
|
||||||
Math.Round(Process.GetCurrentProcess().PeakVirtualMemorySize64 / 1024.0 / 1024.0));
|
Math.Round(myprocess.PeakVirtualMemorySize64 / 1024.0 / 1024.0));
|
||||||
}
|
}
|
||||||
else
|
catch
|
||||||
sb.Append("Process reported as Exited \n");
|
{ }
|
||||||
|
// else
|
||||||
|
// sb.Append("Process reported as Exited \n");
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,8 @@ namespace OpenSim.Framework.Monitoring
|
||||||
|
|
||||||
public int LogLevel { get; set; }
|
public int LogLevel { get; set; }
|
||||||
|
|
||||||
|
private object JobLock = new object();
|
||||||
|
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
|
|
||||||
public string LoggingName { get; private set; }
|
public string LoggingName { get; private set; }
|
||||||
|
@ -76,7 +78,7 @@ namespace OpenSim.Framework.Monitoring
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
private bool m_warnOverMaxQueue = true;
|
private bool m_warnOverMaxQueue = true;
|
||||||
|
|
||||||
private BlockingCollection<Job> m_jobQueue;
|
private BlockingCollection<Job> m_jobQueue = new BlockingCollection<Job>(new ConcurrentQueue<Job>(), 5000);
|
||||||
|
|
||||||
private CancellationTokenSource m_cancelSource;
|
private CancellationTokenSource m_cancelSource;
|
||||||
|
|
||||||
|
@ -95,7 +97,7 @@ namespace OpenSim.Framework.Monitoring
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
lock (this)
|
lock (JobLock)
|
||||||
{
|
{
|
||||||
if (IsRunning)
|
if (IsRunning)
|
||||||
return;
|
return;
|
||||||
|
@ -104,7 +106,6 @@ namespace OpenSim.Framework.Monitoring
|
||||||
|
|
||||||
m_finishedProcessingAfterStop.Reset();
|
m_finishedProcessingAfterStop.Reset();
|
||||||
|
|
||||||
m_jobQueue = new BlockingCollection<Job>(new ConcurrentQueue<Job>(), 5000);
|
|
||||||
m_cancelSource = new CancellationTokenSource();
|
m_cancelSource = new CancellationTokenSource();
|
||||||
|
|
||||||
WorkManager.StartThread(
|
WorkManager.StartThread(
|
||||||
|
@ -120,43 +121,22 @@ namespace OpenSim.Framework.Monitoring
|
||||||
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
lock (this)
|
lock (JobLock)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!IsRunning)
|
if (!IsRunning)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
m_log.DebugFormat("[JobEngine] Stopping {0}", Name);
|
||||||
|
|
||||||
IsRunning = false;
|
IsRunning = false;
|
||||||
|
|
||||||
int requestsLeft = m_jobQueue.Count;
|
m_finishedProcessingAfterStop.Reset();
|
||||||
|
if(m_jobQueue.Count <= 0)
|
||||||
if (requestsLeft <= 0)
|
|
||||||
{
|
|
||||||
m_cancelSource.Cancel();
|
m_cancelSource.Cancel();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.InfoFormat("[{0}]: Waiting to write {1} events after stop.", LoggingName, requestsLeft);
|
|
||||||
|
|
||||||
while (requestsLeft > 0)
|
m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop);
|
||||||
{
|
|
||||||
if (!m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop))
|
|
||||||
{
|
|
||||||
// After timeout no events have been written
|
|
||||||
if (requestsLeft == m_jobQueue.Count)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat(
|
|
||||||
"[{0}]: No requests processed after {1} ms wait. Discarding remaining {2} requests",
|
|
||||||
LoggingName, RequestProcessTimeoutOnStop, requestsLeft);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requestsLeft = m_jobQueue.Count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -245,48 +225,51 @@ namespace OpenSim.Framework.Monitoring
|
||||||
|
|
||||||
private void ProcessRequests()
|
private void ProcessRequests()
|
||||||
{
|
{
|
||||||
try
|
while(IsRunning || m_jobQueue.Count > 0)
|
||||||
{
|
{
|
||||||
while (IsRunning || m_jobQueue.Count > 0)
|
try
|
||||||
{
|
{
|
||||||
try
|
CurrentJob = m_jobQueue.Take(m_cancelSource.Token);
|
||||||
{
|
|
||||||
CurrentJob = m_jobQueue.Take(m_cancelSource.Token);
|
|
||||||
}
|
|
||||||
catch (ObjectDisposedException e)
|
|
||||||
{
|
|
||||||
// If we see this whilst not running then it may be due to a race where this thread checks
|
|
||||||
// IsRunning after the stopping thread sets it to false and disposes of the cancellation source.
|
|
||||||
if (IsRunning)
|
|
||||||
throw e;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LogLevel >= 1)
|
|
||||||
m_log.DebugFormat("[{0}]: Processing job {1}", LoggingName, CurrentJob.Name);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CurrentJob.Action();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Error(
|
|
||||||
string.Format(
|
|
||||||
"[{0}]: Job {1} failed, continuing. Exception ", LoggingName, CurrentJob.Name), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LogLevel >= 1)
|
|
||||||
m_log.DebugFormat("[{0}]: Processed job {1}", LoggingName, CurrentJob.Name);
|
|
||||||
|
|
||||||
CurrentJob = null;
|
|
||||||
}
|
}
|
||||||
}
|
catch(ObjectDisposedException e)
|
||||||
catch (OperationCanceledException)
|
{
|
||||||
{
|
// If we see this whilst not running then it may be due to a race where this thread checks
|
||||||
|
// IsRunning after the stopping thread sets it to false and disposes of the cancellation source.
|
||||||
|
if(IsRunning)
|
||||||
|
throw e;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[JobEngine] {0} stopping ignoring {1} jobs in queue",
|
||||||
|
Name,m_jobQueue.Count);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(OperationCanceledException)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(LogLevel >= 1)
|
||||||
|
m_log.DebugFormat("[{0}]: Processing job {1}",LoggingName,CurrentJob.Name);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CurrentJob.Action();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
m_log.Error(
|
||||||
|
string.Format(
|
||||||
|
"[{0}]: Job {1} failed, continuing. Exception ",LoggingName,CurrentJob.Name),e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(LogLevel >= 1)
|
||||||
|
m_log.DebugFormat("[{0}]: Processed job {1}",LoggingName,CurrentJob.Name);
|
||||||
|
|
||||||
|
CurrentJob = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Watchdog.RemoveThread(false);
|
||||||
m_finishedProcessingAfterStop.Set();
|
m_finishedProcessingAfterStop.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,4 +321,4 @@ namespace OpenSim.Framework.Monitoring
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -332,29 +332,31 @@ namespace OpenSim.Framework.Monitoring
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
List<ThreadWatchdogInfo> callbackInfos = null;
|
List<ThreadWatchdogInfo> callbackInfos = null;
|
||||||
|
List<ThreadWatchdogInfo> threadsInfo;
|
||||||
|
|
||||||
lock (m_threads)
|
lock (m_threads)
|
||||||
{
|
{
|
||||||
// get a copy since we may change m_threads
|
// get a copy since we may change m_threads
|
||||||
List<ThreadWatchdogInfo> threadsInfo = m_threads.Values.ToList();
|
threadsInfo = m_threads.Values.ToList();
|
||||||
foreach (ThreadWatchdogInfo threadInfo in threadsInfo)
|
|
||||||
|
foreach(ThreadWatchdogInfo threadInfo in threadsInfo)
|
||||||
{
|
{
|
||||||
if (threadInfo.Thread.ThreadState == ThreadState.Stopped)
|
if(threadInfo.Thread.ThreadState == ThreadState.Stopped)
|
||||||
{
|
{
|
||||||
RemoveThread(threadInfo.Thread.ManagedThreadId);
|
RemoveThread(threadInfo.Thread.ManagedThreadId);
|
||||||
|
|
||||||
if (callbackInfos == null)
|
if(callbackInfos == null)
|
||||||
callbackInfos = new List<ThreadWatchdogInfo>();
|
callbackInfos = new List<ThreadWatchdogInfo>();
|
||||||
|
|
||||||
callbackInfos.Add(threadInfo);
|
callbackInfos.Add(threadInfo);
|
||||||
}
|
}
|
||||||
else if (!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout)
|
else if(!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout)
|
||||||
{
|
{
|
||||||
threadInfo.IsTimedOut = true;
|
threadInfo.IsTimedOut = true;
|
||||||
|
|
||||||
if (threadInfo.AlarmIfTimeout)
|
if(threadInfo.AlarmIfTimeout)
|
||||||
{
|
{
|
||||||
if (callbackInfos == null)
|
if(callbackInfos == null)
|
||||||
callbackInfos = new List<ThreadWatchdogInfo>();
|
callbackInfos = new List<ThreadWatchdogInfo>();
|
||||||
|
|
||||||
// Send a copy of the watchdog info to prevent race conditions where the watchdog
|
// Send a copy of the watchdog info to prevent race conditions where the watchdog
|
||||||
|
@ -365,7 +367,7 @@ namespace OpenSim.Framework.Monitoring
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callbackInfos != null)
|
if(callbackInfos != null)
|
||||||
foreach (ThreadWatchdogInfo callbackInfo in callbackInfos)
|
foreach (ThreadWatchdogInfo callbackInfo in callbackInfos)
|
||||||
callback(callbackInfo);
|
callback(callbackInfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -753,7 +753,7 @@ namespace OpenSim.Framework
|
||||||
newy *= Constants.RegionSize;
|
newy *= Constants.RegionSize;
|
||||||
if (oldy + oldsizey + drawdist < newy)
|
if (oldy + oldsizey + drawdist < newy)
|
||||||
return true;
|
return true;
|
||||||
if (newy + newsizey + drawdist< oldy)
|
if (newy + newsizey + drawdist < oldy)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -88,7 +88,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
|
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
|
||||||
private static Thread[] m_workerThreads = null;
|
private static Thread[] m_workerThreads = null;
|
||||||
|
private static int m_NumberScenes = 0;
|
||||||
private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue =
|
private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue =
|
||||||
new OpenMetaverse.BlockingQueue<aPollRequest>();
|
new OpenMetaverse.BlockingQueue<aPollRequest>();
|
||||||
|
|
||||||
|
@ -97,13 +97,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
#region Region Module interfaceBase Members
|
#region Region Module interfaceBase Members
|
||||||
|
|
||||||
~GetMeshModule()
|
|
||||||
{
|
|
||||||
foreach (Thread t in m_workerThreads)
|
|
||||||
Watchdog.AbortThread(t.ManagedThreadId);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type ReplaceableInterface
|
public Type ReplaceableInterface
|
||||||
{
|
{
|
||||||
get { return null; }
|
get { return null; }
|
||||||
|
@ -151,7 +144,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||||
m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
|
m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
|
||||||
m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
|
m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
|
||||||
|
m_NumberScenes--;
|
||||||
m_scene = null;
|
m_scene = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +160,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
|
m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
|
||||||
m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate;
|
m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate;
|
||||||
|
|
||||||
|
m_NumberScenes++;
|
||||||
|
|
||||||
if (m_workerThreads == null)
|
if (m_workerThreads == null)
|
||||||
{
|
{
|
||||||
m_workerThreads = new Thread[2];
|
m_workerThreads = new Thread[2];
|
||||||
|
@ -174,7 +169,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
for (uint i = 0; i < 2; i++)
|
for (uint i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
m_workerThreads[i] = WorkManager.StartThread(DoMeshRequests,
|
m_workerThreads[i] = WorkManager.StartThread(DoMeshRequests,
|
||||||
String.Format("MeshWorkerThread{0}", i),
|
String.Format("GetMeshWorker{0}", i),
|
||||||
ThreadPriority.Normal,
|
ThreadPriority.Normal,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
@ -182,22 +177,29 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
int.MaxValue);
|
int.MaxValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
public void Close() { }
|
{
|
||||||
|
if(m_NumberScenes <= 0 && m_workerThreads != null)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[GetMeshModule] Closing");
|
||||||
|
foreach (Thread t in m_workerThreads)
|
||||||
|
Watchdog.AbortThread(t.ManagedThreadId);
|
||||||
|
m_queue.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string Name { get { return "GetMeshModule"; } }
|
public string Name { get { return "GetMeshModule"; } }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void DoMeshRequests()
|
private static void DoMeshRequests()
|
||||||
{
|
{
|
||||||
while (true)
|
while(true)
|
||||||
{
|
{
|
||||||
aPollRequest poolreq = m_queue.Dequeue();
|
aPollRequest poolreq = m_queue.Dequeue();
|
||||||
|
Watchdog.UpdateThread();
|
||||||
poolreq.thepoll.Process(poolreq);
|
poolreq.thepoll.Process(poolreq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,6 +295,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
UUID requestID = requestinfo.reqID;
|
UUID requestID = requestinfo.reqID;
|
||||||
|
|
||||||
|
if(m_scene.ShuttingDown)
|
||||||
|
return;
|
||||||
|
|
||||||
// If the avatar is gone, don't bother to get the texture
|
// If the avatar is gone, don't bother to get the texture
|
||||||
if (m_scene.GetScenePresence(Id) == null)
|
if (m_scene.GetScenePresence(Id) == null)
|
||||||
{
|
{
|
||||||
|
@ -386,7 +391,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
private volatile int BytesSent = 0;
|
private volatile int BytesSent = 0;
|
||||||
private int Lod3 = 0;
|
private int Lod3 = 0;
|
||||||
private int Lod2 = 0;
|
private int Lod2 = 0;
|
||||||
private int Lod1 = 0;
|
// private int Lod1 = 0;
|
||||||
private int UserSetThrottle = 0;
|
private int UserSetThrottle = 0;
|
||||||
private int UDPSetThrottle = 0;
|
private int UDPSetThrottle = 0;
|
||||||
private int CapSetThrottle = 0;
|
private int CapSetThrottle = 0;
|
||||||
|
@ -404,7 +409,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
User = puser;
|
User = puser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses)
|
public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses)
|
||||||
{
|
{
|
||||||
const float ThirtyPercent = 0.30f;
|
const float ThirtyPercent = 0.30f;
|
||||||
|
@ -486,7 +490,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
PassTime();
|
PassTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void PassTime()
|
private void PassTime()
|
||||||
{
|
{
|
||||||
currenttime = Util.EnvironmentTickCount();
|
currenttime = Util.EnvironmentTickCount();
|
||||||
|
@ -501,10 +504,11 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
{
|
{
|
||||||
Lod3 = 0;
|
Lod3 = 0;
|
||||||
Lod2 = 0;
|
Lod2 = 0;
|
||||||
Lod1 = 0;
|
// Lod1 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AlterThrottle(int setting, ScenePresence p)
|
private void AlterThrottle(int setting, ScenePresence p)
|
||||||
{
|
{
|
||||||
p.ControllingClient.SetAgentThrottleSilent((int)Throttle,setting);
|
p.ControllingClient.SetAgentThrottleSilent((int)Throttle,setting);
|
||||||
|
@ -534,6 +538,5 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,14 +76,13 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
|
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
|
||||||
private static Thread[] m_workerThreads = null;
|
private static Thread[] m_workerThreads = null;
|
||||||
|
private static int m_NumberScenes = 0;
|
||||||
private string m_Url = "localhost";
|
|
||||||
|
|
||||||
private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue =
|
private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue =
|
||||||
new OpenMetaverse.BlockingQueue<aPollRequest>();
|
new OpenMetaverse.BlockingQueue<aPollRequest>();
|
||||||
|
|
||||||
private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>();
|
private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>();
|
||||||
|
|
||||||
|
private string m_Url = "localhost";
|
||||||
|
|
||||||
#region ISharedRegionModule Members
|
#region ISharedRegionModule Members
|
||||||
|
|
||||||
|
@ -116,6 +115,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||||
m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
|
m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
|
||||||
m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
|
m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
|
||||||
|
m_NumberScenes--;
|
||||||
m_scene = null;
|
m_scene = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,6 +128,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
|
m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
|
||||||
m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate;
|
m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate;
|
||||||
|
|
||||||
|
m_NumberScenes++;
|
||||||
|
|
||||||
if (m_workerThreads == null)
|
if (m_workerThreads == null)
|
||||||
{
|
{
|
||||||
m_workerThreads = new Thread[2];
|
m_workerThreads = new Thread[2];
|
||||||
|
@ -135,7 +137,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
for (uint i = 0; i < 2; i++)
|
for (uint i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
m_workerThreads[i] = WorkManager.StartThread(DoTextureRequests,
|
m_workerThreads[i] = WorkManager.StartThread(DoTextureRequests,
|
||||||
String.Format("TextureWorkerThread{0}", i),
|
String.Format("GetTextureWorker{0}", i),
|
||||||
ThreadPriority.Normal,
|
ThreadPriority.Normal,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
@ -165,17 +167,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
adjData = pthrottles;
|
adjData = pthrottles;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0.125f converts from bits to bytes
|
|
||||||
//int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
|
||||||
//pos += 4;
|
|
||||||
// int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
|
||||||
//pos += 4;
|
|
||||||
// int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
|
||||||
// pos += 4;
|
|
||||||
// int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
|
||||||
// pos += 4;
|
|
||||||
// int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
|
||||||
// pos += 4;
|
|
||||||
pos = pos + 20;
|
pos = pos + 20;
|
||||||
int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); //pos += 4;
|
int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); //pos += 4;
|
||||||
//int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
//int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
||||||
|
@ -199,7 +190,18 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close() { }
|
public void Close()
|
||||||
|
{
|
||||||
|
if(m_NumberScenes <= 0 && m_workerThreads != null)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[GetTextureModule] Closing");
|
||||||
|
|
||||||
|
foreach (Thread t in m_workerThreads)
|
||||||
|
Watchdog.AbortThread(t.ManagedThreadId);
|
||||||
|
|
||||||
|
m_queue.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string Name { get { return "GetTextureModule"; } }
|
public string Name { get { return "GetTextureModule"; } }
|
||||||
|
|
||||||
|
@ -210,13 +212,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
~GetTextureModule()
|
|
||||||
{
|
|
||||||
foreach (Thread t in m_workerThreads)
|
|
||||||
Watchdog.AbortThread(t.ManagedThreadId);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PollServiceTextureEventArgs : PollServiceEventArgs
|
private class PollServiceTextureEventArgs : PollServiceEventArgs
|
||||||
{
|
{
|
||||||
private List<Hashtable> requests =
|
private List<Hashtable> requests =
|
||||||
|
@ -306,11 +301,13 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
UUID requestID = requestinfo.reqID;
|
UUID requestID = requestinfo.reqID;
|
||||||
|
|
||||||
|
if(m_scene.ShuttingDown)
|
||||||
|
return;
|
||||||
|
|
||||||
if (requestinfo.send503)
|
if (requestinfo.send503)
|
||||||
{
|
{
|
||||||
response = new Hashtable();
|
response = new Hashtable();
|
||||||
|
|
||||||
|
|
||||||
response["int_response_code"] = 503;
|
response["int_response_code"] = 503;
|
||||||
response["str_response_string"] = "Throttled";
|
response["str_response_string"] = "Throttled";
|
||||||
response["content_type"] = "text/plain";
|
response["content_type"] = "text/plain";
|
||||||
|
@ -412,15 +409,16 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DoTextureRequests()
|
private static void DoTextureRequests()
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
aPollRequest poolreq = m_queue.Dequeue();
|
aPollRequest poolreq = m_queue.Dequeue();
|
||||||
|
Watchdog.UpdateThread();
|
||||||
poolreq.thepoll.Process(poolreq);
|
poolreq.thepoll.Process(poolreq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class CapsDataThrottler
|
internal sealed class CapsDataThrottler
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -498,7 +496,5 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
}
|
}
|
||||||
public int ThrottleBytes;
|
public int ThrottleBytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
private static DoubleQueue<aPollRequest> m_queue =
|
private static DoubleQueue<aPollRequest> m_queue =
|
||||||
new DoubleQueue<aPollRequest>();
|
new DoubleQueue<aPollRequest>();
|
||||||
|
|
||||||
|
private static int m_NumberScenes = 0;
|
||||||
|
|
||||||
#region ISharedRegionModule Members
|
#region ISharedRegionModule Members
|
||||||
|
|
||||||
public WebFetchInvDescModule() : this(true) {}
|
public WebFetchInvDescModule() : this(true) {}
|
||||||
|
@ -145,17 +147,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
StatsManager.DeregisterStat(s_processedRequestsStat);
|
StatsManager.DeregisterStat(s_processedRequestsStat);
|
||||||
StatsManager.DeregisterStat(s_queuedRequestsStat);
|
StatsManager.DeregisterStat(s_queuedRequestsStat);
|
||||||
|
|
||||||
if (ProcessQueuedRequestsAsync)
|
m_NumberScenes--;
|
||||||
{
|
|
||||||
if (m_workerThreads != null)
|
|
||||||
{
|
|
||||||
foreach (Thread t in m_workerThreads)
|
|
||||||
Watchdog.AbortThread(t.ManagedThreadId);
|
|
||||||
|
|
||||||
m_workerThreads = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Scene = null;
|
Scene = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,6 +195,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
Scene.EventManager.OnRegisterCaps += RegisterCaps;
|
Scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||||
|
|
||||||
|
m_NumberScenes++;
|
||||||
|
|
||||||
int nworkers = 2; // was 2
|
int nworkers = 2; // was 2
|
||||||
if (ProcessQueuedRequestsAsync && m_workerThreads == null)
|
if (ProcessQueuedRequestsAsync && m_workerThreads == null)
|
||||||
{
|
{
|
||||||
|
@ -225,7 +219,23 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close() { }
|
public void Close()
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ProcessQueuedRequestsAsync)
|
||||||
|
{
|
||||||
|
if (m_NumberScenes <= 0 && m_workerThreads != null)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[WebFetchInvDescModule] Closing");
|
||||||
|
foreach (Thread t in m_workerThreads)
|
||||||
|
Watchdog.AbortThread(t.ManagedThreadId);
|
||||||
|
|
||||||
|
m_workerThreads = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string Name { get { return "WebFetchInvDescModule"; } }
|
public string Name { get { return "WebFetchInvDescModule"; } }
|
||||||
|
|
||||||
|
@ -350,6 +360,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
public void Process(aPollRequest requestinfo)
|
public void Process(aPollRequest requestinfo)
|
||||||
{
|
{
|
||||||
|
if(m_module == null || m_module.Scene == null || m_module.Scene.ShuttingDown)
|
||||||
|
return;
|
||||||
|
|
||||||
UUID requestID = requestinfo.reqID;
|
UUID requestID = requestinfo.reqID;
|
||||||
|
|
||||||
Hashtable response = new Hashtable();
|
Hashtable response = new Hashtable();
|
||||||
|
@ -425,31 +438,26 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private void DoInventoryRequests()
|
private static void DoInventoryRequests()
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
Watchdog.UpdateThread();
|
Watchdog.UpdateThread();
|
||||||
|
|
||||||
WaitProcessQueuedInventoryRequest();
|
aPollRequest poolreq = m_queue.Dequeue();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WaitProcessQueuedInventoryRequest()
|
if (poolreq != null && poolreq.thepoll != null)
|
||||||
{
|
|
||||||
aPollRequest poolreq = m_queue.Dequeue();
|
|
||||||
|
|
||||||
if (poolreq != null && poolreq.thepoll != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
poolreq.thepoll.Process(poolreq);
|
try
|
||||||
}
|
{
|
||||||
catch (Exception e)
|
poolreq.thepoll.Process(poolreq);
|
||||||
{
|
}
|
||||||
m_log.ErrorFormat(
|
catch (Exception e)
|
||||||
"[INVENTORY]: Failed to process queued inventory request {0} for {1} in {2}. Exception {3}",
|
{
|
||||||
poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", Scene.Name, e);
|
m_log.ErrorFormat(
|
||||||
|
"[INVENTORY]: Failed to process queued inventory request {0} for {1}. Exception {3}",
|
||||||
|
poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -556,6 +556,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||||
// In the future, we need to be able to do this programatically more predicably.
|
// In the future, we need to be able to do this programatically more predicably.
|
||||||
scene.EventManager.OnChatFromWorld += OnChatFromWorld;
|
scene.EventManager.OnChatFromWorld += OnChatFromWorld;
|
||||||
|
|
||||||
|
m_chatEvent.Reset();
|
||||||
scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
|
scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
|
||||||
|
|
||||||
m_chatEvent.WaitOne(60000);
|
m_chatEvent.WaitOne(60000);
|
||||||
|
@ -669,6 +670,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||||
// In the future, we need to be able to do this programatically more predicably.
|
// In the future, we need to be able to do this programatically more predicably.
|
||||||
scene.EventManager.OnChatFromWorld += OnChatFromWorld;
|
scene.EventManager.OnChatFromWorld += OnChatFromWorld;
|
||||||
|
|
||||||
|
m_chatEvent.Reset();
|
||||||
SceneObjectGroup rezzedSo
|
SceneObjectGroup rezzedSo
|
||||||
= (SceneObjectGroup)(scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest));
|
= (SceneObjectGroup)(scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest));
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||||
UUID fromID = UUID.Zero;
|
UUID fromID = UUID.Zero;
|
||||||
UUID ownerID = UUID.Zero;
|
UUID ownerID = UUID.Zero;
|
||||||
string message = c.Message;
|
string message = c.Message;
|
||||||
IScene scene = c.Scene;
|
Scene scene = c.Scene as Scene;
|
||||||
UUID destination = c.Destination;
|
UUID destination = c.Destination;
|
||||||
Vector3 fromPos = c.Position;
|
Vector3 fromPos = c.Position;
|
||||||
Vector3 regionPos = new Vector3(scene.RegionInfo.WorldLocX, scene.RegionInfo.WorldLocY, 0);
|
Vector3 regionPos = new Vector3(scene.RegionInfo.WorldLocX, scene.RegionInfo.WorldLocY, 0);
|
||||||
|
@ -217,47 +217,48 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||||
|
|
||||||
if (c.Channel == DEBUG_CHANNEL) c.Type = ChatTypeEnum.DebugChannel;
|
if (c.Channel == DEBUG_CHANNEL) c.Type = ChatTypeEnum.DebugChannel;
|
||||||
|
|
||||||
|
if(!m_scenes.Contains(scene))
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[CHAT]: message from unkown scene {0} ignored",
|
||||||
|
scene.RegionInfo.RegionName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (sourceType)
|
switch (sourceType)
|
||||||
{
|
{
|
||||||
case ChatSourceType.Agent:
|
case ChatSourceType.Agent:
|
||||||
if (!(scene is Scene))
|
ScenePresence avatar = (scene as Scene).GetScenePresence(c.Sender.AgentId);
|
||||||
{
|
fromPos = avatar.AbsolutePosition;
|
||||||
m_log.WarnFormat("[CHAT]: scene {0} is not a Scene object, cannot obtain scene presence for {1}",
|
fromName = avatar.Name;
|
||||||
scene.RegionInfo.RegionName, c.Sender.AgentId);
|
fromID = c.Sender.AgentId;
|
||||||
return;
|
if (avatar.GodLevel >= 200)
|
||||||
}
|
{ // let gods speak to outside or things may get confusing
|
||||||
ScenePresence avatar = (scene as Scene).GetScenePresence(c.Sender.AgentId);
|
fromNamePrefix = m_adminPrefix;
|
||||||
fromPos = avatar.AbsolutePosition;
|
checkParcelHide = false;
|
||||||
fromName = avatar.Name;
|
}
|
||||||
fromID = c.Sender.AgentId;
|
else
|
||||||
if (avatar.GodLevel >= 200)
|
|
||||||
{ // let gods speak to outside or things may get confusing
|
|
||||||
fromNamePrefix = m_adminPrefix;
|
|
||||||
checkParcelHide = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
checkParcelHide = true;
|
|
||||||
}
|
|
||||||
destination = UUID.Zero; // Avatars cant "SayTo"
|
|
||||||
ownerID = c.Sender.AgentId;
|
|
||||||
|
|
||||||
hidePos = fromPos;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ChatSourceType.Object:
|
|
||||||
fromID = c.SenderUUID;
|
|
||||||
|
|
||||||
if (c.SenderObject != null && c.SenderObject is SceneObjectPart)
|
|
||||||
{
|
|
||||||
ownerID = ((SceneObjectPart)c.SenderObject).OwnerID;
|
|
||||||
if (((SceneObjectPart)c.SenderObject).ParentGroup.IsAttachment)
|
|
||||||
{
|
{
|
||||||
checkParcelHide = true;
|
checkParcelHide = true;
|
||||||
hidePos = ((SceneObjectPart)c.SenderObject).ParentGroup.AbsolutePosition;
|
|
||||||
}
|
}
|
||||||
}
|
destination = UUID.Zero; // Avatars cant "SayTo"
|
||||||
break;
|
ownerID = c.Sender.AgentId;
|
||||||
|
|
||||||
|
hidePos = fromPos;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ChatSourceType.Object:
|
||||||
|
fromID = c.SenderUUID;
|
||||||
|
|
||||||
|
if (c.SenderObject != null && c.SenderObject is SceneObjectPart)
|
||||||
|
{
|
||||||
|
ownerID = ((SceneObjectPart)c.SenderObject).OwnerID;
|
||||||
|
if (((SceneObjectPart)c.SenderObject).ParentGroup.IsAttachment)
|
||||||
|
{
|
||||||
|
checkParcelHide = true;
|
||||||
|
hidePos = ((SceneObjectPart)c.SenderObject).ParentGroup.AbsolutePosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: iterate over message
|
// TODO: iterate over message
|
||||||
|
@ -275,7 +276,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||||
checkParcelHide = false;
|
checkParcelHide = false;
|
||||||
if (c.Type < ChatTypeEnum.DebugChannel && destination == UUID.Zero)
|
if (c.Type < ChatTypeEnum.DebugChannel && destination == UUID.Zero)
|
||||||
{
|
{
|
||||||
ILandObject srcland = (scene as Scene).LandChannel.GetLandObject(hidePos.X, hidePos.Y);
|
ILandObject srcland = scene.LandChannel.GetLandObject(hidePos.X, hidePos.Y);
|
||||||
if (srcland != null && !srcland.LandData.SeeAVs)
|
if (srcland != null && !srcland.LandData.SeeAVs)
|
||||||
{
|
{
|
||||||
sourceParcelID = srcland.LandData.GlobalID;
|
sourceParcelID = srcland.LandData.GlobalID;
|
||||||
|
@ -284,50 +285,42 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Scene s in m_scenes)
|
scene.ForEachScenePresence(
|
||||||
{
|
delegate(ScenePresence presence)
|
||||||
// This should use ForEachClient, but clients don't have a position.
|
{
|
||||||
// If camera is moved into client, then camera position can be used
|
if (destination != UUID.Zero && presence.UUID != destination)
|
||||||
// MT: No, it can't, as chat is heard from the avatar position, not
|
return;
|
||||||
// the camera position.
|
|
||||||
|
|
||||||
s.ForEachScenePresence(
|
if(presence.IsChildAgent)
|
||||||
delegate(ScenePresence presence)
|
|
||||||
{
|
|
||||||
if (destination != UUID.Zero && presence.UUID != destination)
|
|
||||||
return;
|
|
||||||
ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
|
|
||||||
if (Presencecheck != null)
|
|
||||||
{
|
{
|
||||||
// This will pass all chat from objects. Not
|
if(checkParcelHide)
|
||||||
// perfect, but it will do. For now. Better
|
return;
|
||||||
// than the prior behavior of muting all
|
if (TrySendChatMessage(presence, fromPos, regionPos, fromID,
|
||||||
// objects on a parcel with access restrictions
|
ownerID, fromNamePrefix + fromName, c.Type,
|
||||||
if (checkParcelHide)
|
message, sourceType, (destination != UUID.Zero)))
|
||||||
{
|
receiverIDs.Add(presence.UUID);
|
||||||
if (sourceParcelID != Presencecheck.LandData.GlobalID && presence.GodLevel < 200)
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)
|
|
||||||
{
|
|
||||||
if (TrySendChatMessage(presence, fromPos, regionPos, fromID,
|
|
||||||
ownerID, fromNamePrefix + fromName, c.Type,
|
|
||||||
message, sourceType, (destination != UUID.Zero)))
|
|
||||||
receiverIDs.Add(presence.UUID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(!checkParcelHide && (presence.IsChildAgent))
|
|
||||||
|
ILandObject Presencecheck = scene.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
|
||||||
|
if (Presencecheck != null)
|
||||||
|
{
|
||||||
|
if (checkParcelHide)
|
||||||
|
{
|
||||||
|
if (sourceParcelID != Presencecheck.LandData.GlobalID && presence.GodLevel < 200)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)
|
||||||
{
|
{
|
||||||
if (TrySendChatMessage(presence, fromPos, regionPos, fromID,
|
if (TrySendChatMessage(presence, fromPos, regionPos, fromID,
|
||||||
ownerID, fromNamePrefix + fromName, c.Type,
|
ownerID, fromNamePrefix + fromName, c.Type,
|
||||||
message, sourceType, (destination != UUID.Zero)))
|
message, sourceType, (destination != UUID.Zero)))
|
||||||
receiverIDs.Add(presence.UUID);
|
receiverIDs.Add(presence.UUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
(scene as Scene).EventManager.TriggerOnChatToClients(
|
scene.EventManager.TriggerOnChatToClients(
|
||||||
fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully);
|
fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1049,6 +1049,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
sp.HasMovedAway(!(OutSideViewRange || logout));
|
sp.HasMovedAway(!(OutSideViewRange || logout));
|
||||||
|
|
||||||
|
ulong sourceRegionHandle = sp.RegionHandle;
|
||||||
|
|
||||||
// Now let's make it officially a child agent
|
// Now let's make it officially a child agent
|
||||||
sp.MakeChildAgent(destinationHandle);
|
sp.MakeChildAgent(destinationHandle);
|
||||||
|
|
||||||
|
@ -1066,8 +1068,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
// This sleep can be increased if necessary. However, whilst it's active,
|
// This sleep can be increased if necessary. However, whilst it's active,
|
||||||
// an agent cannot teleport back to this region if it has teleported away.
|
// an agent cannot teleport back to this region if it has teleported away.
|
||||||
Thread.Sleep(2000);
|
Thread.Sleep(2000);
|
||||||
if (m_eqModule != null && !sp.DoNotCloseAfterTeleport)
|
// if (m_eqModule != null && !sp.DoNotCloseAfterTeleport)
|
||||||
m_eqModule.DisableSimulator(sp.RegionHandle,sp.UUID);
|
// m_eqModule.DisableSimulator(sourceRegionHandle,sp.UUID);
|
||||||
Thread.Sleep(500);
|
Thread.Sleep(500);
|
||||||
sp.Scene.CloseAgent(sp.UUID, false);
|
sp.Scene.CloseAgent(sp.UUID, false);
|
||||||
}
|
}
|
||||||
|
@ -1194,11 +1196,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
//HG hook
|
//HG hook
|
||||||
AgentHasMovedAway(sp, logout);
|
AgentHasMovedAway(sp, logout);
|
||||||
|
|
||||||
|
ulong sourceRegionHandle = sp.RegionHandle;
|
||||||
|
|
||||||
// Now let's make it officially a child agent
|
// Now let's make it officially a child agent
|
||||||
sp.MakeChildAgent(destinationHandle);
|
sp.MakeChildAgent(destinationHandle);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
|
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
|
||||||
// go by HG hook
|
// go by HG hook
|
||||||
if (NeedsClosing(reg, OutSideViewRange))
|
if (NeedsClosing(reg, OutSideViewRange))
|
||||||
|
@ -1213,10 +1215,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
// DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR
|
// DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR
|
||||||
// IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS.
|
// IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS.
|
||||||
|
|
||||||
Thread.Sleep(14000);
|
Thread.Sleep(15000);
|
||||||
if (m_eqModule != null && !sp.DoNotCloseAfterTeleport)
|
// if (m_eqModule != null && !sp.DoNotCloseAfterTeleport)
|
||||||
m_eqModule.DisableSimulator(sp.RegionHandle,sp.UUID);
|
// m_eqModule.DisableSimulator(sourceRegionHandle,sp.UUID);
|
||||||
Thread.Sleep(1000);
|
// Thread.Sleep(1000);
|
||||||
|
|
||||||
// OK, it got this agent. Let's close everything
|
// OK, it got this agent. Let's close everything
|
||||||
// If we shouldn't close the agent due to some other region renewing the connection
|
// If we shouldn't close the agent due to some other region renewing the connection
|
||||||
|
@ -1802,6 +1804,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
// Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
|
// Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
|
||||||
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
|
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
agent.CloseChildAgents(false, neighbourRegion.RegionHandle, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY);
|
||||||
|
|
||||||
// this may need the attachments
|
// this may need the attachments
|
||||||
|
|
||||||
agent.HasMovedAway(true);
|
agent.HasMovedAway(true);
|
||||||
|
@ -1811,9 +1817,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
// FIXME: Possibly this should occur lower down after other commands to close other agents,
|
// FIXME: Possibly this should occur lower down after other commands to close other agents,
|
||||||
// but not sure yet what the side effects would be.
|
// but not sure yet what the side effects would be.
|
||||||
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
|
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
|
||||||
|
|
||||||
agent.CloseChildAgents(false, neighbourRegion.RegionHandle, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY);
|
|
||||||
|
|
||||||
// TODO: Check since what version this wasn't needed anymore. May be as old as 0.6
|
// TODO: Check since what version this wasn't needed anymore. May be as old as 0.6
|
||||||
/*
|
/*
|
||||||
// Backwards compatibility. Best effort
|
// Backwards compatibility. Best effort
|
||||||
|
|
|
@ -182,6 +182,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}",
|
// "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}",
|
||||||
// uuid, remote_client.Name);
|
// uuid, remote_client.Name);
|
||||||
|
if(m_Scenes.Count <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
|
if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
|
||||||
{
|
{
|
||||||
|
@ -288,6 +290,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
public List<UserData> GetUserData(string query, int page_size, int page_number)
|
public List<UserData> GetUserData(string query, int page_size, int page_number)
|
||||||
{
|
{
|
||||||
|
if(m_Scenes.Count <= 0)
|
||||||
|
return new List<UserData>();;
|
||||||
|
|
||||||
// search the user accounts service
|
// search the user accounts service
|
||||||
List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
|
List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
|
||||||
|
|
||||||
|
@ -380,6 +385,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
/// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param>
|
/// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param>
|
||||||
private bool TryGetUserNamesFromServices(UUID uuid, string[] names)
|
private bool TryGetUserNamesFromServices(UUID uuid, string[] names)
|
||||||
{
|
{
|
||||||
|
if(m_Scenes.Count <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid);
|
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid);
|
||||||
|
|
||||||
if (account != null)
|
if (account != null)
|
||||||
|
@ -445,6 +453,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
public UUID GetUserIdByName(string firstName, string lastName)
|
public UUID GetUserIdByName(string firstName, string lastName)
|
||||||
{
|
{
|
||||||
|
if(m_Scenes.Count <= 0)
|
||||||
|
return UUID.Zero;
|
||||||
|
|
||||||
// TODO: Optimize for reverse lookup if this gets used by non-console commands.
|
// TODO: Optimize for reverse lookup if this gets used by non-console commands.
|
||||||
lock (m_UserCache)
|
lock (m_UserCache)
|
||||||
{
|
{
|
||||||
|
@ -555,6 +566,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
#region Cache Management
|
#region Cache Management
|
||||||
public bool GetUser(UUID uuid, out UserData userdata)
|
public bool GetUser(UUID uuid, out UserData userdata)
|
||||||
{
|
{
|
||||||
|
if(m_Scenes.Count <= 0)
|
||||||
|
{
|
||||||
|
userdata = new UserData();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
lock (m_UserCache)
|
lock (m_UserCache)
|
||||||
{
|
{
|
||||||
if (m_UserCache.TryGetValue(uuid, out userdata))
|
if (m_UserCache.TryGetValue(uuid, out userdata))
|
||||||
|
|
|
@ -94,7 +94,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
|
||||||
if (config == null)
|
if (config == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime", "60"));
|
int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime"));
|
||||||
if (refreshminutes < 0)
|
if (refreshminutes < 0)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: Negative refresh time given in config. Module disabled.");
|
m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: Negative refresh time given in config. Module disabled.");
|
||||||
|
|
|
@ -112,7 +112,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
float rotation = 0f;
|
float rotation = 0f;
|
||||||
Vector3 rotationCenter = new Vector3(Scene.RegionInfo.RegionSizeX / 2f, Scene.RegionInfo.RegionSizeY / 2f, 0);
|
Vector3 rotationCenter = new Vector3(Scene.RegionInfo.RegionSizeX / 2f, Scene.RegionInfo.RegionSizeY / 2f, 0);
|
||||||
Vector3 boundingOrigin = new Vector3(0f, 0f, 0f);
|
Vector3 boundingOrigin = new Vector3(0f, 0f, 0f);
|
||||||
Vector3 boundingSize = new Vector3(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY, Constants.RegionHeight);
|
Vector3 boundingSize = new Vector3(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY, float.MaxValue);
|
||||||
bool debug = false;
|
bool debug = false;
|
||||||
|
|
||||||
OptionSet options = new OptionSet();
|
OptionSet options = new OptionSet();
|
||||||
|
@ -183,7 +183,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
boundingSize = v == null ? new Vector3(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY, Constants.RegionHeight) : Vector3.Parse(v);
|
boundingSize = v == null ? new Vector3(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY, float.MaxValue) : Vector3.Parse(v);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|
|
@ -174,6 +174,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public SynchronizeSceneHandler SynchronizeScene;
|
public SynchronizeSceneHandler SynchronizeScene;
|
||||||
|
|
||||||
|
public bool ClampNegativeZ
|
||||||
|
{
|
||||||
|
get { return m_clampNegativeZ; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool m_clampNegativeZ = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to prevent simultaneous calls to code that adds and removes agents.
|
/// Used to prevent simultaneous calls to code that adds and removes agents.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -524,11 +531,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// private int m_lastUpdate;
|
// private int m_lastUpdate;
|
||||||
private bool m_firstHeartbeat = true;
|
private bool m_firstHeartbeat = true;
|
||||||
|
|
||||||
private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time;
|
// private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time;
|
||||||
private bool m_reprioritizationEnabled = true;
|
// private bool m_reprioritizationEnabled = true;
|
||||||
private double m_reprioritizationInterval = 5000.0;
|
// private double m_reprioritizationInterval = 5000.0;
|
||||||
private double m_rootReprioritizationDistance = 10.0;
|
// private double m_rootReprioritizationDistance = 10.0;
|
||||||
private double m_childReprioritizationDistance = 20.0;
|
// private double m_childReprioritizationDistance = 20.0;
|
||||||
|
|
||||||
|
|
||||||
private Timer m_mapGenerationTimer = new Timer();
|
private Timer m_mapGenerationTimer = new Timer();
|
||||||
|
@ -1029,6 +1036,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_clampPrimSize = true;
|
m_clampPrimSize = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_clampNegativeZ = startupConfig.GetBoolean("ClampNegativeZ", m_clampNegativeZ);
|
||||||
|
|
||||||
m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete",m_useTrashOnDelete);
|
m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete",m_useTrashOnDelete);
|
||||||
m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries);
|
m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries);
|
||||||
m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings);
|
m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings);
|
||||||
|
@ -1472,11 +1481,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
|
m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
|
||||||
|
|
||||||
StatsReporter.Close();
|
|
||||||
|
|
||||||
|
StatsReporter.Close();
|
||||||
m_restartTimer.Stop();
|
m_restartTimer.Stop();
|
||||||
m_restartTimer.Close();
|
m_restartTimer.Close();
|
||||||
|
|
||||||
|
if (!GridService.DeregisterRegion(RegionInfo.RegionID))
|
||||||
|
m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
|
||||||
|
|
||||||
// Kick all ROOT agents with the message, 'The simulator is going down'
|
// Kick all ROOT agents with the message, 'The simulator is going down'
|
||||||
ForEachScenePresence(delegate(ScenePresence avatar)
|
ForEachScenePresence(delegate(ScenePresence avatar)
|
||||||
{
|
{
|
||||||
|
@ -1503,13 +1515,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
EventManager.TriggerSceneShuttingDown(this);
|
EventManager.TriggerSceneShuttingDown(this);
|
||||||
|
|
||||||
m_log.Debug("[SCENE]: Persisting changed objects");
|
m_log.Debug("[SCENE]: Persisting changed objects");
|
||||||
|
Backup(true);
|
||||||
|
|
||||||
Backup(false);
|
|
||||||
m_sceneGraph.Close();
|
m_sceneGraph.Close();
|
||||||
|
|
||||||
if (!GridService.DeregisterRegion(RegionInfo.RegionID))
|
|
||||||
m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
|
|
||||||
|
|
||||||
base.Close();
|
base.Close();
|
||||||
|
|
||||||
// XEngine currently listens to the EventManager.OnShutdown event to trigger script stop and persistence.
|
// XEngine currently listens to the EventManager.OnShutdown event to trigger script stop and persistence.
|
||||||
|
@ -1619,6 +1628,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
|
Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
|
||||||
m_lastFrameTick = Util.EnvironmentTickCount();
|
m_lastFrameTick = Util.EnvironmentTickCount();
|
||||||
Update(-1);
|
Update(-1);
|
||||||
|
|
||||||
|
Watchdog.RemoveThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Maintenance()
|
private void Maintenance()
|
||||||
|
|
|
@ -296,13 +296,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
|
Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
|
||||||
sceneObject.RootPart.GroupPosition.Y,
|
sceneObject.RootPart.GroupPosition.Y,
|
||||||
sceneObject.RootPart.GroupPosition.Z);
|
sceneObject.RootPart.GroupPosition.Z);
|
||||||
if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || npos.Z < 0.0 ||
|
bool clampZ = m_parentScene.ClampNegativeZ;
|
||||||
|
|
||||||
|
if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || (npos.Z < 0.0 && clampZ) ||
|
||||||
npos.X > regionSizeX ||
|
npos.X > regionSizeX ||
|
||||||
npos.Y > regionSizeY))
|
npos.Y > regionSizeY))
|
||||||
{
|
{
|
||||||
if (npos.X < 0.0) npos.X = 1.0f;
|
if (npos.X < 0.0) npos.X = 1.0f;
|
||||||
if (npos.Y < 0.0) npos.Y = 1.0f;
|
if (npos.Y < 0.0) npos.Y = 1.0f;
|
||||||
if (npos.Z < 0.0) npos.Z = 0.0f;
|
if (npos.Z < 0.0 && clampZ) npos.Z = 0.0f;
|
||||||
if (npos.X > regionSizeX) npos.X = regionSizeX - 1.0f;
|
if (npos.X > regionSizeX) npos.X = regionSizeX - 1.0f;
|
||||||
if (npos.Y > regionSizeY) npos.Y = regionSizeY - 1.0f;
|
if (npos.Y > regionSizeY) npos.Y = regionSizeY - 1.0f;
|
||||||
|
|
||||||
|
|
|
@ -4143,8 +4143,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
byebyeRegions.Add(handle);
|
byebyeRegions.Add(handle);
|
||||||
// this should not be here
|
// this should not be here
|
||||||
if(eventQueue != null)
|
// if(eventQueue != null)
|
||||||
eventQueue.DisableSimulator(handle,UUID);
|
/// eventQueue.DisableSimulator(handle,UUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4154,8 +4154,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
byebyeRegions.Add(handle);
|
byebyeRegions.Add(handle);
|
||||||
// this should not be here
|
// this should not be here
|
||||||
if(eventQueue != null)
|
// if(eventQueue != null)
|
||||||
eventQueue.DisableSimulator(handle,UUID);
|
// eventQueue.DisableSimulator(handle,UUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,6 +196,7 @@ default
|
||||||
|
|
||||||
EventParams ep = new EventParams("touch_start", new Object[] { new LSL_Types.LSLInteger(1) }, det);
|
EventParams ep = new EventParams("touch_start", new Object[] { new LSL_Types.LSLInteger(1) }, det);
|
||||||
|
|
||||||
|
Thread.Sleep(250); // wait for other change messages to pass
|
||||||
messageReceived = null;
|
messageReceived = null;
|
||||||
chatEventB.Reset();
|
chatEventB.Reset();
|
||||||
xEngineB.PostObjectEvent(soSceneB.LocalId, ep);
|
xEngineB.PostObjectEvent(soSceneB.LocalId, ep);
|
||||||
|
|
|
@ -138,6 +138,9 @@
|
||||||
; This can be overridden in the region config file.
|
; This can be overridden in the region config file.
|
||||||
ClampPrimSize = false
|
ClampPrimSize = false
|
||||||
|
|
||||||
|
; If a prim is loaded from an external source, clamp it to Z = 0 if Z is negative.
|
||||||
|
ClampNegativeZ = false
|
||||||
|
|
||||||
; Maximum number of prims allowable in a linkset. Affects creating new linksets. Ignored if less than or equal to zero.
|
; Maximum number of prims allowable in a linkset. Affects creating new linksets. Ignored if less than or equal to zero.
|
||||||
; This can be overridden in the region config file.
|
; This can be overridden in the region config file.
|
||||||
LinksetPrims = 0
|
LinksetPrims = 0
|
||||||
|
|
Loading…
Reference in New Issue