merge
commit
fe6ad384e4
|
@ -566,7 +566,7 @@ namespace OpenSim.Framework.Capabilities
|
|||
endPos = FindEnd(llsd, 1);
|
||||
|
||||
if (Double.TryParse(llsd.Substring(1, endPos - 1), NumberStyles.Float,
|
||||
Utils.EnUsCulture.NumberFormat, out value))
|
||||
Culture.NumberFormatInfo, out value))
|
||||
return value;
|
||||
else
|
||||
throw new LLSDParseException("Failed to parse double value type");
|
||||
|
|
|
@ -88,6 +88,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
|
||||
bool IsForcefulBansAllowed();
|
||||
void UpdateLandObject(int localID, LandData data);
|
||||
void SendParcelsOverlay(IClientAPI client);
|
||||
void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient);
|
||||
void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel);
|
||||
void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel);
|
||||
|
|
|
@ -64,25 +64,25 @@ namespace OpenSim.Framework
|
|||
|
||||
private void XWfloat(string name, float f)
|
||||
{
|
||||
writer.WriteElementString(name, f.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString(name, f.ToString(Culture.FormatProvider));
|
||||
}
|
||||
|
||||
private void XWVector(string name, Vector3 vec)
|
||||
{
|
||||
writer.WriteStartElement(name);
|
||||
writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("X", vec.X.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Y", vec.Y.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Z", vec.Z.ToString(Culture.FormatProvider));
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
private void XWVector4(string name, Vector4 quat)
|
||||
{
|
||||
writer.WriteStartElement(name);
|
||||
writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("X", quat.X.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Y", quat.Y.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Z", quat.Z.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("W", quat.W.ToString(Culture.FormatProvider));
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
|
|
|
@ -216,6 +216,27 @@ namespace OpenSim.Framework
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool TryOrderedDequeue(out EntityUpdate value, out Int32 timeinqueue)
|
||||
{
|
||||
// If there is anything in imediate queues, return it first no
|
||||
// matter what else. Breaks fairness. But very useful.
|
||||
for (int iq = 0; iq < NumberOfQueues; iq++)
|
||||
{
|
||||
if (m_heaps[iq].Count > 0)
|
||||
{
|
||||
MinHeapItem item = m_heaps[iq].RemoveMin();
|
||||
m_lookupTable.Remove(item.Value.Entity.LocalId);
|
||||
timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
|
||||
value = item.Value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
timeinqueue = 0;
|
||||
value = default(EntityUpdate);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reapply the prioritization function to each of the updates currently
|
||||
/// stored in the priority queues.
|
||||
|
|
|
@ -156,12 +156,14 @@ namespace OpenSim.Framework
|
|||
public static readonly int MAX_THREADPOOL_LEVEL = 3;
|
||||
|
||||
public static double TimeStampClockPeriodMS;
|
||||
public static double TimeStampClockPeriod;
|
||||
|
||||
static Util()
|
||||
{
|
||||
LogThreadPool = 0;
|
||||
LogOverloads = true;
|
||||
TimeStampClockPeriodMS = 1000.0D / (double)Stopwatch.Frequency;
|
||||
TimeStampClockPeriod = 1.0D/ (double)Stopwatch.Frequency;
|
||||
TimeStampClockPeriodMS = 1e3 * TimeStampClockPeriod;
|
||||
m_log.InfoFormat("[UTIL] TimeStamp clock with period of {0}ms", Math.Round(TimeStampClockPeriodMS,6,MidpointRounding.AwayFromZero));
|
||||
}
|
||||
|
||||
|
@ -2221,9 +2223,9 @@ namespace OpenSim.Framework
|
|||
// might have gotten an oversized array even after the string trim
|
||||
byte[] data = UTF8.GetBytes(str);
|
||||
|
||||
if (data.Length > 256)
|
||||
if (data.Length > 255) //play safe
|
||||
{
|
||||
int cut = 255;
|
||||
int cut = 254;
|
||||
if((data[cut] & 0x80 ) != 0 )
|
||||
{
|
||||
while(cut > 0 && (data[cut] & 0xc0) != 0xc0)
|
||||
|
@ -2325,7 +2327,7 @@ namespace OpenSim.Framework
|
|||
|
||||
if (data.Length > MaxLength)
|
||||
{
|
||||
int cut = MaxLength -1 ;
|
||||
int cut = MaxLength - 1 ;
|
||||
if((data[cut] & 0x80 ) != 0 )
|
||||
{
|
||||
while(cut > 0 && (data[cut] & 0xc0) != 0xc0)
|
||||
|
@ -2967,9 +2969,9 @@ namespace OpenSim.Framework
|
|||
/// <returns></returns>
|
||||
public static Int32 EnvironmentTickCount()
|
||||
{
|
||||
double now = GetTimeStampMS();
|
||||
return (int)now;
|
||||
return Environment.TickCount & EnvironmentTickCountMask;
|
||||
}
|
||||
|
||||
const Int32 EnvironmentTickCountMask = 0x3fffffff;
|
||||
|
||||
/// <summary>
|
||||
|
@ -2994,8 +2996,7 @@ namespace OpenSim.Framework
|
|||
/// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
|
||||
public static Int32 EnvironmentTickCountSubtract(Int32 prevValue)
|
||||
{
|
||||
double now = GetTimeStampMS();
|
||||
return EnvironmentTickCountSubtract((int)now, prevValue);
|
||||
return EnvironmentTickCountSubtract(EnvironmentTickCount(), prevValue);
|
||||
}
|
||||
|
||||
// Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount
|
||||
|
@ -3017,6 +3018,11 @@ namespace OpenSim.Framework
|
|||
|
||||
// returns a timestamp in ms as double
|
||||
// using the time resolution avaiable to StopWatch
|
||||
public static double GetTimeStamp()
|
||||
{
|
||||
return (double)Stopwatch.GetTimestamp() * TimeStampClockPeriod;
|
||||
}
|
||||
|
||||
public static double GetTimeStampMS()
|
||||
{
|
||||
return (double)Stopwatch.GetTimestamp() * TimeStampClockPeriodMS;
|
||||
|
|
|
@ -220,7 +220,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
PollServiceMeshEventArgs args;
|
||||
if (m_pollservices.TryGetValue(user, out args))
|
||||
{
|
||||
args.UpdateThrottle(imagethrottle, p);
|
||||
args.UpdateThrottle(imagethrottle);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,14 +238,13 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
base(null, uri, null, null, null, null, pId, int.MaxValue)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId);
|
||||
m_throttler = new MeshCapsDataThrottler(100000);
|
||||
// x is request id, y is userid
|
||||
HasEvents = (x, y) =>
|
||||
{
|
||||
lock (responses)
|
||||
{
|
||||
bool ret = m_throttler.hasEvents(x, responses);
|
||||
m_throttler.ProcessTime();
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
@ -271,8 +270,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
}
|
||||
finally
|
||||
{
|
||||
m_throttler.ProcessTime();
|
||||
responses.Remove(x);
|
||||
m_throttler.PassTime();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -285,6 +284,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
reqinfo.request = y;
|
||||
|
||||
m_queue.Enqueue(reqinfo);
|
||||
m_throttler.PassTime();
|
||||
};
|
||||
|
||||
// this should never happen except possible on shutdown
|
||||
|
@ -364,12 +364,15 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
};
|
||||
|
||||
}
|
||||
m_throttler.ProcessTime();
|
||||
m_throttler.PassTime();
|
||||
}
|
||||
|
||||
internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
|
||||
internal void UpdateThrottle(int pthrottle)
|
||||
{
|
||||
m_throttler.UpdateThrottle(pimagethrottle, p);
|
||||
int tmp = 2 * pthrottle;
|
||||
if(tmp < 10000)
|
||||
tmp = 10000;
|
||||
m_throttler.ThrottleBytes = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -423,24 +426,15 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
|
||||
internal sealed class MeshCapsDataThrottler
|
||||
{
|
||||
private double lastTimeElapsed = 0;
|
||||
private double BytesSent = 0;
|
||||
|
||||
private volatile int currenttime = 0;
|
||||
private volatile int lastTimeElapsed = 0;
|
||||
private volatile int BytesSent = 0;
|
||||
private int CapSetThrottle = 0;
|
||||
private readonly Scene m_scene;
|
||||
private ThrottleOutPacketType Throttle;
|
||||
private readonly UUID User;
|
||||
|
||||
public MeshCapsDataThrottler(int pBytes, int max, int min, Scene pScene, UUID puser)
|
||||
public MeshCapsDataThrottler(int pBytes)
|
||||
{
|
||||
if(pBytes < 10000)
|
||||
pBytes = 10000;
|
||||
ThrottleBytes = pBytes;
|
||||
if(ThrottleBytes < 10000)
|
||||
ThrottleBytes = 10000;
|
||||
lastTimeElapsed = Util.EnvironmentTickCount();
|
||||
Throttle = ThrottleOutPacketType.Asset;
|
||||
m_scene = pScene;
|
||||
User = puser;
|
||||
lastTimeElapsed = Util.GetTimeStampMS();
|
||||
}
|
||||
|
||||
public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses)
|
||||
|
@ -470,46 +464,22 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
return haskey;
|
||||
}
|
||||
|
||||
public void ProcessTime()
|
||||
public void PassTime()
|
||||
{
|
||||
PassTime();
|
||||
}
|
||||
|
||||
private void PassTime()
|
||||
double currenttime = Util.GetTimeStampMS();
|
||||
double timeElapsed = currenttime - lastTimeElapsed;
|
||||
if(timeElapsed < 50.0)
|
||||
return;
|
||||
int add = (int)(ThrottleBytes * timeElapsed * 0.001);
|
||||
if (add >= 1000)
|
||||
{
|
||||
currenttime = Util.EnvironmentTickCount();
|
||||
int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
|
||||
if (timeElapsed >= 100)
|
||||
{
|
||||
lastTimeElapsed = currenttime;
|
||||
BytesSent -= (ThrottleBytes * timeElapsed / 1000);
|
||||
BytesSent -= add;
|
||||
if (BytesSent < 0) BytesSent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void AlterThrottle(int setting, ScenePresence p)
|
||||
{
|
||||
p.ControllingClient.SetAgentThrottleSilent((int)Throttle,setting);
|
||||
public int ThrottleBytes;
|
||||
}
|
||||
|
||||
public int ThrottleBytes
|
||||
{
|
||||
get { return CapSetThrottle; }
|
||||
set
|
||||
{
|
||||
if (value > 10000)
|
||||
CapSetThrottle = value;
|
||||
else
|
||||
CapSetThrottle = 10000;
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
|
||||
{
|
||||
// Client set throttle !
|
||||
CapSetThrottle = 2 * pimagethrottle;
|
||||
ProcessTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -221,7 +221,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
private HashSet<UUID> dropedResponses = new HashSet<UUID>();
|
||||
|
||||
private Scene m_scene;
|
||||
private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000);
|
||||
private CapsDataThrottler m_throttler = new CapsDataThrottler(100000);
|
||||
public PollServiceTextureEventArgs(UUID pId, Scene scene) :
|
||||
base(null, "", null, null, null, null, pId, int.MaxValue)
|
||||
{
|
||||
|
@ -232,7 +232,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
lock (responses)
|
||||
{
|
||||
bool ret = m_throttler.hasEvents(x, responses);
|
||||
m_throttler.ProcessTime();
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
@ -258,6 +257,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
finally
|
||||
{
|
||||
responses.Remove(x);
|
||||
m_throttler.PassTime();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -282,6 +282,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
}
|
||||
}
|
||||
m_queue.Enqueue(reqinfo);
|
||||
m_throttler.PassTime();
|
||||
};
|
||||
|
||||
// this should never happen except possible on shutdown
|
||||
|
@ -381,14 +382,15 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
response = response
|
||||
};
|
||||
}
|
||||
m_throttler.ProcessTime();
|
||||
m_throttler.PassTime();
|
||||
}
|
||||
|
||||
internal void UpdateThrottle(int pimagethrottle)
|
||||
{
|
||||
m_throttler.ThrottleBytes = 2 * pimagethrottle;
|
||||
if(m_throttler.ThrottleBytes < 10000)
|
||||
m_throttler.ThrottleBytes = 10000;
|
||||
int tmp = 2 * pimagethrottle;
|
||||
if(tmp < 10000)
|
||||
tmp = 10000;
|
||||
m_throttler.ThrottleBytes = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -456,15 +458,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
|
||||
internal sealed class CapsDataThrottler
|
||||
{
|
||||
private volatile int currenttime = 0;
|
||||
private volatile int lastTimeElapsed = 0;
|
||||
private double lastTimeElapsed = 0;
|
||||
private volatile int BytesSent = 0;
|
||||
public CapsDataThrottler(int pBytes, int max, int min)
|
||||
public CapsDataThrottler(int pBytes)
|
||||
{
|
||||
if(pBytes < 10000)
|
||||
pBytes = 10000;
|
||||
ThrottleBytes = pBytes;
|
||||
if(ThrottleBytes < 10000)
|
||||
ThrottleBytes = 10000;
|
||||
lastTimeElapsed = Util.EnvironmentTickCount();
|
||||
lastTimeElapsed = Util.GetTimeStampMS();
|
||||
}
|
||||
public bool hasEvents(UUID key, Dictionary<UUID, GetTextureModule.aPollResponse> responses)
|
||||
{
|
||||
|
@ -497,20 +498,17 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
return haskey;
|
||||
}
|
||||
|
||||
public void ProcessTime()
|
||||
public void PassTime()
|
||||
{
|
||||
PassTime();
|
||||
}
|
||||
|
||||
private void PassTime()
|
||||
double currenttime = Util.GetTimeStampMS();
|
||||
double timeElapsed = currenttime - lastTimeElapsed;
|
||||
if(timeElapsed < 50.0)
|
||||
return;
|
||||
int add = (int)(ThrottleBytes * timeElapsed * 0.001);
|
||||
if (add >= 1000)
|
||||
{
|
||||
currenttime = Util.EnvironmentTickCount();
|
||||
int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
|
||||
//processTimeBasedActions(responses);
|
||||
if (timeElapsed >= 100)
|
||||
{
|
||||
lastTimeElapsed = currenttime;
|
||||
BytesSent -= (ThrottleBytes * timeElapsed / 1000);
|
||||
BytesSent -= add;
|
||||
if (BytesSent < 0) BytesSent = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4137,6 +4137,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
Vector3 mypos = Vector3.Zero;
|
||||
ScenePresence mysp = (ScenePresence)SceneAgent;
|
||||
|
||||
bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance;
|
||||
// we should have a presence
|
||||
if(mysp == null)
|
||||
return;
|
||||
|
@ -4151,8 +4152,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
while (maxUpdatesBytes > 0)
|
||||
{
|
||||
lock (m_entityUpdates.SyncRoot)
|
||||
if (!m_entityUpdates.TryDequeue(out update, out timeinqueue))
|
||||
break;
|
||||
{
|
||||
if(orderedDequeue)
|
||||
{
|
||||
if (!m_entityUpdates.TryOrderedDequeue(out update, out timeinqueue))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_entityUpdates.TryDequeue(out update, out timeinqueue))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
|
||||
|
||||
|
@ -4850,6 +4861,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates =
|
||||
// new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
|
||||
|
||||
bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance;
|
||||
|
||||
EntityUpdate iupdate;
|
||||
Int32 timeinqueue; // this is just debugging code & can be dropped later
|
||||
|
@ -4857,8 +4869,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
while (maxUpdateBytes > 0)
|
||||
{
|
||||
lock (m_entityProps.SyncRoot)
|
||||
if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue))
|
||||
break;
|
||||
{
|
||||
if(orderedDequeue)
|
||||
{
|
||||
if (!m_entityProps.TryOrderedDequeue(out iupdate, out timeinqueue))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate;
|
||||
if (update.SendFamilyProps)
|
||||
|
@ -5526,6 +5548,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
#endregion
|
||||
|
||||
#region Helper Methods
|
||||
private void ClampVectorForUint(ref Vector3 v, float max)
|
||||
{
|
||||
float a,b;
|
||||
|
||||
a = Math.Abs(v.X);
|
||||
b = Math.Abs(v.Y);
|
||||
if(b > a)
|
||||
a = b;
|
||||
b= Math.Abs(v.Z);
|
||||
if(b > a)
|
||||
a = b;
|
||||
|
||||
if (a > max)
|
||||
{
|
||||
a = max / a;
|
||||
v.X *= a;
|
||||
v.Y *= a;
|
||||
v.Z *= a;
|
||||
}
|
||||
}
|
||||
|
||||
protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture)
|
||||
{
|
||||
|
@ -5616,11 +5658,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
pos += 12;
|
||||
|
||||
// Velocity
|
||||
ClampVectorForUint(ref velocity, 128f);
|
||||
Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.X, -128.0f, 128.0f), data, pos); pos += 2;
|
||||
Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Y, -128.0f, 128.0f), data, pos); pos += 2;
|
||||
Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Z, -128.0f, 128.0f), data, pos); pos += 2;
|
||||
|
||||
// Acceleration
|
||||
ClampVectorForUint(ref acceleration, 64f);
|
||||
Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.X, -64.0f, 64.0f), data, pos); pos += 2;
|
||||
Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2;
|
||||
Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2;
|
||||
|
@ -5632,6 +5676,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.W, -1.0f, 1.0f), data, pos); pos += 2;
|
||||
|
||||
// Angular Velocity
|
||||
ClampVectorForUint(ref angularVelocity, 64f);
|
||||
Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2;
|
||||
Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2;
|
||||
Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2;
|
||||
|
@ -5753,7 +5798,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
//update.JointPivot = Vector3.Zero;
|
||||
//update.JointType = 0;
|
||||
update.Material = part.Material;
|
||||
update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
|
||||
/*
|
||||
if (data.ParentGroup.IsAttachment)
|
||||
{
|
||||
|
@ -5832,8 +5876,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
update.TextureAnim = part.TextureAnimation ?? Utils.EmptyBytes;
|
||||
update.TextureEntry = part.Shape.TextureEntry ?? Utils.EmptyBytes;
|
||||
update.Scale = part.Shape.Scale;
|
||||
update.Text = Util.StringToBytes256(part.Text);
|
||||
update.MediaURL = Util.StringToBytes256(part.MediaUrl);
|
||||
update.Text = Util.StringToBytes(part.Text, 255);
|
||||
update.MediaURL = Util.StringToBytes(part.MediaUrl, 255);
|
||||
|
||||
#region PrimFlags
|
||||
|
||||
|
@ -6234,20 +6278,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
/// <param name='x'></param>
|
||||
private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
|
||||
{
|
||||
float vdelta = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis);
|
||||
if((vdelta > VDELTA))
|
||||
return true;
|
||||
if(Math.Abs(x.CameraCenter.X - m_thisAgentUpdateArgs.CameraCenter.X) > VDELTA ||
|
||||
Math.Abs(x.CameraCenter.Y - m_thisAgentUpdateArgs.CameraCenter.Y) > VDELTA ||
|
||||
Math.Abs(x.CameraCenter.Z - m_thisAgentUpdateArgs.CameraCenter.Z) > VDELTA ||
|
||||
|
||||
vdelta = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter);
|
||||
if((vdelta > VDELTA))
|
||||
return true;
|
||||
Math.Abs(x.CameraAtAxis.X - m_thisAgentUpdateArgs.CameraAtAxis.X) > VDELTA ||
|
||||
Math.Abs(x.CameraAtAxis.Y - m_thisAgentUpdateArgs.CameraAtAxis.Y) > VDELTA ||
|
||||
// Math.Abs(x.CameraAtAxis.Z - m_thisAgentUpdateArgs.CameraAtAxis.Z) > VDELTA ||
|
||||
|
||||
vdelta = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis);
|
||||
if((vdelta > VDELTA))
|
||||
return true;
|
||||
Math.Abs(x.CameraLeftAxis.X - m_thisAgentUpdateArgs.CameraLeftAxis.X) > VDELTA ||
|
||||
Math.Abs(x.CameraLeftAxis.Y - m_thisAgentUpdateArgs.CameraLeftAxis.Y) > VDELTA ||
|
||||
// Math.Abs(x.CameraLeftAxis.Z - m_thisAgentUpdateArgs.CameraLeftAxis.Z) > VDELTA ||
|
||||
|
||||
vdelta = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis);
|
||||
if((vdelta > VDELTA))
|
||||
Math.Abs(x.CameraUpAxis.X - m_thisAgentUpdateArgs.CameraUpAxis.X) > VDELTA ||
|
||||
Math.Abs(x.CameraUpAxis.Y - m_thisAgentUpdateArgs.CameraUpAxis.Y) > VDELTA
|
||||
// Math.Abs(x.CameraLeftAxis.Z - m_thisAgentUpdateArgs.CameraLeftAxis.Z) > VDELTA ||
|
||||
)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -218,10 +218,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
|
||||
// Count inventory items (different to asset count)
|
||||
CountItems++;
|
||||
|
||||
|
||||
// Don't chase down link asset items as they actually point to their target item IDs rather than an asset
|
||||
if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder)
|
||||
{
|
||||
int curErrorCntr = m_assetGatherer.ErrorCount;
|
||||
int possible = m_assetGatherer.possibleNotAssetCount;
|
||||
m_assetGatherer.AddForInspection(inventoryItem.AssetID);
|
||||
m_assetGatherer.GatherAll();
|
||||
curErrorCntr = m_assetGatherer.ErrorCount - curErrorCntr;
|
||||
possible = m_assetGatherer.possibleNotAssetCount - possible;
|
||||
|
||||
if(curErrorCntr > 0 || possible > 0)
|
||||
{
|
||||
string spath;
|
||||
int indx = path.IndexOf("__");
|
||||
if(indx > 0)
|
||||
spath = path.Substring(0,indx);
|
||||
else
|
||||
spath = path;
|
||||
|
||||
if(curErrorCntr > 0)
|
||||
{
|
||||
m_log.ErrorFormat("[INVENTORY ARCHIVER Warning]: item {0} '{1}', type {2}, in '{3}', contains {4} references to missing or damaged assets",
|
||||
inventoryItem.ID, inventoryItem.Name, itemAssetType.ToString(), spath, curErrorCntr);
|
||||
if(possible > 0)
|
||||
m_log.WarnFormat("[INVENTORY ARCHIVER Warning]: item also contains {0} references that may be to missing or damaged assets or not a problem", possible);
|
||||
}
|
||||
else if(possible > 0)
|
||||
{
|
||||
m_log.WarnFormat("[INVENTORY ARCHIVER Warning]: item {0} '{1}', type {2}, in '{3}', contains {4} references that may be to missing or damaged assets or not a problem", inventoryItem.ID, inventoryItem.Name, itemAssetType.ToString(), spath, possible);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -381,6 +410,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath);
|
||||
Exception e = new InventoryArchiverException(errorMessage);
|
||||
m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e, 0, 0);
|
||||
if(m_saveStream != null && m_saveStream.CanWrite)
|
||||
m_saveStream.Close();
|
||||
throw e;
|
||||
}
|
||||
|
||||
|
@ -420,17 +451,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
{
|
||||
m_assetGatherer.GatherAll();
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetGatherer.GatheredUuids.Count);
|
||||
int errors = m_assetGatherer.FailedUUIDs.Count;
|
||||
|
||||
AssetsRequest ar
|
||||
= new AssetsRequest(
|
||||
m_log.DebugFormat(
|
||||
"[INVENTORY ARCHIVER]: The items to save reference {0} possible assets", m_assetGatherer.GatheredUuids.Count + errors);
|
||||
if(errors > 0)
|
||||
m_log.DebugFormat("[INVENTORY ARCHIVER]: {0} of these have problems or are not assets and will be ignored", errors);
|
||||
|
||||
AssetsRequest ar = new AssetsRequest(
|
||||
new AssetsArchiver(m_archiveWriter),
|
||||
m_assetGatherer.GatheredUuids, m_scene.AssetService,
|
||||
m_assetGatherer.GatheredUuids, m_assetGatherer.FailedUUIDs.Count,
|
||||
m_scene.AssetService,
|
||||
m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
|
||||
options, ReceivedAllAssets);
|
||||
|
||||
WorkManager.RunInThread(o => ar.Execute(), null, string.Format("AssetsRequest ({0})", m_scene.Name));
|
||||
ar.Execute();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -218,7 +218,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
// {
|
||||
try
|
||||
{
|
||||
new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, saveStream).Execute(options, UserAccountService);
|
||||
InventoryArchiveWriteRequest iarReq = new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, saveStream);
|
||||
iarReq.Execute(options, UserAccountService);
|
||||
}
|
||||
catch (EntryPointNotFoundException e)
|
||||
{
|
||||
|
@ -261,7 +262,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
// {
|
||||
try
|
||||
{
|
||||
new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, savePath).Execute(options, UserAccountService);
|
||||
InventoryArchiveWriteRequest iarReq = new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, savePath);
|
||||
iarReq.Execute(options, UserAccountService);
|
||||
}
|
||||
catch (EntryPointNotFoundException e)
|
||||
{
|
||||
|
|
|
@ -412,7 +412,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>();
|
||||
Dictionary<UUID, Quaternion> originalRotations = new Dictionary<UUID, Quaternion>();
|
||||
// this possible is not needed if keyframes are saved
|
||||
Dictionary<UUID, KeyframeMotion> originalKeyframes = new Dictionary<UUID, KeyframeMotion>();
|
||||
// Dictionary<UUID, KeyframeMotion> originalKeyframes = new Dictionary<UUID, KeyframeMotion>();
|
||||
|
||||
foreach (SceneObjectGroup objectGroup in objlist)
|
||||
{
|
||||
|
@ -423,8 +423,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
objectGroup.RootPart.SetForce(Vector3.Zero);
|
||||
objectGroup.RootPart.SetAngularImpulse(Vector3.Zero, false);
|
||||
|
||||
originalKeyframes[objectGroup.UUID] = objectGroup.RootPart.KeyframeMotion;
|
||||
objectGroup.RootPart.KeyframeMotion = null;
|
||||
// originalKeyframes[objectGroup.UUID] = objectGroup.RootPart.KeyframeMotion;
|
||||
// objectGroup.RootPart.KeyframeMotion = null;
|
||||
|
||||
Vector3 inventoryStoredPosition = objectGroup.AbsolutePosition;
|
||||
originalPositions[objectGroup.UUID] = inventoryStoredPosition;
|
||||
|
@ -476,7 +476,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
{
|
||||
objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
|
||||
objectGroup.RootPart.RotationOffset = originalRotations[objectGroup.UUID];
|
||||
objectGroup.RootPart.KeyframeMotion = originalKeyframes[objectGroup.UUID];
|
||||
// objectGroup.RootPart.KeyframeMotion = originalKeyframes[objectGroup.UUID];
|
||||
if (objectGroup.RootPart.KeyframeMotion != null)
|
||||
objectGroup.RootPart.KeyframeMotion.Resume();
|
||||
}
|
||||
|
@ -989,11 +989,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
// one full update during the attachment
|
||||
// process causes some clients to fail to display the
|
||||
// attachment properly.
|
||||
m_Scene.AddNewSceneObject(group, true, false);
|
||||
|
||||
if (!attachment)
|
||||
{
|
||||
group.AbsolutePosition = pos + veclist[i];
|
||||
m_Scene.AddNewSceneObject(group, true, false);
|
||||
|
||||
// Fire on_rez
|
||||
group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
|
||||
|
@ -1001,6 +1001,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
|
||||
group.ScheduleGroupForFullUpdate();
|
||||
}
|
||||
else
|
||||
m_Scene.AddNewSceneObject(group, true, false);
|
||||
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY ACCESS MODULE]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
|
||||
|
|
|
@ -135,17 +135,13 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
|||
m_reuseableDynamicTextures.Store(
|
||||
GenerateReusableTextureKey(texture.InputCommands, texture.InputParams), newTextureID);
|
||||
}
|
||||
updater.newTextureID = newTextureID;
|
||||
}
|
||||
}
|
||||
|
||||
if (updater.UpdateTimer == 0)
|
||||
{
|
||||
lock (Updaters)
|
||||
{
|
||||
if (!Updaters.ContainsKey(updater.UpdaterID))
|
||||
{
|
||||
if (Updaters.ContainsKey(updater.UpdaterID))
|
||||
Updaters.Remove(updater.UpdaterID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,21 +168,20 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
|||
}
|
||||
|
||||
public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
|
||||
string extraParams, int updateTimer)
|
||||
string extraParams)
|
||||
{
|
||||
return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, updateTimer, false, 255);
|
||||
return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, false, 255);
|
||||
}
|
||||
|
||||
public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
|
||||
string extraParams, int updateTimer, bool SetBlending, byte AlphaValue)
|
||||
string extraParams, bool SetBlending, byte AlphaValue)
|
||||
{
|
||||
return AddDynamicTextureURL(simID, primID, contentType, url,
|
||||
extraParams, updateTimer, SetBlending,
|
||||
(int)(DISP_TEMP|DISP_EXPIRE), AlphaValue, ALL_SIDES);
|
||||
return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, SetBlending,
|
||||
(DISP_TEMP|DISP_EXPIRE), AlphaValue, ALL_SIDES);
|
||||
}
|
||||
|
||||
public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
|
||||
string extraParams, int updateTimer, bool SetBlending,
|
||||
string extraParams, bool SetBlending,
|
||||
int disp, byte AlphaValue, int face)
|
||||
{
|
||||
if (RenderPlugins.ContainsKey(contentType))
|
||||
|
@ -196,7 +191,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
|||
updater.PrimID = primID;
|
||||
updater.ContentType = contentType;
|
||||
updater.Url = url;
|
||||
updater.UpdateTimer = updateTimer;
|
||||
updater.UpdaterID = UUID.Random();
|
||||
updater.Params = extraParams;
|
||||
updater.BlendWithOldTexture = SetBlending;
|
||||
|
@ -213,26 +207,27 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
|||
}
|
||||
|
||||
RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams);
|
||||
return updater.UpdaterID;
|
||||
return updater.newTextureID;
|
||||
}
|
||||
return UUID.Zero;
|
||||
}
|
||||
|
||||
public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data,
|
||||
string extraParams, int updateTimer)
|
||||
string extraParams)
|
||||
{
|
||||
return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, false, 255);
|
||||
return AddDynamicTextureData(simID, primID, contentType, data, extraParams, false,
|
||||
(DISP_TEMP|DISP_EXPIRE), 255, ALL_SIDES);
|
||||
}
|
||||
|
||||
public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data,
|
||||
string extraParams, int updateTimer, bool SetBlending, byte AlphaValue)
|
||||
string extraParams, bool SetBlending, byte AlphaValue)
|
||||
{
|
||||
return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, SetBlending,
|
||||
(int) (DISP_TEMP|DISP_EXPIRE), AlphaValue, ALL_SIDES);
|
||||
return AddDynamicTextureData(simID, primID, contentType, data, extraParams, SetBlending,
|
||||
(DISP_TEMP|DISP_EXPIRE), AlphaValue, ALL_SIDES);
|
||||
}
|
||||
|
||||
public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data,
|
||||
string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face)
|
||||
string extraParams, bool SetBlending, int disp, byte AlphaValue, int face)
|
||||
{
|
||||
if (!RenderPlugins.ContainsKey(contentType))
|
||||
return UUID.Zero;
|
||||
|
@ -258,7 +253,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
|||
updater.PrimID = primID;
|
||||
updater.ContentType = contentType;
|
||||
updater.BodyData = data;
|
||||
updater.UpdateTimer = updateTimer;
|
||||
updater.UpdaterID = UUID.Random();
|
||||
updater.Params = extraParams;
|
||||
updater.BlendWithOldTexture = SetBlending;
|
||||
|
@ -314,7 +308,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
|||
updater.UpdatePart(part, (UUID)objReusableTextureUUID);
|
||||
}
|
||||
|
||||
return updater.UpdaterID;
|
||||
return updater.newTextureID;
|
||||
}
|
||||
|
||||
private string GenerateReusableTextureKey(string data, string extraParams)
|
||||
|
@ -404,17 +398,15 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
|||
public byte FrontAlpha = 255;
|
||||
public string Params;
|
||||
public UUID PrimID;
|
||||
public bool SetNewFrontAlpha = false;
|
||||
public UUID SimUUID;
|
||||
public UUID UpdaterID;
|
||||
public int UpdateTimer;
|
||||
public int Face;
|
||||
public int Disp;
|
||||
public string Url;
|
||||
public UUID newTextureID;
|
||||
|
||||
public DynamicTextureUpdater()
|
||||
{
|
||||
UpdateTimer = 0;
|
||||
BodyData = null;
|
||||
}
|
||||
|
||||
|
@ -436,16 +428,23 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
|||
// FIXME: Need to return the appropriate ID if only a single face is replaced.
|
||||
oldID = tmptex.DefaultTexture.TextureID;
|
||||
|
||||
// not using parts number of faces because that fails on old meshs
|
||||
if (Face == ALL_SIDES)
|
||||
{
|
||||
oldID = tmptex.DefaultTexture.TextureID;
|
||||
tmptex.DefaultTexture.TextureID = textureID;
|
||||
for(int i = 0; i < tmptex.FaceTextures.Length; i++)
|
||||
{
|
||||
if(tmptex.FaceTextures[i] != null)
|
||||
tmptex.FaceTextures[i].TextureID = textureID;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
|
||||
oldID = texface.TextureID;
|
||||
texface.TextureID = textureID;
|
||||
tmptex.FaceTextures[Face] = texface;
|
||||
}
|
||||
|
@ -455,10 +454,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
|||
}
|
||||
}
|
||||
|
||||
// I'm pretty sure we always want to force this to true
|
||||
// I'm pretty sure noone whats to set fullbright true if it wasn't true before.
|
||||
// tmptex.DefaultTexture.Fullbright = true;
|
||||
|
||||
part.UpdateTextureEntry(tmptex.GetBytes());
|
||||
}
|
||||
|
||||
|
@ -491,13 +486,26 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
|||
|
||||
if (BlendWithOldTexture)
|
||||
{
|
||||
Primitive.TextureEntryFace defaultFace = part.Shape.Textures.DefaultTexture;
|
||||
if (defaultFace != null)
|
||||
Primitive.TextureEntryFace curFace;
|
||||
if(Face == ALL_SIDES)
|
||||
curFace = part.Shape.Textures.DefaultTexture;
|
||||
else
|
||||
{
|
||||
oldAsset = scene.AssetService.Get(defaultFace.TextureID.ToString());
|
||||
try
|
||||
{
|
||||
curFace = part.Shape.Textures.GetFace((uint)Face);
|
||||
}
|
||||
catch
|
||||
{
|
||||
curFace = null;
|
||||
}
|
||||
}
|
||||
if (curFace != null)
|
||||
{
|
||||
oldAsset = scene.AssetService.Get(curFace.TextureID.ToString());
|
||||
|
||||
if (oldAsset != null)
|
||||
assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha);
|
||||
assetData = BlendTextures(data, oldAsset.Data, FrontAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -548,7 +556,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
|||
return asset.FullID;
|
||||
}
|
||||
|
||||
private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)
|
||||
private byte[] BlendTextures(byte[] frontImage, byte[] backImage, byte newAlpha)
|
||||
{
|
||||
ManagedImage managedImage;
|
||||
Image image;
|
||||
|
@ -568,7 +576,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
|||
Bitmap image2 = new Bitmap(image);
|
||||
image.Dispose();
|
||||
|
||||
if (setNewAlpha)
|
||||
if (newAlpha < 255)
|
||||
SetAlpha(ref image1, newAlpha);
|
||||
|
||||
using(Bitmap joint = MergeBitMaps(image1, image2))
|
||||
|
|
|
@ -379,9 +379,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
|||
if (ThreadPool == null)
|
||||
{
|
||||
STPStartInfo startInfo = new STPStartInfo();
|
||||
startInfo.IdleTimeout = 20000;
|
||||
startInfo.IdleTimeout = 2000;
|
||||
startInfo.MaxWorkerThreads = maxThreads;
|
||||
startInfo.MinWorkerThreads = 1;
|
||||
startInfo.MinWorkerThreads = 0;
|
||||
startInfo.ThreadPriority = ThreadPriority.BelowNormal;
|
||||
startInfo.StartSuspended = true;
|
||||
startInfo.ThreadPoolName = "ScriptsHttpReq";
|
||||
|
|
|
@ -77,8 +77,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
"PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
|
||||
"",
|
||||
0);
|
||||
"");
|
||||
|
||||
Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
|
||||
}
|
||||
|
@ -98,8 +97,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
dtText,
|
||||
"",
|
||||
0);
|
||||
"");
|
||||
|
||||
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
|
||||
|
||||
|
@ -108,8 +106,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
dtText,
|
||||
"",
|
||||
0);
|
||||
"");
|
||||
|
||||
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
|
||||
}
|
||||
|
@ -129,8 +126,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
dtText,
|
||||
"",
|
||||
0);
|
||||
"");
|
||||
|
||||
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
|
||||
|
||||
|
@ -139,8 +135,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
dtText,
|
||||
"alpha:250",
|
||||
0);
|
||||
"alpha:250");
|
||||
|
||||
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
|
||||
}
|
||||
|
@ -161,8 +156,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
dtText,
|
||||
"",
|
||||
0);
|
||||
"");
|
||||
|
||||
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
|
||||
|
||||
|
@ -171,8 +165,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
dtText,
|
||||
"",
|
||||
0);
|
||||
"");
|
||||
|
||||
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
|
||||
}
|
||||
|
@ -191,8 +184,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
"PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
|
||||
"",
|
||||
0);
|
||||
"");
|
||||
|
||||
Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
|
||||
}
|
||||
|
@ -213,8 +205,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
dtText,
|
||||
"",
|
||||
0);
|
||||
"");
|
||||
|
||||
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
|
||||
|
||||
|
@ -223,8 +214,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
dtText,
|
||||
"",
|
||||
0);
|
||||
"");
|
||||
|
||||
Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
|
||||
}
|
||||
|
@ -253,8 +243,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
dtText,
|
||||
"1024",
|
||||
0);
|
||||
"1024");
|
||||
|
||||
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
|
||||
|
||||
|
@ -263,8 +252,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
dtText,
|
||||
"1024",
|
||||
0);
|
||||
"1024");
|
||||
|
||||
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
|
||||
}
|
||||
|
@ -284,8 +272,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
dtText,
|
||||
"",
|
||||
0);
|
||||
"");
|
||||
|
||||
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
|
||||
|
||||
|
@ -294,8 +281,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
dtText,
|
||||
"alpha:250",
|
||||
0);
|
||||
"alpha:250");
|
||||
|
||||
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
|
||||
}
|
||||
|
@ -316,8 +302,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
dtText,
|
||||
"",
|
||||
0);
|
||||
"");
|
||||
|
||||
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
|
||||
|
||||
|
@ -326,8 +311,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
|||
so.UUID,
|
||||
m_vrm.GetContentType(),
|
||||
dtText,
|
||||
"",
|
||||
0);
|
||||
"");
|
||||
|
||||
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
|
||||
}
|
||||
|
|
|
@ -355,30 +355,22 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
|
|||
lock (this)
|
||||
{
|
||||
if (alpha == 256)
|
||||
bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
|
||||
else
|
||||
bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
|
||||
|
||||
graph = Graphics.FromImage(bitmap);
|
||||
|
||||
// this is really just to save people filling the
|
||||
// background color in their scripts, only do when fully opaque
|
||||
if (alpha >= 255)
|
||||
{
|
||||
bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
|
||||
graph = Graphics.FromImage(bitmap);
|
||||
using (SolidBrush bgFillBrush = new SolidBrush(bgColor))
|
||||
{
|
||||
graph.FillRectangle(bgFillBrush, 0, 0, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
for (int w = 0; w < bitmap.Width; w++)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (alpha <= 255)
|
||||
bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
|
||||
graph = Graphics.FromImage(bitmap);
|
||||
Color newbg = Color.FromArgb(alpha,bgColor);
|
||||
using (SolidBrush bgFillBrush = new SolidBrush(newbg))
|
||||
{
|
||||
for (int h = 0; h < bitmap.Height; h++)
|
||||
{
|
||||
bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
|
||||
}
|
||||
graph.FillRectangle(bgFillBrush, 0, 0, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -519,8 +511,32 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
|
|||
|
||||
// m_log.DebugFormat("[VECTOR RENDER MODULE]: Processing line '{0}'", nextLine);
|
||||
|
||||
if (nextLine.StartsWith("ResetTransf"))
|
||||
{
|
||||
graph.ResetTransform();
|
||||
}
|
||||
else if (nextLine.StartsWith("TransTransf"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 11, ref x, ref y);
|
||||
graph.TranslateTransform(x, y);
|
||||
}
|
||||
else if (nextLine.StartsWith("ScaleTransf"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 11, ref x, ref y);
|
||||
graph.ScaleTransform(x, y);
|
||||
}
|
||||
else if (nextLine.StartsWith("RotTransf"))
|
||||
{
|
||||
float x = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 9, ref x);
|
||||
graph.RotateTransform(x);
|
||||
}
|
||||
//replace with switch, or even better, do some proper parsing
|
||||
if (nextLine.StartsWith("MoveTo"))
|
||||
else if (nextLine.StartsWith("MoveTo"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
|
@ -625,6 +641,17 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
|
|||
startPoint.X += endPoint.X;
|
||||
startPoint.Y += endPoint.Y;
|
||||
}
|
||||
else if (nextLine.StartsWith("FillEllipse"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 11, ref x, ref y);
|
||||
endPoint.X = (int)x;
|
||||
endPoint.Y = (int)y;
|
||||
graph.FillEllipse(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
|
||||
startPoint.X += endPoint.X;
|
||||
startPoint.Y += endPoint.Y;
|
||||
}
|
||||
else if (nextLine.StartsWith("FontSize"))
|
||||
{
|
||||
nextLine = nextLine.Remove(0, 8);
|
||||
|
@ -790,6 +817,17 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
|
|||
}
|
||||
}
|
||||
|
||||
private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x)
|
||||
{
|
||||
line = line.Remove(0, startLength);
|
||||
string[] parts = line.Split(partsDelimiter);
|
||||
if (parts.Length > 0)
|
||||
{
|
||||
string xVal = parts[0].Trim();
|
||||
x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x, ref float y)
|
||||
{
|
||||
line = line.Remove(0, startLength);
|
||||
|
|
|
@ -658,7 +658,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
|
|||
public void Process()
|
||||
{
|
||||
_finished = false;
|
||||
httpThread = WorkManager.StartThread(SendRequest, "HttpRequestThread", ThreadPriority.BelowNormal, true, false, null, int.MaxValue);
|
||||
httpThread = WorkManager.StartThread(SendRequest, "XMLRPCreqThread", ThreadPriority.BelowNormal, true, false, null, int.MaxValue);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -181,11 +181,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
// Archive the regions
|
||||
|
||||
Dictionary<UUID, sbyte> assetUuids = new Dictionary<UUID, sbyte>();
|
||||
HashSet<UUID> failedIDs = new HashSet<UUID>();
|
||||
HashSet<UUID> uncertainAssetsUUIDs = new HashSet<UUID>();
|
||||
|
||||
scenesGroup.ForEachScene(delegate(Scene scene)
|
||||
{
|
||||
string regionDir = MultiRegionFormat ? scenesGroup.GetRegionDir(scene.RegionInfo.RegionID) : "";
|
||||
ArchiveOneRegion(scene, regionDir, assetUuids);
|
||||
ArchiveOneRegion(scene, regionDir, assetUuids, failedIDs, uncertainAssetsUUIDs);
|
||||
});
|
||||
|
||||
// Archive the assets
|
||||
|
@ -193,23 +195,21 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
if (SaveAssets)
|
||||
{
|
||||
m_log.DebugFormat("[ARCHIVER]: Saving {0} assets", assetUuids.Count);
|
||||
|
||||
// Asynchronously request all the assets required to perform this archive operation
|
||||
AssetsRequest ar
|
||||
= new AssetsRequest(
|
||||
|
||||
AssetsRequest ar = new AssetsRequest(
|
||||
new AssetsArchiver(m_archiveWriter), assetUuids,
|
||||
failedIDs.Count,
|
||||
m_rootScene.AssetService, m_rootScene.UserAccountService,
|
||||
m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets);
|
||||
|
||||
WorkManager.RunInThread(o => ar.Execute(), null, "Archive Assets Request");
|
||||
|
||||
// CloseArchive() will be called from ReceivedAllAssets()
|
||||
m_rootScene.RegionInfo.ScopeID, options, null);
|
||||
ar.Execute();
|
||||
assetUuids = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
|
||||
CloseArchive(string.Empty);
|
||||
// CloseArchive(string.Empty);
|
||||
}
|
||||
CloseArchive(string.Empty);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -218,7 +218,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
}
|
||||
}
|
||||
|
||||
private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, sbyte> assetUuids)
|
||||
private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, sbyte> assetUuids,
|
||||
HashSet<UUID> failedIDs, HashSet<UUID> uncertainAssetsUUIDs)
|
||||
{
|
||||
m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.Name);
|
||||
|
||||
|
@ -237,7 +238,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
{
|
||||
SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
|
||||
|
||||
if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
|
||||
if (!sceneObject.IsDeleted && !sceneObject.IsAttachment && !sceneObject.IsTemporary && !sceneObject.inTransit)
|
||||
{
|
||||
if (!CanUserArchiveObject(scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, FilterContent, permissionsModule))
|
||||
{
|
||||
|
@ -254,17 +255,39 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
|
||||
if (SaveAssets)
|
||||
{
|
||||
UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService, assetUuids);
|
||||
UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService, assetUuids, failedIDs, uncertainAssetsUUIDs);
|
||||
int prevAssets = assetUuids.Count;
|
||||
|
||||
foreach (SceneObjectGroup sceneObject in sceneObjects)
|
||||
{
|
||||
int curErrorCntr = assetGatherer.ErrorCount;
|
||||
int possible = assetGatherer.possibleNotAssetCount;
|
||||
assetGatherer.AddForInspection(sceneObject);
|
||||
assetGatherer.GatherAll();
|
||||
curErrorCntr = assetGatherer.ErrorCount - curErrorCntr;
|
||||
possible = assetGatherer.possibleNotAssetCount - possible;
|
||||
if(curErrorCntr > 0)
|
||||
{
|
||||
m_log.ErrorFormat("[ARCHIVER]: object {0} '{1}', at {2}, contains {3} references to missing or damaged assets",
|
||||
sceneObject.UUID, sceneObject.Name ,sceneObject.AbsolutePosition.ToString(), curErrorCntr);
|
||||
if(possible > 0)
|
||||
m_log.WarnFormat("[ARCHIVER Warning]: object also contains {0} references that may be to missing or damaged assets or not a problem", possible);
|
||||
}
|
||||
else if(possible > 0)
|
||||
{
|
||||
m_log.WarnFormat("[ARCHIVER Warning]: object {0} '{1}', at {2}, contains {3} references that may be to missing or damaged assets or not a problem",
|
||||
sceneObject.UUID, sceneObject.Name ,sceneObject.AbsolutePosition.ToString(), possible);
|
||||
}
|
||||
}
|
||||
|
||||
assetGatherer.GatherAll();
|
||||
|
||||
int errors = assetGatherer.FailedUUIDs.Count;
|
||||
m_log.DebugFormat(
|
||||
"[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
|
||||
sceneObjects.Count, assetUuids.Count - prevAssets);
|
||||
"[ARCHIVER]: {0} region scene objects to save reference {1} possible assets",
|
||||
sceneObjects.Count, assetUuids.Count - prevAssets + errors);
|
||||
if(errors > 0)
|
||||
m_log.DebugFormat("[ARCHIVER]: {0} of these have problems or are not assets and will be ignored", errors);
|
||||
}
|
||||
|
||||
if (numObjectsSkippedPermissions > 0)
|
||||
|
@ -572,7 +595,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
foreach (SceneObjectGroup sceneObject in sceneObjects)
|
||||
{
|
||||
//m_log.DebugFormat("[ARCHIVER]: Saving {0} {1}, {2}", entity.Name, entity.UUID, entity.GetType());
|
||||
|
||||
if(sceneObject.IsDeleted || sceneObject.inTransit)
|
||||
continue;
|
||||
string serializedObject = serializer.SerializeGroupToXml2(sceneObject, m_options);
|
||||
string objectPath = string.Format("{0}{1}", regionDir, ArchiveHelpers.CreateObjectPath(sceneObject));
|
||||
m_archiveWriter.WriteFile(objectPath, serializedObject);
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
/// <value>
|
||||
/// Post a message to the log every x assets as a progress bar
|
||||
/// </value>
|
||||
protected static int LOG_ASSET_LOAD_NOTIFICATION_INTERVAL = 50;
|
||||
protected static int LOG_ASSET_LOAD_NOTIFICATION_INTERVAL = 100;
|
||||
|
||||
/// <value>
|
||||
/// Keep a count of the number of assets written so that we can provide status updates
|
||||
|
|
|
@ -61,28 +61,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
Aborted
|
||||
};
|
||||
|
||||
/// <value>
|
||||
/// Timeout threshold if we still need assets or missing asset notifications but have stopped receiving them
|
||||
/// from the asset service
|
||||
/// </value>
|
||||
protected const int TIMEOUT = 60 * 1000;
|
||||
|
||||
/// <value>
|
||||
/// If a timeout does occur, limit the amount of UUID information put to the console.
|
||||
/// </value>
|
||||
protected const int MAX_UUID_DISPLAY_ON_TIMEOUT = 3;
|
||||
|
||||
protected System.Timers.Timer m_requestCallbackTimer;
|
||||
|
||||
/// <value>
|
||||
/// State of this request
|
||||
/// </value>
|
||||
private RequestState m_requestState = RequestState.Initial;
|
||||
|
||||
/// <value>
|
||||
/// uuids to request
|
||||
/// </value>
|
||||
protected IDictionary<UUID, sbyte> m_uuids;
|
||||
private int m_previousErrorsCount;
|
||||
|
||||
/// <value>
|
||||
/// Callback used when all the assets requested have been received.
|
||||
|
@ -104,6 +87,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
/// </value>
|
||||
private int m_repliesRequired;
|
||||
|
||||
private System.Timers.Timer m_timeOutTimer;
|
||||
private bool m_timeout;
|
||||
|
||||
/// <value>
|
||||
/// Asset service used to request the assets
|
||||
/// </value>
|
||||
|
@ -117,205 +103,98 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
|
||||
protected internal AssetsRequest(
|
||||
AssetsArchiver assetsArchiver, IDictionary<UUID, sbyte> uuids,
|
||||
int previousErrorsCount,
|
||||
IAssetService assetService, IUserAccountService userService,
|
||||
UUID scope, Dictionary<string, object> options,
|
||||
AssetsRequestCallback assetsRequestCallback)
|
||||
{
|
||||
m_assetsArchiver = assetsArchiver;
|
||||
m_uuids = uuids;
|
||||
m_previousErrorsCount = previousErrorsCount;
|
||||
m_assetsRequestCallback = assetsRequestCallback;
|
||||
m_assetService = assetService;
|
||||
m_userAccountService = userService;
|
||||
m_scopeID = scope;
|
||||
m_options = options;
|
||||
m_repliesRequired = uuids.Count;
|
||||
|
||||
// FIXME: This is a really poor way of handling the timeout since it will always leave the original requesting thread
|
||||
// hanging. Need to restructure so an original request thread waits for a ManualResetEvent on asset received
|
||||
// so we can properly abort that thread. Or request all assets synchronously, though that would be a more
|
||||
// radical change
|
||||
m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT);
|
||||
m_requestCallbackTimer.AutoReset = false;
|
||||
m_requestCallbackTimer.Elapsed += new ElapsedEventHandler(OnRequestCallbackTimeout);
|
||||
}
|
||||
|
||||
protected internal void Execute()
|
||||
{
|
||||
m_requestState = RequestState.Running;
|
||||
|
||||
m_log.DebugFormat("[ARCHIVER]: AssetsRequest executed looking for {0} possible assets", m_repliesRequired);
|
||||
|
||||
Culture.SetCurrentCulture();
|
||||
// We can stop here if there are no assets to fetch
|
||||
if (m_repliesRequired == 0)
|
||||
{
|
||||
m_requestState = RequestState.Completed;
|
||||
PerformAssetsRequestCallback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
m_requestCallbackTimer.Enabled = true;
|
||||
m_timeOutTimer = new System.Timers.Timer(60000);
|
||||
m_timeOutTimer .AutoReset = false;
|
||||
m_timeOutTimer.Elapsed += OnTimeout;
|
||||
m_timeout = false;
|
||||
|
||||
foreach (KeyValuePair<UUID, sbyte> kvp in m_uuids)
|
||||
{
|
||||
// m_log.DebugFormat("[ARCHIVER]: Requesting asset {0}", kvp.Key);
|
||||
|
||||
// m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback);
|
||||
AssetBase asset = m_assetService.Get(kvp.Key.ToString());
|
||||
PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset);
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args)
|
||||
{
|
||||
bool timedOut = true;
|
||||
|
||||
try
|
||||
{
|
||||
lock (this)
|
||||
string thiskey = kvp.Key.ToString();
|
||||
try
|
||||
{
|
||||
// Take care of the possibilty that this thread started but was paused just outside the lock before
|
||||
// the final request came in (assuming that such a thing is possible)
|
||||
if (m_requestState == RequestState.Completed)
|
||||
{
|
||||
timedOut = false;
|
||||
return;
|
||||
}
|
||||
|
||||
m_requestState = RequestState.Aborted;
|
||||
}
|
||||
|
||||
// Calculate which uuids were not found. This is an expensive way of doing it, but this is a failure
|
||||
// case anyway.
|
||||
List<UUID> uuids = new List<UUID>();
|
||||
foreach (UUID uuid in m_uuids.Keys)
|
||||
{
|
||||
uuids.Add(uuid);
|
||||
}
|
||||
|
||||
foreach (UUID uuid in m_foundAssetUuids)
|
||||
{
|
||||
uuids.Remove(uuid);
|
||||
}
|
||||
|
||||
foreach (UUID uuid in m_notFoundAssetUuids)
|
||||
{
|
||||
uuids.Remove(uuid);
|
||||
}
|
||||
|
||||
m_log.ErrorFormat(
|
||||
"[ARCHIVER]: Asset service failed to return information about {0} requested assets", uuids.Count);
|
||||
|
||||
int i = 0;
|
||||
foreach (UUID uuid in uuids)
|
||||
{
|
||||
m_log.ErrorFormat("[ARCHIVER]: No information about asset {0} received", uuid);
|
||||
|
||||
if (++i >= MAX_UUID_DISPLAY_ON_TIMEOUT)
|
||||
m_timeOutTimer.Enabled = true;
|
||||
AssetBase asset = m_assetService.Get(thiskey);
|
||||
if(m_timeout)
|
||||
break;
|
||||
|
||||
m_timeOutTimer.Enabled = false;
|
||||
|
||||
if(asset == null)
|
||||
{
|
||||
m_notFoundAssetUuids.Add(new UUID(thiskey));
|
||||
continue;
|
||||
}
|
||||
|
||||
sbyte assetType = kvp.Value;
|
||||
if (asset != null && assetType == (sbyte)AssetType.Unknown)
|
||||
{
|
||||
m_log.InfoFormat("[ARCHIVER]: Rewriting broken asset type for {0} to {1}", thiskey, SLUtil.AssetTypeFromCode(assetType));
|
||||
asset.Type = assetType;
|
||||
}
|
||||
|
||||
m_foundAssetUuids.Add(asset.FullID);
|
||||
m_assetsArchiver.WriteAsset(PostProcess(asset));
|
||||
}
|
||||
|
||||
if (uuids.Count > MAX_UUID_DISPLAY_ON_TIMEOUT)
|
||||
m_log.ErrorFormat(
|
||||
"[ARCHIVER]: (... {0} more not shown)", uuids.Count - MAX_UUID_DISPLAY_ON_TIMEOUT);
|
||||
|
||||
m_log.Error("[ARCHIVER]: Archive save aborted. PLEASE DO NOT USE THIS ARCHIVE, IT WILL BE INCOMPLETE.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ARCHIVER]: Timeout handler exception {0}{1}", e.Message, e.StackTrace);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (timedOut)
|
||||
WorkManager.RunInThread(PerformAssetsRequestCallback, true, "Archive Assets Request Callback");
|
||||
}
|
||||
}
|
||||
|
||||
protected void PreAssetRequestCallback(string fetchedAssetID, object assetType, AssetBase fetchedAsset)
|
||||
{
|
||||
// Check for broken asset types and fix them with the AssetType gleaned by UuidGatherer
|
||||
if (fetchedAsset != null && fetchedAsset.Type == (sbyte)AssetType.Unknown)
|
||||
{
|
||||
m_log.InfoFormat("[ARCHIVER]: Rewriting broken asset type for {0} to {1}", fetchedAsset.ID, SLUtil.AssetTypeFromCode((sbyte)assetType));
|
||||
fetchedAsset.Type = (sbyte)assetType;
|
||||
}
|
||||
|
||||
AssetRequestCallback(fetchedAssetID, this, fetchedAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called back by the asset cache when it has the asset
|
||||
/// </summary>
|
||||
/// <param name="assetID"></param>
|
||||
/// <param name="asset"></param>
|
||||
public void AssetRequestCallback(string id, object sender, AssetBase asset)
|
||||
{
|
||||
Culture.SetCurrentCulture();
|
||||
|
||||
try
|
||||
{
|
||||
lock (this)
|
||||
catch (Exception e)
|
||||
{
|
||||
//m_log.DebugFormat("[ARCHIVER]: Received callback for asset {0}", id);
|
||||
|
||||
m_requestCallbackTimer.Stop();
|
||||
|
||||
if ((m_requestState == RequestState.Aborted) || (m_requestState == RequestState.Completed))
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[ARCHIVER]: Received information about asset {0} while in state {1}. Ignoring.",
|
||||
id, m_requestState);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (asset != null)
|
||||
{
|
||||
// m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id);
|
||||
m_foundAssetUuids.Add(asset.FullID);
|
||||
|
||||
m_assetsArchiver.WriteAsset(PostProcess(asset));
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_log.DebugFormat("[ARCHIVER]: Recording asset {0} as not found", id);
|
||||
m_notFoundAssetUuids.Add(new UUID(id));
|
||||
}
|
||||
|
||||
if (m_foundAssetUuids.Count + m_notFoundAssetUuids.Count >= m_repliesRequired)
|
||||
{
|
||||
m_requestState = RequestState.Completed;
|
||||
if(m_notFoundAssetUuids.Count == 0)
|
||||
m_log.DebugFormat(
|
||||
"[ARCHIVER]: Successfully added {0} assets",
|
||||
m_foundAssetUuids.Count);
|
||||
else
|
||||
m_log.DebugFormat(
|
||||
"[ARCHIVER]: Successfully added {0} assets ({1} assets not found but these may be expected invalid references)",
|
||||
m_foundAssetUuids.Count, m_notFoundAssetUuids.Count);
|
||||
|
||||
|
||||
// We want to stop using the asset cache thread asap
|
||||
// as we now need to do the work of producing the rest of the archive
|
||||
WorkManager.RunInThread(PerformAssetsRequestCallback, false, "Archive Assets Request Callback");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_requestCallbackTimer.Start();
|
||||
}
|
||||
m_log.ErrorFormat("[ARCHIVER]: Execute failed with {0}", e);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ARCHIVER]: AssetRequestCallback failed with {0}", e);
|
||||
}
|
||||
|
||||
m_timeOutTimer.Dispose();
|
||||
int totalerrors = m_notFoundAssetUuids.Count + m_previousErrorsCount;
|
||||
|
||||
if(m_timeout)
|
||||
m_log.DebugFormat("[ARCHIVER]: Aborted because AssetService request timeout. Successfully added {0} assets", m_foundAssetUuids.Count);
|
||||
else if(totalerrors == 0)
|
||||
m_log.DebugFormat("[ARCHIVER]: Successfully added all {0} assets", m_foundAssetUuids.Count);
|
||||
else
|
||||
m_log.DebugFormat("[ARCHIVER]: Successfully added {0} assets ({1} of total possible assets requested were not found, were damaged or were not assets)",
|
||||
m_foundAssetUuids.Count, totalerrors);
|
||||
|
||||
PerformAssetsRequestCallback(m_timeout);
|
||||
}
|
||||
|
||||
private void OnTimeout(object source, ElapsedEventArgs args)
|
||||
{
|
||||
m_timeout = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform the callback on the original requester of the assets
|
||||
/// </summary>
|
||||
protected void PerformAssetsRequestCallback(object o)
|
||||
private void PerformAssetsRequestCallback(object o)
|
||||
{
|
||||
if(m_assetsRequestCallback == null)
|
||||
return;
|
||||
Culture.SetCurrentCulture();
|
||||
|
||||
Boolean timedOut = (Boolean)o;
|
||||
|
@ -331,7 +210,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
}
|
||||
}
|
||||
|
||||
protected AssetBase PostProcess(AssetBase asset)
|
||||
private AssetBase PostProcess(AssetBase asset)
|
||||
{
|
||||
if (asset.Type == (sbyte)AssetType.Object && asset.Data != null && m_options.ContainsKey("home"))
|
||||
{
|
||||
|
|
|
@ -176,6 +176,14 @@ namespace OpenSim.Region.CoreModules.World.Land
|
|||
}
|
||||
}
|
||||
|
||||
public void SendParcelsOverlay(IClientAPI client)
|
||||
{
|
||||
if (m_landManagementModule != null)
|
||||
{
|
||||
m_landManagementModule.SendParcelOverlay(client);
|
||||
}
|
||||
}
|
||||
|
||||
public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
|
||||
{
|
||||
if (m_landManagementModule != null)
|
||||
|
|
|
@ -44,14 +44,13 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// <param name='isReuseable'></param>
|
||||
void ReturnData(UUID id, IDynamicTexture texture);
|
||||
|
||||
UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams);
|
||||
UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
|
||||
int updateTimer);
|
||||
bool SetBlending, byte AlphaValue);
|
||||
UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
|
||||
int updateTimer, bool SetBlending, byte AlphaValue);
|
||||
UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
|
||||
int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face);
|
||||
UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams,
|
||||
int updateTimer);
|
||||
bool SetBlending, int disp, byte AlphaValue, int face);
|
||||
|
||||
UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams);
|
||||
|
||||
/// Apply a dynamically generated texture to all sides of the given prim. The texture is not persisted to the
|
||||
/// asset service.
|
||||
|
@ -62,8 +61,6 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// based texture or "image" to create a texture from an image at a particular URL</param>
|
||||
/// <param name="data">The data for the generator</param>
|
||||
/// <param name="extraParams">Parameters for the generator that don't form part of the main data.</param>
|
||||
/// <param name="updateTimer">If zero, the image is never updated after the first generation. If positive
|
||||
/// the image is updated at the given interval. Not implemented for </param>
|
||||
/// <param name="SetBlending">
|
||||
/// If true, the newly generated texture is blended with the appropriate existing ones on the prim
|
||||
/// </param>
|
||||
|
@ -76,7 +73,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// can be obtained as SceneObjectPart.Shape.Textures.DefaultTexture.TextureID
|
||||
/// </returns>
|
||||
UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams,
|
||||
int updateTimer, bool SetBlending, byte AlphaValue);
|
||||
bool SetBlending, byte AlphaValue);
|
||||
|
||||
/// <summary>
|
||||
/// Apply a dynamically generated texture to the given prim.
|
||||
|
@ -87,8 +84,6 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// based texture or "image" to create a texture from an image at a particular URL</param>
|
||||
/// <param name="data">The data for the generator</param>
|
||||
/// <param name="extraParams">Parameters for the generator that don't form part of the main data.</param>
|
||||
/// <param name="updateTimer">If zero, the image is never updated after the first generation. If positive
|
||||
/// the image is updated at the given interval. Not implemented for </param>
|
||||
/// <param name="SetBlending">
|
||||
/// If true, the newly generated texture is blended with the appropriate existing ones on the prim
|
||||
/// </param>
|
||||
|
@ -109,9 +104,8 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// to obtain it directly from the SceneObjectPart. For instance, if ALL_SIDES is set then this texture
|
||||
/// can be obtained as SceneObjectPart.Shape.Textures.DefaultTexture.TextureID
|
||||
/// </returns>
|
||||
UUID AddDynamicTextureData(
|
||||
UUID simID, UUID primID, string contentType, string data, string extraParams,
|
||||
int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face);
|
||||
UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams,
|
||||
bool SetBlending, int disp, byte AlphaValue, int face);
|
||||
|
||||
void GetDrawStringSize(string contentType, string text, string fontName, int fontSize,
|
||||
out double xSize, out double ySize);
|
||||
|
|
|
@ -116,16 +116,20 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public static void PartCollisionSound(SceneObjectPart part, List<CollisionForSoundInfo> collidersinfolist)
|
||||
{
|
||||
if (part.CollisionSoundType < 0)
|
||||
return;
|
||||
|
||||
if (collidersinfolist.Count == 0 || part == null)
|
||||
return;
|
||||
|
||||
if (part.VolumeDetectActive || (part.Flags & PrimFlags.Physics) == 0)
|
||||
return;
|
||||
|
||||
if (part.ParentGroup == null)
|
||||
SceneObjectGroup sog = part.ParentGroup;
|
||||
if (sog == null || sog.IsDeleted || sog.inTransit)
|
||||
return;
|
||||
|
||||
if (part.CollisionSoundType < 0)
|
||||
if(sog.CollisionSoundThrottled(part.CollisionSoundType))
|
||||
return;
|
||||
|
||||
float volume = part.CollisionSoundVolume;
|
||||
|
@ -189,15 +193,23 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
continue;
|
||||
}
|
||||
|
||||
SceneObjectPart otherPart = part.ParentGroup.Scene.GetSceneObjectPart(id);
|
||||
SceneObjectPart otherPart = sog.Scene.GetSceneObjectPart(id);
|
||||
if (otherPart != null)
|
||||
{
|
||||
if (otherPart.CollisionSoundType < 0 || otherPart.VolumeDetectActive)
|
||||
SceneObjectGroup othersog = otherPart.ParentGroup;
|
||||
if(othersog == null || othersog.IsDeleted || othersog.inTransit)
|
||||
continue;
|
||||
|
||||
int otherType = otherPart.CollisionSoundType;
|
||||
if (otherType < 0 || otherPart.VolumeDetectActive)
|
||||
continue;
|
||||
|
||||
if (!HaveSound)
|
||||
{
|
||||
if (otherPart.CollisionSoundType == 1)
|
||||
if(othersog.CollisionSoundThrottled(otherType))
|
||||
continue;
|
||||
|
||||
if (otherType == 1)
|
||||
{
|
||||
soundID = otherPart.CollisionSound;
|
||||
volume = otherPart.CollisionSoundVolume;
|
||||
|
@ -206,7 +218,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
else
|
||||
{
|
||||
if (otherPart.CollisionSoundType == 2)
|
||||
if (otherType == 2)
|
||||
{
|
||||
volume = otherPart.CollisionSoundVolume;
|
||||
if (volume == 0.0f)
|
||||
|
|
|
@ -855,7 +855,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <see cref="Scene.DeleteSceneObject"/>,
|
||||
/// <see cref="Scene.SelectPrim"/>,
|
||||
/// <see cref="Scene.DeselectPrim"/>,
|
||||
/// <see cref="SceneObjectGroup.UpdatePrimFlags"/>,
|
||||
/// <see cref="SceneObjectGroup.UpdateFlags"/>,
|
||||
/// <see cref="SceneObjectGroup.AbsolutePosition"/>
|
||||
/// </remarks>
|
||||
public event ParcelPrimCountTainted OnParcelPrimCountTainted;
|
||||
|
|
|
@ -295,6 +295,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
lock (m_frames)
|
||||
{
|
||||
KeyframeTimer.Add(this);
|
||||
m_lasttickMS = Util.GetTimeStampMS();
|
||||
m_timerStopped = false;
|
||||
}
|
||||
}
|
||||
|
@ -326,8 +327,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
newMotion.m_selected = true;
|
||||
}
|
||||
|
||||
newMotion.m_timerStopped = false;
|
||||
newMotion.m_running = true;
|
||||
// newMotion.m_timerStopped = false;
|
||||
// newMotion.m_running = true;
|
||||
newMotion.m_isCrossing = false;
|
||||
newMotion.m_waitingCrossing = false;
|
||||
}
|
||||
|
@ -483,9 +484,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_group.RootPart.AngularVelocity = Vector3.Zero;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
// m_group.RootPart.ScheduleTerseUpdate();
|
||||
// m_group.SendGroupRootTerseUpdate();
|
||||
m_group.RootPart.ScheduleTerseUpdate();
|
||||
m_frames.Clear();
|
||||
m_group.Scene.EventManager.TriggerMovingEndEvent(m_group.RootPart.LocalId);
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
|
@ -496,8 +498,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_group.RootPart.AngularVelocity = Vector3.Zero;
|
||||
m_skippedUpdates = 1000;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
// m_group.RootPart.ScheduleTerseUpdate();
|
||||
// m_group.SendGroupRootTerseUpdate();
|
||||
m_group.RootPart.ScheduleTerseUpdate();
|
||||
m_group.Scene.EventManager.TriggerMovingEndEvent(m_group.RootPart.LocalId);
|
||||
}
|
||||
|
||||
public void Suspend()
|
||||
|
@ -644,15 +647,16 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_group.RootPart.AngularVelocity = Vector3.Zero;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
|
||||
// m_group.SendGroupRootTerseUpdate();
|
||||
m_group.RootPart.ScheduleTerseUpdate();
|
||||
m_frames.Clear();
|
||||
}
|
||||
|
||||
Vector3 m_lastPosUpdate;
|
||||
Quaternion m_lastRotationUpdate;
|
||||
Vector3 m_currentVel;
|
||||
int m_skippedUpdates;
|
||||
[NonSerialized()] Vector3 m_lastPosUpdate;
|
||||
[NonSerialized()] Quaternion m_lastRotationUpdate;
|
||||
[NonSerialized()] Vector3 m_currentVel;
|
||||
[NonSerialized()] int m_skippedUpdates;
|
||||
[NonSerialized()] double m_lasttickMS;
|
||||
|
||||
private void DoOnTimer(double tickDuration)
|
||||
{
|
||||
|
@ -673,7 +677,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_skippedUpdates = 1000;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
// m_group.SendGroupRootTerseUpdate();
|
||||
m_group.RootPart.ScheduleTerseUpdate();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -696,6 +701,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
return;
|
||||
}
|
||||
|
||||
double nowMS = Util.GetTimeStampMS();
|
||||
|
||||
if (m_frames.Count == 0)
|
||||
{
|
||||
lock (m_frames)
|
||||
|
@ -716,10 +723,16 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_currentVel /= (m_currentFrame.TimeMS * 0.001f);
|
||||
|
||||
m_currentFrame.TimeMS += (int)tickDuration;
|
||||
m_lasttickMS = nowMS - 50f;
|
||||
update = true;
|
||||
}
|
||||
|
||||
m_currentFrame.TimeMS -= (int)tickDuration;
|
||||
int elapsed = (int)(nowMS - m_lasttickMS);
|
||||
if( elapsed > 3 * tickDuration)
|
||||
elapsed = (int)tickDuration;
|
||||
|
||||
m_currentFrame.TimeMS -= elapsed;
|
||||
m_lasttickMS = nowMS;
|
||||
|
||||
// Do the frame processing
|
||||
double remainingSteps = (double)m_currentFrame.TimeMS / tickDuration;
|
||||
|
@ -752,7 +765,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
else
|
||||
{
|
||||
bool lastSteps = remainingSteps < 4;
|
||||
// bool lastSteps = remainingSteps < 4;
|
||||
|
||||
Vector3 currentPosition = m_group.AbsolutePosition;
|
||||
Vector3 motionThisFrame = (Vector3)m_currentFrame.Position - currentPosition;
|
||||
motionThisFrame /= (float)remainingSteps;
|
||||
|
@ -766,20 +780,22 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, completed);
|
||||
step.Normalize();
|
||||
m_group.RootPart.RotationOffset = step;
|
||||
/*
|
||||
if (Math.Abs(step.X - m_lastRotationUpdate.X) > 0.001f
|
||||
|| Math.Abs(step.Y - m_lastRotationUpdate.Y) > 0.001f
|
||||
|| Math.Abs(step.Z - m_lastRotationUpdate.Z) > 0.001f)
|
||||
update = true;
|
||||
*/
|
||||
}
|
||||
|
||||
m_group.AbsolutePosition = m_nextPosition;
|
||||
if(lastSteps)
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
else
|
||||
// if(lastSteps)
|
||||
// m_group.RootPart.Velocity = Vector3.Zero;
|
||||
// else
|
||||
m_group.RootPart.Velocity = m_currentVel;
|
||||
|
||||
/*
|
||||
if(!update && (
|
||||
lastSteps ||
|
||||
// lastSteps ||
|
||||
m_skippedUpdates * tickDuration > 0.5 ||
|
||||
Math.Abs(m_nextPosition.X - currentPosition.X) > 5f ||
|
||||
Math.Abs(m_nextPosition.Y - currentPosition.Y) > 5f ||
|
||||
|
@ -790,15 +806,16 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
else
|
||||
m_skippedUpdates++;
|
||||
|
||||
}
|
||||
if(update)
|
||||
{
|
||||
m_lastPosUpdate = m_nextPosition;
|
||||
m_lastRotationUpdate = m_group.GroupRotation;
|
||||
m_skippedUpdates = 0;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
*/
|
||||
}
|
||||
// if(update)
|
||||
// {
|
||||
// m_lastPosUpdate = m_nextPosition;
|
||||
// m_lastRotationUpdate = m_group.GroupRotation;
|
||||
// m_skippedUpdates = 0;
|
||||
// m_group.SendGroupRootTerseUpdate();
|
||||
m_group.RootPart.ScheduleTerseUpdate();
|
||||
// }
|
||||
}
|
||||
|
||||
public Byte[] Serialize()
|
||||
|
@ -842,8 +859,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_skippedUpdates = 1000;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
// m_group.RootPart.ScheduleTerseUpdate();
|
||||
// m_group.SendGroupRootTerseUpdate();
|
||||
m_group.RootPart.ScheduleTerseUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -855,8 +872,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_skippedUpdates = 1000;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
// m_group.RootPart.ScheduleTerseUpdate();
|
||||
// m_group.SendGroupRootTerseUpdate();
|
||||
m_group.RootPart.ScheduleTerseUpdate();
|
||||
|
||||
if (m_running)
|
||||
{
|
||||
|
|
|
@ -425,25 +425,25 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
private void XWfloat(string name, float f)
|
||||
{
|
||||
writer.WriteElementString(name, f.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString(name, f.ToString(Culture.FormatProvider));
|
||||
}
|
||||
|
||||
private void XWVector(string name, Vector3 vec)
|
||||
{
|
||||
writer.WriteStartElement(name);
|
||||
writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("X", vec.X.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Y", vec.Y.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Z", vec.Z.ToString(Culture.FormatProvider));
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
private void XWQuat(string name, Quaternion quat)
|
||||
{
|
||||
writer.WriteStartElement(name);
|
||||
writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("X", quat.X.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Y", quat.Y.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Z", quat.Z.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("W", quat.W.ToString(Culture.FormatProvider));
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
|
|
|
@ -1651,10 +1651,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
physicsMS2 = (float)(tmpMS2 - tmpMS);
|
||||
tmpMS = tmpMS2;
|
||||
|
||||
/*
|
||||
// Apply any pending avatar force input to the avatar's velocity
|
||||
if (Frame % m_update_entitymovement == 0)
|
||||
m_sceneGraph.UpdateScenePresenceMovement();
|
||||
|
||||
*/
|
||||
if (Frame % (m_update_coarse_locations) == 0 && !m_sendingCoarseLocations)
|
||||
{
|
||||
m_sendingCoarseLocations = true;
|
||||
|
@ -1942,7 +1943,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
if (!m_backingup)
|
||||
{
|
||||
m_backingup = true;
|
||||
WorkManager.RunInThreadPool(o => Backup(false), null, string.Format("BackupWorker ({0})", Name));
|
||||
}
|
||||
}
|
||||
|
@ -1971,38 +1971,58 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
lock (m_returns)
|
||||
{
|
||||
EventManager.TriggerOnBackup(SimulationDataService, forced);
|
||||
|
||||
foreach (KeyValuePair<UUID, ReturnInfo> ret in m_returns)
|
||||
if(m_backingup)
|
||||
{
|
||||
UUID transaction = UUID.Random();
|
||||
m_log.WarnFormat("[Scene] Backup of {0} already running. New call skipped", RegionInfo.RegionName);
|
||||
return;
|
||||
}
|
||||
|
||||
GridInstantMessage msg = new GridInstantMessage();
|
||||
msg.fromAgentID = new Guid(UUID.Zero.ToString()); // From server
|
||||
msg.toAgentID = new Guid(ret.Key.ToString());
|
||||
msg.imSessionID = new Guid(transaction.ToString());
|
||||
msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
|
||||
msg.fromAgentName = "Server";
|
||||
msg.dialog = (byte)19; // Object msg
|
||||
msg.fromGroup = false;
|
||||
msg.offline = (byte)1;
|
||||
msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
|
||||
msg.Position = Vector3.Zero;
|
||||
msg.RegionID = RegionInfo.RegionID.Guid;
|
||||
m_backingup = true;
|
||||
try
|
||||
{
|
||||
EventManager.TriggerOnBackup(SimulationDataService, forced);
|
||||
|
||||
// We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3.
|
||||
msg.binaryBucket = Util.StringToBytes256("\0");
|
||||
if (ret.Value.count > 1)
|
||||
msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
|
||||
else
|
||||
msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
|
||||
if(m_returns.Count == 0)
|
||||
return;
|
||||
|
||||
IMessageTransferModule tr = RequestModuleInterface<IMessageTransferModule>();
|
||||
if (tr != null)
|
||||
if (tr == null)
|
||||
return;
|
||||
|
||||
uint unixtime = (uint)Util.UnixTimeSinceEpoch();
|
||||
uint estateid = RegionInfo.EstateSettings.ParentEstateID;
|
||||
Guid regionguid = RegionInfo.RegionID.Guid;
|
||||
|
||||
foreach (KeyValuePair<UUID, ReturnInfo> ret in m_returns)
|
||||
{
|
||||
GridInstantMessage msg = new GridInstantMessage();
|
||||
msg.fromAgentID = Guid.Empty; // From server
|
||||
msg.toAgentID = ret.Key.Guid;
|
||||
msg.imSessionID = Guid.NewGuid();
|
||||
msg.timestamp = unixtime;
|
||||
msg.fromAgentName = "Server";
|
||||
msg.dialog = 19; // Object msg
|
||||
msg.fromGroup = false;
|
||||
msg.offline = 1;
|
||||
msg.ParentEstateID = estateid;
|
||||
msg.Position = Vector3.Zero;
|
||||
msg.RegionID = regionguid;
|
||||
|
||||
// We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3.
|
||||
msg.binaryBucket = new Byte[1] {0};
|
||||
if (ret.Value.count > 1)
|
||||
msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
|
||||
else
|
||||
msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
|
||||
|
||||
tr.SendInstantMessage(msg, delegate(bool success) { });
|
||||
}
|
||||
m_returns.Clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_backingup = false;
|
||||
}
|
||||
m_returns.Clear();
|
||||
m_backingup = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4805,16 +4825,34 @@ Label_GroupsDone:
|
|||
public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position,
|
||||
Vector3 lookat, uint teleportFlags)
|
||||
{
|
||||
GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName);
|
||||
if (EntityTransferModule == null)
|
||||
{
|
||||
m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active");
|
||||
return;
|
||||
}
|
||||
|
||||
if (region == null)
|
||||
ScenePresence sp = GetScenePresence(remoteClient.AgentId);
|
||||
if (sp == null || sp.IsDeleted || sp.IsInTransit)
|
||||
return;
|
||||
|
||||
ulong regionHandle = 0;
|
||||
if(regionName == RegionInfo.RegionName)
|
||||
regionHandle = RegionInfo.RegionHandle;
|
||||
else
|
||||
{
|
||||
GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName);
|
||||
if (region != null)
|
||||
regionHandle = region.RegionHandle;
|
||||
}
|
||||
|
||||
if(regionHandle == 0)
|
||||
{
|
||||
// can't find the region: Tell viewer and abort
|
||||
remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found.");
|
||||
return;
|
||||
}
|
||||
|
||||
RequestTeleportLocation(remoteClient, region.RegionHandle, position, lookat, teleportFlags);
|
||||
EntityTransferModule.Teleport(sp, regionHandle, position, lookat, teleportFlags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -4828,19 +4866,17 @@ Label_GroupsDone:
|
|||
public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position,
|
||||
Vector3 lookAt, uint teleportFlags)
|
||||
{
|
||||
ScenePresence sp = GetScenePresence(remoteClient.AgentId);
|
||||
if (sp != null)
|
||||
if (EntityTransferModule == null)
|
||||
{
|
||||
if (EntityTransferModule != null)
|
||||
{
|
||||
EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active");
|
||||
sp.ControllingClient.SendTeleportFailed("Unable to perform teleports on this simulator.");
|
||||
}
|
||||
m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active");
|
||||
return;
|
||||
}
|
||||
|
||||
ScenePresence sp = GetScenePresence(remoteClient.AgentId);
|
||||
if (sp == null || sp.IsDeleted || sp.IsInTransit)
|
||||
return;
|
||||
|
||||
EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags);
|
||||
}
|
||||
|
||||
public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
|
||||
|
|
|
@ -1649,7 +1649,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
else // else turn it off
|
||||
vdtc = false;
|
||||
|
||||
group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, vdtc);
|
||||
group.UpdateFlags(UsePhysics, SetTemporary, SetPhantom, vdtc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1259,6 +1259,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
set { m_LoopSoundSlavePrims = value; }
|
||||
}
|
||||
|
||||
private double m_lastCollisionSoundMS;
|
||||
|
||||
/// <summary>
|
||||
/// The UUID for the region this object is in.
|
||||
/// </summary>
|
||||
|
@ -1336,7 +1338,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// </summary>
|
||||
public SceneObjectGroup()
|
||||
{
|
||||
|
||||
m_lastCollisionSoundMS = Util.GetTimeStampMS() + 1000.0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -2716,35 +2718,22 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
RootPart.KeyframeMotion.Stop();
|
||||
RootPart.KeyframeMotion = null;
|
||||
}
|
||||
UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
|
||||
UpdateFlags(usePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
|
||||
}
|
||||
|
||||
public void ScriptSetTemporaryStatus(bool makeTemporary)
|
||||
{
|
||||
UpdatePrimFlags(RootPart.LocalId, UsesPhysics, makeTemporary, IsPhantom, IsVolumeDetect);
|
||||
UpdateFlags(UsesPhysics, makeTemporary, IsPhantom, IsVolumeDetect);
|
||||
}
|
||||
|
||||
public void ScriptSetPhantomStatus(bool makePhantom)
|
||||
{
|
||||
UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, makePhantom, IsVolumeDetect);
|
||||
UpdateFlags(UsesPhysics, IsTemporary, makePhantom, IsVolumeDetect);
|
||||
}
|
||||
|
||||
public void ScriptSetVolumeDetect(bool makeVolumeDetect)
|
||||
{
|
||||
UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, IsPhantom, makeVolumeDetect);
|
||||
|
||||
/*
|
||||
ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore
|
||||
|
||||
if (PhysActor != null) // Should always be the case now
|
||||
{
|
||||
PhysActor.SetVolumeDetect(param);
|
||||
}
|
||||
if (param != 0)
|
||||
AddFlag(PrimFlags.Phantom);
|
||||
|
||||
ScheduleFullUpdate();
|
||||
*/
|
||||
UpdateFlags(UsesPhysics, IsTemporary, IsPhantom, makeVolumeDetect);
|
||||
}
|
||||
|
||||
public void applyImpulse(Vector3 impulse)
|
||||
|
@ -4029,84 +4018,80 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <param name="SetTemporary"></param>
|
||||
/// <param name="SetPhantom"></param>
|
||||
/// <param name="SetVolumeDetect"></param>
|
||||
public void UpdatePrimFlags(uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect)
|
||||
public void UpdateFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect)
|
||||
{
|
||||
if (m_scene == null || IsDeleted)
|
||||
return;
|
||||
|
||||
HasGroupChanged = true;
|
||||
|
||||
SceneObjectPart selectionPart = GetPart(localID);
|
||||
|
||||
if (Scene != null)
|
||||
if (SetTemporary)
|
||||
{
|
||||
if (SetTemporary)
|
||||
{
|
||||
DetachFromBackup();
|
||||
// Remove from database and parcel prim count
|
||||
//
|
||||
m_scene.DeleteFromStorage(UUID);
|
||||
}
|
||||
else if (!Backup)
|
||||
{
|
||||
// Previously been temporary now switching back so make it
|
||||
// available for persisting again
|
||||
AttachToBackup();
|
||||
}
|
||||
|
||||
m_scene.EventManager.TriggerParcelPrimCountTainted();
|
||||
DetachFromBackup();
|
||||
// Remove from database and parcel prim count
|
||||
//
|
||||
m_scene.DeleteFromStorage(UUID);
|
||||
}
|
||||
else if (!Backup)
|
||||
{
|
||||
// Previously been temporary now switching back so make it
|
||||
// available for persisting again
|
||||
AttachToBackup();
|
||||
}
|
||||
|
||||
if (selectionPart != null)
|
||||
|
||||
SceneObjectPart[] parts = m_parts.GetArray();
|
||||
|
||||
if (UsePhysics)
|
||||
{
|
||||
SceneObjectPart[] parts = m_parts.GetArray();
|
||||
int maxprims = m_scene.m_linksetPhysCapacity;
|
||||
bool checkShape = (maxprims > 0 &&
|
||||
parts.Length > maxprims);
|
||||
|
||||
if (Scene != null && UsePhysics)
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
int maxprims = m_scene.m_linksetPhysCapacity;
|
||||
bool checkShape = (maxprims > 0 &&
|
||||
parts.Length > maxprims);
|
||||
SceneObjectPart part = parts[i];
|
||||
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
if(part.PhysicsShapeType == (byte)PhysicsShapeType.None)
|
||||
continue; // assuming root type was checked elsewhere
|
||||
|
||||
if (checkShape)
|
||||
{
|
||||
SceneObjectPart part = parts[i];
|
||||
|
||||
if(part.PhysicsShapeType == (byte)PhysicsShapeType.None)
|
||||
continue; // assuming root type was checked elsewhere
|
||||
|
||||
if (checkShape)
|
||||
if (--maxprims < 0)
|
||||
{
|
||||
if (--maxprims < 0)
|
||||
{
|
||||
UsePhysics = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (part.Scale.X > m_scene.m_maxPhys ||
|
||||
part.Scale.Y > m_scene.m_maxPhys ||
|
||||
part.Scale.Z > m_scene.m_maxPhys )
|
||||
{
|
||||
UsePhysics = false; // Reset physics
|
||||
UsePhysics = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parts.Length > 1)
|
||||
{
|
||||
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
|
||||
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
if (part.Scale.X > m_scene.m_maxPhys ||
|
||||
part.Scale.Y > m_scene.m_maxPhys ||
|
||||
part.Scale.Z > m_scene.m_maxPhys )
|
||||
{
|
||||
|
||||
if (parts[i].UUID != m_rootPart.UUID)
|
||||
parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
|
||||
UsePhysics = false; // Reset physics
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_rootPart.PhysActor != null)
|
||||
m_rootPart.PhysActor.Building = false;
|
||||
}
|
||||
else
|
||||
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, false);
|
||||
}
|
||||
|
||||
if (parts.Length > 1)
|
||||
{
|
||||
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
|
||||
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
|
||||
if (parts[i].UUID != m_rootPart.UUID)
|
||||
parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
|
||||
}
|
||||
|
||||
if (m_rootPart.PhysActor != null)
|
||||
m_rootPart.PhysActor.Building = false;
|
||||
}
|
||||
else
|
||||
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, false);
|
||||
|
||||
m_scene.EventManager.TriggerParcelPrimCountTainted();
|
||||
}
|
||||
|
||||
public void UpdateExtraParam(uint localID, ushort type, bool inUse, byte[] data)
|
||||
|
@ -5528,7 +5513,33 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
public bool CollisionSoundThrottled(int collisionSoundType)
|
||||
{
|
||||
double time = m_lastCollisionSoundMS;
|
||||
// m_lastCollisionSoundMS = Util.GetTimeStampMS();
|
||||
// time = m_lastCollisionSoundMS - time;
|
||||
double now = Util.GetTimeStampMS();
|
||||
time = now - time;
|
||||
switch (collisionSoundType)
|
||||
{
|
||||
case 0: // default sounds
|
||||
case 2: // default sounds with volume set by script
|
||||
if(time < 300.0)
|
||||
return true;
|
||||
break;
|
||||
case 1: // selected sound
|
||||
if(time < 200.0)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_lastCollisionSoundMS = now;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -329,7 +329,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
private byte[] m_TextureAnimation;
|
||||
private byte m_clickAction;
|
||||
private Color m_color = Color.Black;
|
||||
private readonly List<uint> m_lastColliders = new List<uint>();
|
||||
private List<uint> m_lastColliders = new List<uint>();
|
||||
private bool m_lastLandCollide;
|
||||
private int m_linkNum;
|
||||
|
||||
private int m_scriptAccessPin;
|
||||
|
@ -369,9 +370,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
protected Vector3 m_lastPosition;
|
||||
protected Quaternion m_lastRotation;
|
||||
protected Vector3 m_lastVelocity;
|
||||
protected Vector3 m_lastAcceleration;
|
||||
protected Vector3 m_lastAcceleration; // acceleration is a derived var with high noise
|
||||
protected Vector3 m_lastAngularVelocity;
|
||||
protected int m_lastUpdateSentTime;
|
||||
protected double m_lastUpdateSentTime;
|
||||
protected float m_buoyancy = 0.0f;
|
||||
protected Vector3 m_force;
|
||||
protected Vector3 m_torque;
|
||||
|
@ -809,7 +810,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
// If this is a linkset, we don't want the physics engine mucking up our group position here.
|
||||
PhysicsActor actor = PhysActor;
|
||||
if (ParentID == 0)
|
||||
if (_parentID == 0)
|
||||
{
|
||||
if (actor != null)
|
||||
m_groupPosition = actor.Position;
|
||||
|
@ -838,7 +839,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
try
|
||||
{
|
||||
// Root prim actually goes at Position
|
||||
if (ParentID == 0)
|
||||
if (_parentID == 0)
|
||||
{
|
||||
actor.Position = value;
|
||||
}
|
||||
|
@ -880,7 +881,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
ParentGroup.InvalidBoundsRadius();
|
||||
|
||||
PhysicsActor actor = PhysActor;
|
||||
if (ParentID != 0 && actor != null)
|
||||
if (_parentID != 0 && actor != null)
|
||||
{
|
||||
actor.Position = GetWorldPosition();
|
||||
actor.Orientation = GetWorldRotation();
|
||||
|
@ -940,7 +941,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
PhysicsActor actor = PhysActor;
|
||||
// If this is a root of a linkset, the real rotation is what the physics engine thinks.
|
||||
// If not a root prim, the offset rotation is computed by SOG and is relative to the root.
|
||||
if (ParentID == 0 && (Shape.PCode != 9 || Shape.State == 0) && actor != null)
|
||||
if (_parentID == 0 && (Shape.PCode != 9 || Shape.State == 0) && actor != null)
|
||||
m_rotationOffset = actor.Orientation;
|
||||
|
||||
return m_rotationOffset;
|
||||
|
@ -957,7 +958,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
try
|
||||
{
|
||||
// Root prim gets value directly
|
||||
if (ParentID == 0)
|
||||
if (_parentID == 0)
|
||||
{
|
||||
actor.Orientation = value;
|
||||
//m_log.Info("[PART]: RO1:" + actor.Orientation.ToString());
|
||||
|
@ -1103,8 +1104,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
get
|
||||
{
|
||||
if (m_text.Length > 255)
|
||||
return m_text.Substring(0, 254);
|
||||
if (m_text.Length > 256) // yes > 254
|
||||
return m_text.Substring(0, 256);
|
||||
return m_text;
|
||||
}
|
||||
set { m_text = value; }
|
||||
|
@ -1258,6 +1259,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
get
|
||||
{
|
||||
if (_parentID == 0)
|
||||
return GroupPosition;
|
||||
|
||||
return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
|
||||
}
|
||||
}
|
||||
|
@ -1379,7 +1383,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public UUID LastOwnerID
|
||||
{
|
||||
get { return _lastOwnerID; }
|
||||
set { _lastOwnerID = value; }
|
||||
set {
|
||||
_lastOwnerID = value; }
|
||||
}
|
||||
|
||||
public UUID RezzerID
|
||||
|
@ -2422,7 +2427,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
|
||||
PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
|
||||
|
||||
if (ParentID != 0 && ParentID != LocalId)
|
||||
if (_parentID != 0 && _parentID != LocalId)
|
||||
{
|
||||
PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
|
||||
|
||||
|
@ -2788,12 +2793,13 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
ColliderArgs colliderArgs = new ColliderArgs();
|
||||
List<DetectedObject> colliding = new List<DetectedObject>();
|
||||
Scene parentScene = ParentGroup.Scene;
|
||||
foreach (uint localId in colliders)
|
||||
{
|
||||
if (localId == 0)
|
||||
continue;
|
||||
|
||||
SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId);
|
||||
SceneObjectPart obj = parentScene.GetSceneObjectPart(localId);
|
||||
if (obj != null)
|
||||
{
|
||||
if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
|
||||
|
@ -2801,7 +2807,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
else
|
||||
{
|
||||
ScenePresence av = ParentGroup.Scene.GetScenePresence(localId);
|
||||
ScenePresence av = parentScene.GetScenePresence(localId);
|
||||
if (av != null && (!av.IsChildAgent))
|
||||
{
|
||||
if (!dest.CollisionFilteredOut(av.UUID, av.Name))
|
||||
|
@ -2874,10 +2880,13 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public void PhysicsCollision(EventArgs e)
|
||||
{
|
||||
if (ParentGroup.Scene == null || ParentGroup.IsDeleted)
|
||||
if (ParentGroup.Scene == null || ParentGroup.IsDeleted || ParentGroup.inTransit)
|
||||
return;
|
||||
|
||||
// this a thread from physics ( heartbeat )
|
||||
bool thisHitLand = false;
|
||||
bool startLand = false;
|
||||
bool endedLand = false;
|
||||
|
||||
CollisionEventUpdate a = (CollisionEventUpdate)e;
|
||||
Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList;
|
||||
|
@ -2887,13 +2896,17 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
if (collissionswith.Count == 0)
|
||||
{
|
||||
if (m_lastColliders.Count == 0)
|
||||
if (m_lastColliders.Count == 0 && !m_lastLandCollide)
|
||||
return; // nothing to do
|
||||
|
||||
endedLand = m_lastLandCollide;
|
||||
m_lastLandCollide = false;
|
||||
|
||||
foreach (uint localID in m_lastColliders)
|
||||
{
|
||||
endedColliders.Add(localID);
|
||||
}
|
||||
|
||||
m_lastColliders.Clear();
|
||||
}
|
||||
else
|
||||
|
@ -2909,19 +2922,39 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
foreach (uint id in collissionswith.Keys)
|
||||
{
|
||||
thisHitColliders.Add(id);
|
||||
if (!m_lastColliders.Contains(id))
|
||||
if(id == 0)
|
||||
{
|
||||
startedColliders.Add(id);
|
||||
|
||||
curcontact = collissionswith[id];
|
||||
if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
|
||||
thisHitLand = true;
|
||||
if (!m_lastLandCollide)
|
||||
{
|
||||
soundinfo = new CollisionForSoundInfo();
|
||||
soundinfo.colliderID = id;
|
||||
soundinfo.position = curcontact.Position;
|
||||
soundinfo.relativeVel = curcontact.RelativeSpeed;
|
||||
soundinfolist.Add(soundinfo);
|
||||
startLand = true;
|
||||
curcontact = collissionswith[id];
|
||||
if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
|
||||
{
|
||||
soundinfo = new CollisionForSoundInfo();
|
||||
soundinfo.colliderID = id;
|
||||
soundinfo.position = curcontact.Position;
|
||||
soundinfo.relativeVel = curcontact.RelativeSpeed;
|
||||
soundinfolist.Add(soundinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thisHitColliders.Add(id);
|
||||
if (!m_lastColliders.Contains(id))
|
||||
{
|
||||
startedColliders.Add(id);
|
||||
|
||||
curcontact = collissionswith[id];
|
||||
if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
|
||||
{
|
||||
soundinfo = new CollisionForSoundInfo();
|
||||
soundinfo.colliderID = id;
|
||||
soundinfo.position = curcontact.Position;
|
||||
soundinfo.relativeVel = curcontact.RelativeSpeed;
|
||||
soundinfolist.Add(soundinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2930,9 +2963,18 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
foreach (uint id in collissionswith.Keys)
|
||||
{
|
||||
thisHitColliders.Add(id);
|
||||
if (!m_lastColliders.Contains(id))
|
||||
startedColliders.Add(id);
|
||||
if(id == 0)
|
||||
{
|
||||
thisHitLand = true;
|
||||
if (!m_lastLandCollide)
|
||||
startLand = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
thisHitColliders.Add(id);
|
||||
if (!m_lastColliders.Contains(id))
|
||||
startedColliders.Add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2951,22 +2993,32 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
foreach (uint localID in endedColliders)
|
||||
m_lastColliders.Remove(localID);
|
||||
|
||||
if(m_lastLandCollide && !thisHitLand)
|
||||
endedLand = true;
|
||||
|
||||
m_lastLandCollide = thisHitLand;
|
||||
|
||||
// play sounds.
|
||||
if (soundinfolist.Count > 0)
|
||||
CollisionSounds.PartCollisionSound(this, soundinfolist);
|
||||
}
|
||||
|
||||
EventManager eventmanager = ParentGroup.Scene.EventManager;
|
||||
|
||||
SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
|
||||
SendCollisionEvent(scriptEvents.collision_start, startedColliders, eventmanager.TriggerScriptCollidingStart);
|
||||
if (!VolumeDetectActive)
|
||||
SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
|
||||
SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
|
||||
SendCollisionEvent(scriptEvents.collision , m_lastColliders , eventmanager.TriggerScriptColliding);
|
||||
SendCollisionEvent(scriptEvents.collision_end , endedColliders , eventmanager.TriggerScriptCollidingEnd);
|
||||
|
||||
if (startedColliders.Contains(0))
|
||||
SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
|
||||
if (m_lastColliders.Contains(0))
|
||||
SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
|
||||
if (endedColliders.Contains(0))
|
||||
SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
|
||||
if (!VolumeDetectActive)
|
||||
{
|
||||
if (startLand)
|
||||
SendLandCollisionEvent(scriptEvents.land_collision_start, eventmanager.TriggerScriptLandCollidingStart);
|
||||
if (m_lastLandCollide)
|
||||
SendLandCollisionEvent(scriptEvents.land_collision, eventmanager.TriggerScriptLandColliding);
|
||||
if (endedLand)
|
||||
SendLandCollisionEvent(scriptEvents.land_collision_end, eventmanager.TriggerScriptLandCollidingEnd);
|
||||
}
|
||||
}
|
||||
|
||||
// The Collision sounds code calls this
|
||||
|
@ -2985,7 +3037,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
volume = 0;
|
||||
|
||||
int now = Util.EnvironmentTickCount();
|
||||
if(Util.EnvironmentTickCountSubtract(now,LastColSoundSentTime) <200)
|
||||
if(Util.EnvironmentTickCountSubtract(now, LastColSoundSentTime) < 200)
|
||||
return;
|
||||
|
||||
LastColSoundSentTime = now;
|
||||
|
@ -3026,7 +3078,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
//ParentGroup.RootPart.m_groupPosition = newpos;
|
||||
}
|
||||
/*
|
||||
if (pa != null && ParentID != 0 && ParentGroup != null)
|
||||
if (pa != null && _parentID != 0 && ParentGroup != null)
|
||||
{
|
||||
// Special case where a child object is requesting property updates.
|
||||
// This happens when linksets are modified to use flexible links rather than
|
||||
|
@ -3236,7 +3288,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
/// <summary>
|
||||
/// Schedule a terse update for this prim. Terse updates only send position,
|
||||
/// rotation, velocity and rotational velocity information.
|
||||
/// rotation, velocity and rotational velocity information. WRONG!!!!
|
||||
/// </summary>
|
||||
public void ScheduleTerseUpdate()
|
||||
{
|
||||
|
@ -3295,21 +3347,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
sp.SendAttachmentUpdate(this, UpdateRequired.FULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* this does nothing
|
||||
SendFullUpdateToClient(remoteClient, Position) ignores position parameter
|
||||
if (IsRoot)
|
||||
{
|
||||
if (ParentGroup.IsAttachment)
|
||||
{
|
||||
SendFullUpdateToClient(remoteClient, AttachedPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendFullUpdateToClient(remoteClient, AbsolutePosition);
|
||||
}
|
||||
}
|
||||
*/
|
||||
else
|
||||
{
|
||||
SendFullUpdateToClient(remoteClient);
|
||||
|
@ -3325,12 +3362,12 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
|
|||
return;
|
||||
|
||||
// Update the "last" values
|
||||
m_lastPosition = OffsetPosition;
|
||||
m_lastPosition = AbsolutePosition;
|
||||
m_lastRotation = RotationOffset;
|
||||
m_lastVelocity = Velocity;
|
||||
m_lastAcceleration = Acceleration;
|
||||
m_lastAngularVelocity = AngularVelocity;
|
||||
m_lastUpdateSentTime = Environment.TickCount;
|
||||
m_lastUpdateSentTime = Util.GetTimeStampMS();
|
||||
|
||||
ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
|
||||
{
|
||||
|
@ -3344,12 +3381,12 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
|
|||
return;
|
||||
|
||||
// Update the "last" values
|
||||
m_lastPosition = OffsetPosition;
|
||||
m_lastPosition = AbsolutePosition;
|
||||
m_lastRotation = RotationOffset;
|
||||
m_lastVelocity = Velocity;
|
||||
m_lastAcceleration = Acceleration;
|
||||
m_lastAngularVelocity = AngularVelocity;
|
||||
m_lastUpdateSentTime = Environment.TickCount;
|
||||
m_lastUpdateSentTime = Util.GetTimeStampMS();
|
||||
|
||||
if (ParentGroup.IsAttachment)
|
||||
{
|
||||
|
@ -3395,40 +3432,129 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
|
|||
ParentGroup.Scene.StatsReporter.AddObjectUpdates(1);
|
||||
}
|
||||
|
||||
|
||||
private const float ROTATION_TOLERANCE = 0.01f;
|
||||
private const float VELOCITY_TOLERANCE = 0.1f; // terse update vel has low resolution
|
||||
private const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
|
||||
private const double TIME_MS_TOLERANCE = 200f; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
|
||||
|
||||
/// <summary>
|
||||
/// Tell all the prims which have had updates scheduled
|
||||
/// </summary>
|
||||
public void SendScheduledUpdates()
|
||||
{
|
||||
const float ROTATION_TOLERANCE = 0.01f;
|
||||
const float VELOCITY_TOLERANCE = 0.001f;
|
||||
const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
|
||||
const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
|
||||
|
||||
{
|
||||
switch (UpdateFlag)
|
||||
{
|
||||
case UpdateRequired.TERSE:
|
||||
{
|
||||
case UpdateRequired.NONE:
|
||||
ClearUpdateSchedule();
|
||||
// Throw away duplicate or insignificant updates
|
||||
if (!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
|
||||
!Acceleration.Equals(m_lastAcceleration) ||
|
||||
!Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
|
||||
Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) ||
|
||||
!AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
|
||||
!OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
|
||||
Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE)
|
||||
break;
|
||||
|
||||
case UpdateRequired.TERSE:
|
||||
|
||||
ClearUpdateSchedule();
|
||||
bool needupdate = true;
|
||||
double now = Util.GetTimeStampMS();
|
||||
Vector3 curvel = Velocity;
|
||||
Vector3 curacc = Acceleration;
|
||||
Vector3 angvel = AngularVelocity;
|
||||
|
||||
while(true) // just to avoid ugly goto
|
||||
{
|
||||
SendTerseUpdateToAllClientsInternal();
|
||||
double elapsed = now - m_lastUpdateSentTime;
|
||||
if (elapsed > TIME_MS_TOLERANCE)
|
||||
break;
|
||||
|
||||
if( Math.Abs(curacc.X - m_lastAcceleration.X) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(curacc.Y - m_lastAcceleration.Y) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(curacc.Z - m_lastAcceleration.Z) > VELOCITY_TOLERANCE)
|
||||
break;
|
||||
|
||||
// velocity change is also direction not only norm)
|
||||
if( Math.Abs(curvel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(curvel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(curvel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE)
|
||||
break;
|
||||
|
||||
float vx = Math.Abs(curvel.X);
|
||||
if(vx > 128.0)
|
||||
break;
|
||||
float vy = Math.Abs(curvel.Y);
|
||||
if(vy > 128.0)
|
||||
break;
|
||||
float vz = Math.Abs(curvel.Z);
|
||||
if(vz > 128.0)
|
||||
break;
|
||||
|
||||
if (
|
||||
vx < VELOCITY_TOLERANCE &&
|
||||
vy < VELOCITY_TOLERANCE &&
|
||||
vz < VELOCITY_TOLERANCE
|
||||
)
|
||||
{
|
||||
if(!AbsolutePosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
|
||||
break;
|
||||
|
||||
if (vx < 1e-4 &&
|
||||
vy < 1e-4 &&
|
||||
vz < 1e-4 &&
|
||||
(
|
||||
Math.Abs(m_lastVelocity.X) > 1e-4 ||
|
||||
Math.Abs(m_lastVelocity.Y) > 1e-4 ||
|
||||
Math.Abs(m_lastVelocity.Z) > 1e-4
|
||||
))
|
||||
break;
|
||||
}
|
||||
|
||||
if( Math.Abs(angvel.X - m_lastAngularVelocity.X) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(angvel.Y - m_lastAngularVelocity.Y) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(angvel.Z - m_lastAngularVelocity.Z) > VELOCITY_TOLERANCE)
|
||||
break;
|
||||
|
||||
// viewer interpolators have a limit of 128m/s
|
||||
float ax = Math.Abs(angvel.X);
|
||||
if(ax > 64.0)
|
||||
break;
|
||||
float ay = Math.Abs(angvel.Y);
|
||||
if(ay > 64.0)
|
||||
break;
|
||||
float az = Math.Abs(angvel.Z);
|
||||
if(az > 64.0)
|
||||
break;
|
||||
|
||||
if (
|
||||
ax < VELOCITY_TOLERANCE &&
|
||||
ay < VELOCITY_TOLERANCE &&
|
||||
az < VELOCITY_TOLERANCE &&
|
||||
!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
|
||||
)
|
||||
break;
|
||||
|
||||
needupdate = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(needupdate)
|
||||
{
|
||||
|
||||
// Update the "last" values
|
||||
m_lastPosition = AbsolutePosition;
|
||||
m_lastRotation = RotationOffset;
|
||||
m_lastVelocity = curvel;
|
||||
m_lastAcceleration = curacc;
|
||||
m_lastAngularVelocity = angvel;
|
||||
m_lastUpdateSentTime = now;
|
||||
|
||||
ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
|
||||
{
|
||||
SendTerseUpdateToClient(client);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case UpdateRequired.FULL:
|
||||
{
|
||||
ClearUpdateSchedule();
|
||||
SendFullUpdateToAllClientsInternal();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3441,13 +3567,15 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
|
|||
if (ParentGroup == null || ParentGroup.Scene == null)
|
||||
return;
|
||||
|
||||
ClearUpdateSchedule();
|
||||
|
||||
// Update the "last" values
|
||||
m_lastPosition = OffsetPosition;
|
||||
m_lastPosition = AbsolutePosition;
|
||||
m_lastRotation = RotationOffset;
|
||||
m_lastVelocity = Velocity;
|
||||
m_lastAcceleration = Acceleration;
|
||||
m_lastAngularVelocity = AngularVelocity;
|
||||
m_lastUpdateSentTime = Environment.TickCount;
|
||||
m_lastUpdateSentTime = Util.GetTimeStampMS();
|
||||
|
||||
ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
|
||||
{
|
||||
|
@ -3460,13 +3588,15 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
|
|||
if (ParentGroup == null || ParentGroup.Scene == null)
|
||||
return;
|
||||
|
||||
ClearUpdateSchedule();
|
||||
|
||||
// Update the "last" values
|
||||
m_lastPosition = OffsetPosition;
|
||||
m_lastPosition = AbsolutePosition;
|
||||
m_lastRotation = RotationOffset;
|
||||
m_lastVelocity = Velocity;
|
||||
m_lastAcceleration = Acceleration;
|
||||
m_lastAngularVelocity = AngularVelocity;
|
||||
m_lastUpdateSentTime = Environment.TickCount;
|
||||
m_lastUpdateSentTime = Util.GetTimeStampMS();
|
||||
|
||||
if (ParentGroup.IsAttachment)
|
||||
{
|
||||
|
@ -4783,7 +4913,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
|
|||
pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
|
||||
pa.OnOutOfBounds += PhysicsOutOfBounds;
|
||||
|
||||
if (ParentID != 0 && ParentID != LocalId)
|
||||
if (_parentID != 0 && _parentID != LocalId)
|
||||
{
|
||||
PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
|
||||
|
||||
|
|
|
@ -279,8 +279,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
private bool MouseDown = false;
|
||||
public Vector3 lastKnownAllowedPosition;
|
||||
public bool sentMessageAboutRestrictedParcelFlyingDown;
|
||||
|
||||
public Vector4 CollisionPlane = Vector4.UnitW;
|
||||
|
||||
public Vector4 m_lastCollisionPlane = Vector4.UnitW;
|
||||
private byte m_lastState;
|
||||
private Vector3 m_lastPosition;
|
||||
private Quaternion m_lastRotation;
|
||||
private Vector3 m_lastVelocity;
|
||||
|
@ -2818,16 +2821,13 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
CameraAtAxis = agentData.CameraAtAxis;
|
||||
CameraLeftAxis = agentData.CameraLeftAxis;
|
||||
CameraUpAxis = agentData.CameraUpAxis;
|
||||
Quaternion camRot = Util.Axes2Rot(CameraAtAxis, CameraLeftAxis, CameraUpAxis);
|
||||
CameraRotation = camRot;
|
||||
|
||||
// The Agent's Draw distance setting
|
||||
// When we get to the point of re-computing neighbors everytime this
|
||||
// changes, then start using the agent's drawdistance rather than the
|
||||
// region's draw distance.
|
||||
|
||||
DrawDistance = agentData.Far;
|
||||
|
||||
CameraAtAxis.Normalize();
|
||||
CameraLeftAxis.Normalize();
|
||||
CameraUpAxis.Normalize();
|
||||
Quaternion camRot = Util.Axes2Rot(CameraAtAxis, CameraLeftAxis, CameraUpAxis);
|
||||
CameraRotation = camRot;
|
||||
|
||||
// Check if Client has camera in 'follow cam' or 'build' mode.
|
||||
// Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
|
||||
|
@ -3789,29 +3789,21 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
// Send terse position update if not sitting and position, velocity, or rotation
|
||||
// has changed significantly from last sent update
|
||||
if (!IsSatOnObject && (
|
||||
!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
|
||||
|| !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
|
||||
|| !m_pos.ApproxEquals(m_lastPosition, POSITION_LARGETOLERANCE)
|
||||
// if velocity is zero and it wasn't zero last time, send the update
|
||||
|| (Velocity == Vector3.Zero && m_lastVelocity != Vector3.Zero)
|
||||
// if position has moved just a little and velocity is very low, send the update
|
||||
|| (!m_pos.ApproxEquals(m_lastPosition, POSITION_SMALLTOLERANCE) && Velocity.LengthSquared() < LOWVELOCITYSQ )
|
||||
) )
|
||||
{
|
||||
/*
|
||||
if (!IsSatOnObject)
|
||||
{
|
||||
// this does need to be more complex later
|
||||
Vector3 vel = Velocity;
|
||||
Vector3 dpos = m_pos - m_lastPosition;
|
||||
if( Math.Abs(vel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE ||
|
||||
if( State != m_lastState ||
|
||||
Math.Abs(vel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(vel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(vel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE ||
|
||||
|
||||
Math.Abs(m_bodyRot.X - m_lastRotation.X) > ROTATION_TOLERANCE ||
|
||||
Math.Abs(m_bodyRot.Y - m_lastRotation.Y) > ROTATION_TOLERANCE ||
|
||||
Math.Abs(m_bodyRot.Z - m_lastRotation.Z) > ROTATION_TOLERANCE ||
|
||||
|
||||
(vel == Vector3.Zero && m_lastVelocity != Vector3.Zero) ||
|
||||
|
||||
Math.Abs(dpos.X) > POSITION_LARGETOLERANCE ||
|
||||
Math.Abs(dpos.Y) > POSITION_LARGETOLERANCE ||
|
||||
|
@ -3821,11 +3813,15 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
Math.Abs(dpos.Y) > POSITION_SMALLTOLERANCE ||
|
||||
Math.Abs(dpos.Z) > POSITION_SMALLTOLERANCE)
|
||||
&& vel.LengthSquared() < LOWVELOCITYSQ
|
||||
))
|
||||
) ||
|
||||
|
||||
Math.Abs(CollisionPlane.X - m_lastCollisionPlane.X) > POSITION_SMALLTOLERANCE ||
|
||||
Math.Abs(CollisionPlane.Y - m_lastCollisionPlane.Y) > POSITION_SMALLTOLERANCE ||
|
||||
Math.Abs(CollisionPlane.W - m_lastCollisionPlane.W) > POSITION_SMALLTOLERANCE
|
||||
)
|
||||
{
|
||||
*/
|
||||
SendTerseUpdateToAllClients();
|
||||
// }
|
||||
}
|
||||
}
|
||||
CheckForSignificantMovement();
|
||||
}
|
||||
|
@ -3921,11 +3917,14 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// </summary>
|
||||
public void SendTerseUpdateToAllClients()
|
||||
{
|
||||
m_scene.ForEachScenePresence(SendTerseUpdateToAgent);
|
||||
// Update the "last" values
|
||||
m_lastState = State;
|
||||
m_lastPosition = m_pos;
|
||||
m_lastRotation = m_bodyRot;
|
||||
m_lastVelocity = Velocity;
|
||||
m_lastCollisionPlane = CollisionPlane;
|
||||
|
||||
m_scene.ForEachScenePresence(SendTerseUpdateToAgent);
|
||||
// Update the "last" values
|
||||
TriggerScenePresenceUpdated();
|
||||
}
|
||||
|
||||
|
|
|
@ -86,9 +86,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
|
||||
writer.WriteStartElement("CoalescedObject");
|
||||
|
||||
writer.WriteAttributeString("x", size.X.ToString());
|
||||
writer.WriteAttributeString("y", size.Y.ToString());
|
||||
writer.WriteAttributeString("z", size.Z.ToString());
|
||||
writer.WriteAttributeString("x", size.X.ToString(Culture.FormatProvider));
|
||||
writer.WriteAttributeString("y", size.Y.ToString(Culture.FormatProvider));
|
||||
writer.WriteAttributeString("z", size.Z.ToString(Culture.FormatProvider));
|
||||
|
||||
// Embed the offsets into the group XML
|
||||
for (int i = 0; i < coaObjects.Count; i++)
|
||||
|
@ -100,9 +100,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
// i, obj.Name);
|
||||
|
||||
writer.WriteStartElement("SceneObjectGroup");
|
||||
writer.WriteAttributeString("offsetx", offsets[i].X.ToString());
|
||||
writer.WriteAttributeString("offsety", offsets[i].Y.ToString());
|
||||
writer.WriteAttributeString("offsetz", offsets[i].Z.ToString());
|
||||
writer.WriteAttributeString("offsetx", offsets[i].X.ToString(Culture.FormatProvider));
|
||||
writer.WriteAttributeString("offsety", offsets[i].Y.ToString(Culture.FormatProvider));
|
||||
writer.WriteAttributeString("offsetz", offsets[i].Z.ToString(Culture.FormatProvider));
|
||||
|
||||
SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, doScriptStates);
|
||||
|
||||
|
|
|
@ -65,7 +65,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
{
|
||||
using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment }))
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
return FromOriginalXmlFormat(reader);
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -109,11 +110,23 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
}
|
||||
}
|
||||
while (reader.ReadToNextSibling("Part"));
|
||||
reader.ReadEndElement();
|
||||
}
|
||||
|
||||
if (reader.Name == "KeyframeMotion" && reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
|
||||
string innerkeytxt = reader.ReadElementContentAsString();
|
||||
sceneObject.RootPart.KeyframeMotion =
|
||||
KeyframeMotion.FromData(sceneObject, Convert.FromBase64String(innerkeytxt));
|
||||
}
|
||||
else
|
||||
sceneObject.RootPart.KeyframeMotion = null;
|
||||
|
||||
// Script state may, or may not, exist. Not having any, is NOT
|
||||
// ever a problem.
|
||||
sceneObject.LoadScriptState(reader);
|
||||
|
||||
sceneObject.InvalidateDeepEffectivePerms();
|
||||
return sceneObject;
|
||||
}
|
||||
|
@ -210,9 +223,19 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
|
||||
writer.WriteEndElement(); // OtherParts
|
||||
|
||||
if (sceneObject.RootPart.KeyframeMotion != null)
|
||||
{
|
||||
Byte[] data = sceneObject.RootPart.KeyframeMotion.Serialize();
|
||||
|
||||
writer.WriteStartElement(String.Empty, "KeyframeMotion", String.Empty);
|
||||
writer.WriteBase64(data, 0, data.Length);
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
if (doScriptStates)
|
||||
sceneObject.SaveScriptedState(writer);
|
||||
|
||||
|
||||
if (!noRootElement)
|
||||
writer.WriteEndElement(); // SceneObjectGroup
|
||||
|
||||
|
@ -1459,10 +1482,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
writer.WriteElementString("Description", sop.Description);
|
||||
|
||||
writer.WriteStartElement("Color");
|
||||
writer.WriteElementString("R", sop.Color.R.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("G", sop.Color.G.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("B", sop.Color.B.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("A", sop.Color.A.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("R", sop.Color.R.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("G", sop.Color.G.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("B", sop.Color.B.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("A", sop.Color.A.ToString(Culture.FormatProvider));
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteElementString("Text", sop.Text);
|
||||
|
@ -1505,7 +1528,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
writer.WriteElementString("NextOwnerMask", sop.NextOwnerMask.ToString());
|
||||
WriteFlags(writer, "Flags", sop.Flags.ToString(), options);
|
||||
WriteUUID(writer, "CollisionSound", sop.CollisionSound, options);
|
||||
writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString());
|
||||
writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString(Culture.FormatProvider));
|
||||
if (sop.MediaUrl != null)
|
||||
writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString());
|
||||
WriteVector(writer, "AttachedPos", sop.AttachedPos);
|
||||
|
@ -1525,7 +1548,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
writer.WriteElementString("PayPrice3", sop.PayPrice[3].ToString());
|
||||
writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString());
|
||||
|
||||
writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString());
|
||||
writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString(Culture.FormatProvider));
|
||||
|
||||
WriteVector(writer, "Force", sop.Force);
|
||||
WriteVector(writer, "Torque", sop.Torque);
|
||||
|
@ -1542,22 +1565,22 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
writer.WriteElementString("RotationAxisLocks", sop.RotationAxisLocks.ToString().ToLower());
|
||||
writer.WriteElementString("PhysicsShapeType", sop.PhysicsShapeType.ToString().ToLower());
|
||||
if (sop.Density != 1000.0f)
|
||||
writer.WriteElementString("Density", sop.Density.ToString().ToLower());
|
||||
writer.WriteElementString("Density", sop.Density.ToString(Culture.FormatProvider));
|
||||
if (sop.Friction != 0.6f)
|
||||
writer.WriteElementString("Friction", sop.Friction.ToString().ToLower());
|
||||
writer.WriteElementString("Friction", sop.Friction.ToString(Culture.FormatProvider));
|
||||
if (sop.Restitution != 0.5f)
|
||||
writer.WriteElementString("Bounce", sop.Restitution.ToString().ToLower());
|
||||
writer.WriteElementString("Bounce", sop.Restitution.ToString(Culture.FormatProvider));
|
||||
if (sop.GravityModifier != 1.0f)
|
||||
writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString().ToLower());
|
||||
writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString(Culture.FormatProvider));
|
||||
WriteVector(writer, "CameraEyeOffset", sop.GetCameraEyeOffset());
|
||||
WriteVector(writer, "CameraAtOffset", sop.GetCameraAtOffset());
|
||||
|
||||
// if (sop.Sound != UUID.Zero) force it till sop crossing does clear it on child prim
|
||||
{
|
||||
WriteUUID(writer, "SoundID", sop.Sound, options);
|
||||
writer.WriteElementString("SoundGain", sop.SoundGain.ToString().ToLower());
|
||||
writer.WriteElementString("SoundGain", sop.SoundGain.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("SoundFlags", sop.SoundFlags.ToString().ToLower());
|
||||
writer.WriteElementString("SoundRadius", sop.SoundRadius.ToString().ToLower());
|
||||
writer.WriteElementString("SoundRadius", sop.SoundRadius.ToString(Culture.FormatProvider));
|
||||
}
|
||||
writer.WriteElementString("SoundQueueing", sop.SoundQueueing.ToString().ToLower());
|
||||
|
||||
|
@ -1577,19 +1600,19 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
static void WriteVector(XmlTextWriter writer, string name, Vector3 vec)
|
||||
{
|
||||
writer.WriteStartElement(name);
|
||||
writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("X", vec.X.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Y", vec.Y.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Z", vec.Z.ToString(Culture.FormatProvider));
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
static void WriteQuaternion(XmlTextWriter writer, string name, Quaternion quat)
|
||||
{
|
||||
writer.WriteStartElement(name);
|
||||
writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("X", quat.X.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Y", quat.Y.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Z", quat.Z.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("W", quat.W.ToString(Culture.FormatProvider));
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
|
@ -1731,22 +1754,22 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
// Don't serialize SculptData. It's just a copy of the asset, which can be loaded separately using 'SculptTexture'.
|
||||
|
||||
writer.WriteElementString("FlexiSoftness", shp.FlexiSoftness.ToString());
|
||||
writer.WriteElementString("FlexiTension", shp.FlexiTension.ToString());
|
||||
writer.WriteElementString("FlexiDrag", shp.FlexiDrag.ToString());
|
||||
writer.WriteElementString("FlexiGravity", shp.FlexiGravity.ToString());
|
||||
writer.WriteElementString("FlexiWind", shp.FlexiWind.ToString());
|
||||
writer.WriteElementString("FlexiForceX", shp.FlexiForceX.ToString());
|
||||
writer.WriteElementString("FlexiForceY", shp.FlexiForceY.ToString());
|
||||
writer.WriteElementString("FlexiForceZ", shp.FlexiForceZ.ToString());
|
||||
writer.WriteElementString("FlexiTension", shp.FlexiTension.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("FlexiDrag", shp.FlexiDrag.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("FlexiGravity", shp.FlexiGravity.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("FlexiWind", shp.FlexiWind.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("FlexiForceX", shp.FlexiForceX.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("FlexiForceY", shp.FlexiForceY.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("FlexiForceZ", shp.FlexiForceZ.ToString(Culture.FormatProvider));
|
||||
|
||||
writer.WriteElementString("LightColorR", shp.LightColorR.ToString());
|
||||
writer.WriteElementString("LightColorG", shp.LightColorG.ToString());
|
||||
writer.WriteElementString("LightColorB", shp.LightColorB.ToString());
|
||||
writer.WriteElementString("LightColorA", shp.LightColorA.ToString());
|
||||
writer.WriteElementString("LightRadius", shp.LightRadius.ToString());
|
||||
writer.WriteElementString("LightCutoff", shp.LightCutoff.ToString());
|
||||
writer.WriteElementString("LightFalloff", shp.LightFalloff.ToString());
|
||||
writer.WriteElementString("LightIntensity", shp.LightIntensity.ToString());
|
||||
writer.WriteElementString("LightColorR", shp.LightColorR.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("LightColorG", shp.LightColorG.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("LightColorB", shp.LightColorB.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("LightColorA", shp.LightColorA.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("LightRadius", shp.LightRadius.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("LightCutoff", shp.LightCutoff.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("LightFalloff", shp.LightFalloff.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("LightIntensity", shp.LightIntensity.ToString(Culture.FormatProvider));
|
||||
|
||||
writer.WriteElementString("FlexiEntry", shp.FlexiEntry.ToString().ToLower());
|
||||
writer.WriteElementString("LightEntry", shp.LightEntry.ToString().ToLower());
|
||||
|
|
|
@ -54,8 +54,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
|
||||
UUID ownerId = TestHelpers.ParseTail(0x1);
|
||||
SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(3, ownerId, "so1", 0x10);
|
||||
so1.ScriptSetPhysicsStatus(true);
|
||||
m_scene.AddSceneObject(so1);
|
||||
so1.ScriptSetPhysicsStatus(true);
|
||||
|
||||
Assert.That(m_scene.SceneGraph.GetTotalObjectsCount(), Is.EqualTo(3));
|
||||
Assert.That(m_scene.SceneGraph.GetActiveObjectsCount(), Is.EqualTo(3));
|
||||
|
|
|
@ -65,7 +65,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// </summary>
|
||||
/// <value>The gathered uuids.</value>
|
||||
public IDictionary<UUID, sbyte> GatheredUuids { get; private set; }
|
||||
|
||||
public HashSet<UUID> FailedUUIDs { get; private set; }
|
||||
public HashSet<UUID> UncertainAssetsUUIDs { get; private set; }
|
||||
public int possibleNotAssetCount { get; set; }
|
||||
public int ErrorCount { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets the next UUID to inspect.
|
||||
/// </summary>
|
||||
|
@ -92,7 +95,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <param name="assetService">
|
||||
/// Asset service.
|
||||
/// </param>
|
||||
public UuidGatherer(IAssetService assetService) : this(assetService, new Dictionary<UUID, sbyte>()) {}
|
||||
public UuidGatherer(IAssetService assetService) : this(assetService, new Dictionary<UUID, sbyte>(),
|
||||
new HashSet <UUID>(),new HashSet <UUID>()) {}
|
||||
public UuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector) : this(assetService, collector,
|
||||
new HashSet <UUID>(), new HashSet <UUID>()) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenSim.Region.Framework.Scenes.UuidGatherer"/> class.
|
||||
|
@ -101,16 +107,20 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// Asset service.
|
||||
/// </param>
|
||||
/// <param name="collector">
|
||||
/// Gathered UUIDs will be collected in this dictinaory.
|
||||
/// Gathered UUIDs will be collected in this dictionary.
|
||||
/// It can be pre-populated if you want to stop the gatherer from analyzing assets that have already been fetched and inspected.
|
||||
/// </param>
|
||||
public UuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector)
|
||||
public UuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector, HashSet <UUID> failedIDs, HashSet <UUID> uncertainAssetsUUIDs)
|
||||
{
|
||||
m_assetService = assetService;
|
||||
GatheredUuids = collector;
|
||||
|
||||
// FIXME: Not efficient for searching, can improve.
|
||||
m_assetUuidsToInspect = new Queue<UUID>();
|
||||
FailedUUIDs = failedIDs;
|
||||
UncertainAssetsUUIDs = uncertainAssetsUUIDs;
|
||||
ErrorCount = 0;
|
||||
possibleNotAssetCount = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -120,6 +130,19 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <param name="uuid">UUID.</param>
|
||||
public bool AddForInspection(UUID uuid)
|
||||
{
|
||||
if(uuid == UUID.Zero)
|
||||
return false;
|
||||
|
||||
if(FailedUUIDs.Contains(uuid))
|
||||
{
|
||||
if(UncertainAssetsUUIDs.Contains(uuid))
|
||||
possibleNotAssetCount++;
|
||||
else
|
||||
ErrorCount++;
|
||||
return false;
|
||||
}
|
||||
if(GatheredUuids.ContainsKey(uuid))
|
||||
return false;
|
||||
if (m_assetUuidsToInspect.Contains(uuid))
|
||||
return false;
|
||||
|
||||
|
@ -141,7 +164,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public void AddForInspection(SceneObjectGroup sceneObject)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
|
||||
// "[UUID GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
|
||||
if(sceneObject.IsDeleted)
|
||||
return;
|
||||
|
||||
SceneObjectPart[] parts = sceneObject.Parts;
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
|
@ -149,7 +174,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
SceneObjectPart part = parts[i];
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
|
||||
// "[UUID GATHERER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -207,9 +232,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// m_log.DebugFormat(
|
||||
// "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
|
||||
// tii.Name, tii.Type, part.Name, part.UUID);
|
||||
|
||||
if (!GatheredUuids.ContainsKey(tii.AssetID))
|
||||
AddForInspection(tii.AssetID, (sbyte)tii.Type);
|
||||
AddForInspection(tii.AssetID, (sbyte)tii.Type);
|
||||
}
|
||||
|
||||
// FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed
|
||||
|
@ -225,9 +248,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e);
|
||||
m_log.DebugFormat(
|
||||
"[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)",
|
||||
part.Shape.TextureEntry.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -278,55 +298,112 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
|
||||
private void GetAssetUuids(UUID assetUuid)
|
||||
{
|
||||
if(assetUuid == UUID.Zero)
|
||||
return;
|
||||
|
||||
if(FailedUUIDs.Contains(assetUuid))
|
||||
{
|
||||
if(UncertainAssetsUUIDs.Contains(assetUuid))
|
||||
possibleNotAssetCount++;
|
||||
else
|
||||
ErrorCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
// avoid infinite loops
|
||||
if (GatheredUuids.ContainsKey(assetUuid))
|
||||
return;
|
||||
|
||||
AssetBase assetBase;
|
||||
try
|
||||
{
|
||||
AssetBase assetBase = GetAsset(assetUuid);
|
||||
assetBase = GetAsset(assetUuid);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[UUID GATHERER]: Failed to get asset {0} : {1}", assetUuid, e.Message);
|
||||
ErrorCount++;
|
||||
FailedUUIDs.Add(assetUuid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (null != assetBase)
|
||||
if(assetBase == null)
|
||||
{
|
||||
// m_log.ErrorFormat("[UUID GATHERER]: asset {0} not found", assetUuid);
|
||||
FailedUUIDs.Add(assetUuid);
|
||||
if(UncertainAssetsUUIDs.Contains(assetUuid))
|
||||
possibleNotAssetCount++;
|
||||
else
|
||||
ErrorCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
if(UncertainAssetsUUIDs.Contains(assetUuid))
|
||||
UncertainAssetsUUIDs.Remove(assetUuid);
|
||||
|
||||
sbyte assetType = assetBase.Type;
|
||||
|
||||
if(assetBase.Data == null || assetBase.Data.Length == 0)
|
||||
{
|
||||
// m_log.ErrorFormat("[UUID GATHERER]: asset {0}, type {1} has no data", assetUuid, assetType);
|
||||
ErrorCount++;
|
||||
FailedUUIDs.Add(assetUuid);
|
||||
return;
|
||||
}
|
||||
|
||||
GatheredUuids[assetUuid] = assetType;
|
||||
try
|
||||
{
|
||||
if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
|
||||
{
|
||||
sbyte assetType = assetBase.Type;
|
||||
GatheredUuids[assetUuid] = assetType;
|
||||
|
||||
if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
|
||||
{
|
||||
RecordWearableAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.Gesture == assetType)
|
||||
{
|
||||
RecordGestureAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.Notecard == assetType)
|
||||
{
|
||||
RecordTextEmbeddedAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.LSLText == assetType)
|
||||
{
|
||||
RecordTextEmbeddedAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)OpenSimAssetType.Material == assetType)
|
||||
{
|
||||
RecordMaterialAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.Object == assetType)
|
||||
{
|
||||
RecordSceneObjectAssetUuids(assetBase);
|
||||
}
|
||||
RecordWearableAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.Gesture == assetType)
|
||||
{
|
||||
RecordGestureAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.Notecard == assetType)
|
||||
{
|
||||
RecordTextEmbeddedAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.LSLText == assetType)
|
||||
{
|
||||
RecordTextEmbeddedAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)OpenSimAssetType.Material == assetType)
|
||||
{
|
||||
RecordMaterialAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.Object == assetType)
|
||||
{
|
||||
RecordSceneObjectAssetUuids(assetBase);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset id {0}", assetUuid);
|
||||
throw;
|
||||
m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset with id {0} type {1}: {2}", assetUuid, assetType, e.Message);
|
||||
GatheredUuids.Remove(assetUuid);
|
||||
ErrorCount++;
|
||||
FailedUUIDs.Add(assetUuid);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddForInspection(UUID assetUuid, sbyte assetType)
|
||||
{
|
||||
if(assetUuid == UUID.Zero)
|
||||
return;
|
||||
|
||||
// Here, we want to collect uuids which require further asset fetches but mark the others as gathered
|
||||
if(FailedUUIDs.Contains(assetUuid))
|
||||
{
|
||||
if(UncertainAssetsUUIDs.Contains(assetUuid))
|
||||
possibleNotAssetCount++;
|
||||
else
|
||||
ErrorCount++;
|
||||
return;
|
||||
}
|
||||
if(GatheredUuids.ContainsKey(assetUuid))
|
||||
return;
|
||||
try
|
||||
{
|
||||
if ((sbyte)AssetType.Bodypart == assetType
|
||||
|
@ -458,8 +535,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
foreach (Match uuidMatch in uuidMatches)
|
||||
{
|
||||
UUID uuid = new UUID(uuidMatch.Value);
|
||||
if(uuid == UUID.Zero)
|
||||
continue;
|
||||
// m_log.DebugFormat("[UUID GATHERER]: Recording {0} in text", uuid);
|
||||
|
||||
if(!UncertainAssetsUUIDs.Contains(uuid))
|
||||
UncertainAssetsUUIDs.Add(uuid);
|
||||
AddForInspection(uuid);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,23 +59,23 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Config Settings Documentation.
|
||||
/// Each configuration setting can be specified in two places: OpenSim.ini or Regions.ini.
|
||||
/// If specified in Regions.ini, the settings should be within the region's section name.
|
||||
/// If specified in OpenSim.ini, the settings should be within the [AutoBackupModule] section.
|
||||
/// Region-specific settings take precedence.
|
||||
/// Configuration setting can be specified in two places: OpenSim.ini and/or Regions.ini.
|
||||
///
|
||||
/// AutoBackupModuleEnabled: True/False. Default: False. If True, use the auto backup module. This setting does not support per-region basis.
|
||||
/// All other settings under [AutoBackupModule] are ignored if AutoBackupModuleEnabled is false, even per-region settings!
|
||||
/// AutoBackup: True/False. Default: False. If True, activate auto backup functionality.
|
||||
/// This is the only required option for enabling auto-backup; the other options have sane defaults.
|
||||
/// If False for a particular region, the auto-backup module becomes a no-op for the region, and all other AutoBackup* settings are ignored.
|
||||
/// If False globally (the default), only regions that specifically override it in Regions.ini will get AutoBackup functionality.
|
||||
/// OpenSim.ini only settings section [AutoBackupModule]
|
||||
/// AutoBackupModuleEnabled: True/False. Default: False. If True, use the auto backup module.
|
||||
/// if false module is disable and all rest is ignored
|
||||
/// AutoBackupInterval: Double, non-negative value. Default: 720 (12 hours).
|
||||
/// The number of minutes between each backup attempt.
|
||||
/// If a negative or zero value is given, it is equivalent to setting AutoBackup = False.
|
||||
/// AutoBackupBusyCheck: True/False. Default: True.
|
||||
/// If True, we will only take an auto-backup if a set of conditions are met.
|
||||
/// These conditions are heuristics to try and avoid taking a backup when the sim is busy.
|
||||
/// AutoBackupDir: String. Default: "." (the current directory).
|
||||
/// A directory (absolute or relative) where backups should be saved.
|
||||
/// AutoBackupKeepFilesForDays remove files older than this number of days. 0 disables
|
||||
///
|
||||
/// Next can be set on OpenSim.ini, as default, and or per region in Regions.ini
|
||||
/// Region-specific settings take precedence.
|
||||
///
|
||||
/// AutoBackup: True/False. Default: False. If True, activate auto backup functionality.
|
||||
/// controls backup per region, with default optionaly set on OpenSim.ini
|
||||
|
||||
/// AutoBackupSkipAssets
|
||||
/// If true, assets are not saved to the oar file. Considerably reduces impact on simulator when backing up. Intended for when assets db is backed up separately
|
||||
/// AutoBackupKeepFilesForDays
|
||||
|
@ -89,40 +89,28 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
/// AutoBackupNaming: string. Default: Time.
|
||||
/// One of three strings (case insensitive):
|
||||
/// "Time": Current timestamp is appended to file name. An existing file will never be overwritten.
|
||||
/// "Sequential": A number is appended to the file name. So if RegionName_x.oar exists, we'll save to RegionName_{x+1}.oar next. An existing file will never be overwritten.
|
||||
/// "Overwrite": Always save to file named "${AutoBackupDir}/RegionName.oar", even if we have to overwrite an existing file.
|
||||
/// AutoBackupDir: String. Default: "." (the current directory).
|
||||
/// A directory (absolute or relative) where backups should be saved.
|
||||
/// AutoBackupDilationThreshold: float. Default: 0.5. Lower bound on time dilation required for BusyCheck heuristics to pass.
|
||||
/// If the time dilation is below this value, don't take a backup right now.
|
||||
/// AutoBackupAgentThreshold: int. Default: 10. Upper bound on # of agents in region required for BusyCheck heuristics to pass.
|
||||
/// If the number of agents is greater than this value, don't take a backup right now
|
||||
/// Save memory by setting low initial capacities. Minimizes impact in common cases of all regions using same interval, and instances hosting 1 ~ 4 regions.
|
||||
/// Also helps if you don't want AutoBackup at all.
|
||||
/// "Sequential": A number is appended to the file name. So if RegionName_x.oar exists, we'll save to RegionName_{x+1}.oar next. An existing file will never be overwritten.
|
||||
/// "Overwrite": Always save to file named "${AutoBackupDir}/RegionName.oar", even if we have to overwrite an existing file.
|
||||
/// </remarks>
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AutoBackupModule")]
|
||||
public class AutoBackupModule : ISharedRegionModule
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private readonly Dictionary<Guid, IScene> m_pendingSaves = new Dictionary<Guid, IScene>(1);
|
||||
private readonly AutoBackupModuleState m_defaultState = new AutoBackupModuleState();
|
||||
private readonly Dictionary<IScene, AutoBackupModuleState> m_states =
|
||||
new Dictionary<IScene, AutoBackupModuleState>(1);
|
||||
private readonly Dictionary<Timer, List<IScene>> m_timerMap =
|
||||
new Dictionary<Timer, List<IScene>>(1);
|
||||
private readonly Dictionary<double, Timer> m_timers = new Dictionary<double, Timer>(1);
|
||||
|
||||
private delegate T DefaultGetter<T>(string settingName, T defaultValue);
|
||||
private bool m_enabled;
|
||||
private ICommandConsole m_console;
|
||||
private List<Scene> m_Scenes = new List<Scene> ();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Whether the shared module should be enabled at all. NOT the same as m_Enabled in AutoBackupModuleState!
|
||||
/// </summary>
|
||||
private bool m_closed;
|
||||
private Timer m_masterTimer;
|
||||
private bool m_busy;
|
||||
private int m_KeepFilesForDays = -1;
|
||||
private string m_backupDir;
|
||||
private bool m_doneFirst;
|
||||
private double m_baseInterval;
|
||||
|
||||
private IConfigSource m_configSource;
|
||||
|
||||
|
@ -159,36 +147,38 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
void IRegionModuleBase.Initialise(IConfigSource source)
|
||||
{
|
||||
// Determine if we have been enabled at all in OpenSim.ini -- this is part and parcel of being an optional module
|
||||
this.m_configSource = source;
|
||||
m_configSource = source;
|
||||
IConfig moduleConfig = source.Configs["AutoBackupModule"];
|
||||
if (moduleConfig == null)
|
||||
{
|
||||
this.m_enabled = false;
|
||||
m_enabled = false;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.m_enabled = moduleConfig.GetBoolean("AutoBackupModuleEnabled", false);
|
||||
if (this.m_enabled)
|
||||
{
|
||||
m_log.Info("[AUTO BACKUP]: AutoBackupModule enabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Timer defTimer = new Timer(43200000);
|
||||
this.m_defaultState.Timer = defTimer;
|
||||
this.m_timers.Add(43200000, defTimer);
|
||||
defTimer.Elapsed += this.HandleElapsed;
|
||||
defTimer.AutoReset = true;
|
||||
defTimer.Start();
|
||||
m_enabled = moduleConfig.GetBoolean("AutoBackupModuleEnabled", false);
|
||||
if(!m_enabled)
|
||||
return;
|
||||
|
||||
AutoBackupModuleState abms = this.ParseConfig(null, true);
|
||||
m_log.Debug("[AUTO BACKUP]: Here is the default config:");
|
||||
m_log.Debug(abms.ToString());
|
||||
ParseDefaultConfig(moduleConfig);
|
||||
if(!m_enabled)
|
||||
return;
|
||||
|
||||
m_log.Debug("[AUTO BACKUP]: Default config:");
|
||||
m_log.Debug(m_defaultState.ToString());
|
||||
|
||||
m_log.Info("[AUTO BACKUP]: AutoBackupModule enabled");
|
||||
m_masterTimer = new Timer();
|
||||
m_masterTimer.Interval = m_baseInterval;
|
||||
m_masterTimer.Elapsed += HandleElapsed;
|
||||
m_masterTimer.AutoReset = false;
|
||||
|
||||
m_console = MainConsole.Instance;
|
||||
|
||||
m_console.Commands.AddCommand (
|
||||
"AutoBackup", true, "dooarbackup",
|
||||
"dooarbackup <regionName> | ALL",
|
||||
"saves the single region <regionName> to a oar or ALL regions in instance to oars, using same settings as AutoBackup. Note it restarts time interval", DoBackup);
|
||||
m_busy = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -196,13 +186,11 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
/// </summary>
|
||||
void IRegionModuleBase.Close()
|
||||
{
|
||||
if (!this.m_enabled)
|
||||
{
|
||||
if (!m_enabled)
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't want any timers firing while the sim's coming down; strange things may happen.
|
||||
this.StopAllTimers();
|
||||
m_masterTimer.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -211,18 +199,11 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
/// <param name="scene"></param>
|
||||
void IRegionModuleBase.AddRegion (Scene scene)
|
||||
{
|
||||
if (!this.m_enabled) {
|
||||
if (!m_enabled)
|
||||
return;
|
||||
}
|
||||
lock (m_Scenes) {
|
||||
m_Scenes.Add (scene);
|
||||
}
|
||||
m_console = MainConsole.Instance;
|
||||
|
||||
m_console.Commands.AddCommand (
|
||||
"AutoBackup", false, "dobackup",
|
||||
"dobackup",
|
||||
"do backup.", DoBackup);
|
||||
lock (m_Scenes)
|
||||
m_Scenes.Add (scene);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -231,28 +212,14 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
/// <param name="scene">The scene (region) to stop performing AutoBackup on.</param>
|
||||
void IRegionModuleBase.RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!this.m_enabled)
|
||||
{
|
||||
if (m_enabled)
|
||||
return;
|
||||
}
|
||||
m_Scenes.Remove (scene);
|
||||
if (this.m_states.ContainsKey(scene))
|
||||
|
||||
lock(m_Scenes)
|
||||
{
|
||||
AutoBackupModuleState abms = this.m_states[scene];
|
||||
|
||||
// Remove this scene out of the timer map list
|
||||
Timer timer = abms.Timer;
|
||||
List<IScene> list = this.m_timerMap[timer];
|
||||
list.Remove(scene);
|
||||
|
||||
// Shut down the timer if this was the last scene for the timer
|
||||
if (list.Count == 0)
|
||||
{
|
||||
this.m_timerMap.Remove(timer);
|
||||
this.m_timers.Remove(timer.Interval);
|
||||
timer.Close();
|
||||
}
|
||||
this.m_states.Remove(scene);
|
||||
if (m_states.ContainsKey(scene))
|
||||
m_states.Remove(scene);
|
||||
m_Scenes.Remove(scene);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,22 +230,29 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
/// <param name="scene">The scene to (possibly) perform AutoBackup on.</param>
|
||||
void IRegionModuleBase.RegionLoaded(Scene scene)
|
||||
{
|
||||
if (!this.m_enabled)
|
||||
{
|
||||
if (!m_enabled)
|
||||
return;
|
||||
}
|
||||
|
||||
// This really ought not to happen, but just in case, let's pretend it didn't...
|
||||
if (scene == null)
|
||||
{
|
||||
return;
|
||||
|
||||
AutoBackupModuleState abms = ParseConfig(scene);
|
||||
if(abms == null)
|
||||
{
|
||||
m_log.Debug("[AUTO BACKUP]: Config for " + scene.RegionInfo.RegionName);
|
||||
m_log.Debug("DEFAULT");
|
||||
abms = new AutoBackupModuleState(m_defaultState);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Debug("[AUTO BACKUP]: Config for " + scene.RegionInfo.RegionName);
|
||||
m_log.Debug(abms.ToString());
|
||||
}
|
||||
|
||||
AutoBackupModuleState abms = this.ParseConfig(scene, false);
|
||||
m_log.Debug("[AUTO BACKUP]: Config for " + scene.RegionInfo.RegionName);
|
||||
m_log.Debug((abms == null ? "DEFAULT" : abms.ToString()));
|
||||
|
||||
m_states.Add(scene, abms);
|
||||
m_busy = false;
|
||||
m_masterTimer.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -292,24 +266,122 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
|
||||
private void DoBackup (string module, string[] args)
|
||||
{
|
||||
if (args.Length != 2) {
|
||||
MainConsole.Instance.OutputFormat ("Usage: dobackup <regionname>");
|
||||
if (!m_enabled)
|
||||
return;
|
||||
|
||||
if (args.Length != 2)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat ("Usage: dooarbackup <regionname>");
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_busy)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat ("Already doing a backup, please try later");
|
||||
return;
|
||||
}
|
||||
|
||||
m_masterTimer.Stop();
|
||||
m_busy = true;
|
||||
|
||||
bool found = false;
|
||||
string name = args [1];
|
||||
lock (m_Scenes) {
|
||||
foreach (Scene s in m_Scenes) {
|
||||
string test = s.Name.ToString ();
|
||||
if (test == name) {
|
||||
Scene[] scenes;
|
||||
lock (m_Scenes)
|
||||
scenes = m_Scenes.ToArray();
|
||||
|
||||
if(scenes == null)
|
||||
return;
|
||||
|
||||
Scene s;
|
||||
try
|
||||
{
|
||||
if(name == "ALL")
|
||||
{
|
||||
for(int i = 0; i < scenes.Length; i++)
|
||||
{
|
||||
s = scenes[i];
|
||||
DoRegionBackup(s);
|
||||
if (!m_enabled)
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < scenes.Length; i++)
|
||||
{
|
||||
s = scenes[i];
|
||||
if (s.Name == name)
|
||||
{
|
||||
found = true;
|
||||
DoRegionBackup (s);
|
||||
DoRegionBackup(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
}
|
||||
catch { }
|
||||
finally
|
||||
{
|
||||
if (m_enabled)
|
||||
m_masterTimer.Start();
|
||||
m_busy = false;
|
||||
}
|
||||
if (!found)
|
||||
MainConsole.Instance.OutputFormat ("No such region {0}. Nothing to backup", name);
|
||||
}
|
||||
|
||||
private void ParseDefaultConfig(IConfig config)
|
||||
{
|
||||
|
||||
m_backupDir = ".";
|
||||
string backupDir = config.GetString("AutoBackupDir", ".");
|
||||
if (backupDir != ".")
|
||||
{
|
||||
try
|
||||
{
|
||||
DirectoryInfo dirinfo = new DirectoryInfo(backupDir);
|
||||
if (!dirinfo.Exists)
|
||||
dirinfo.Create();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_enabled = false;
|
||||
m_log.WarnFormat("[AUTO BACKUP]: Error accessing backup folder {0}. Module disabled. {1}",
|
||||
backupDir, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_backupDir = backupDir;
|
||||
|
||||
double interval = config.GetDouble("AutoBackupInterval", 720);
|
||||
interval *= 60000.0;
|
||||
m_baseInterval = interval;
|
||||
|
||||
// How long to keep backup files in days, 0 Disables this feature
|
||||
m_KeepFilesForDays = config.GetInt("AutoBackupKeepFilesForDays",m_KeepFilesForDays);
|
||||
|
||||
m_defaultState.Enabled = config.GetBoolean("AutoBackup", m_defaultState.Enabled);
|
||||
|
||||
m_defaultState.SkipAssets = config.GetBoolean("AutoBackupSkipAssets",m_defaultState.SkipAssets);
|
||||
|
||||
// Set file naming algorithm
|
||||
string stmpNamingType = config.GetString("AutoBackupNaming", m_defaultState.NamingType.ToString());
|
||||
NamingType tmpNamingType;
|
||||
if (stmpNamingType.Equals("Time", StringComparison.CurrentCultureIgnoreCase))
|
||||
tmpNamingType = NamingType.Time;
|
||||
else if (stmpNamingType.Equals("Sequential", StringComparison.CurrentCultureIgnoreCase))
|
||||
tmpNamingType = NamingType.Sequential;
|
||||
else if (stmpNamingType.Equals("Overwrite", StringComparison.CurrentCultureIgnoreCase))
|
||||
tmpNamingType = NamingType.Overwrite;
|
||||
else
|
||||
{
|
||||
m_log.Warn("Unknown naming type specified for Default");
|
||||
tmpNamingType = NamingType.Time;
|
||||
}
|
||||
m_defaultState.NamingType = tmpNamingType;
|
||||
|
||||
m_defaultState.Script = config.GetString("AutoBackupScript", m_defaultState.Script);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -319,329 +391,49 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
/// <param name="scene">The scene to look at.</param>
|
||||
/// <param name="parseDefault">Whether this call is intended to figure out what we consider the "default" config (applied to all regions unless overridden by per-region settings).</param>
|
||||
/// <returns>An AutoBackupModuleState contains most information you should need to know relevant to auto-backup, as applicable to a single region.</returns>
|
||||
private AutoBackupModuleState ParseConfig(IScene scene, bool parseDefault)
|
||||
private AutoBackupModuleState ParseConfig(IScene scene)
|
||||
{
|
||||
string sRegionName;
|
||||
string sRegionLabel;
|
||||
// string prepend;
|
||||
AutoBackupModuleState state;
|
||||
if(scene == null)
|
||||
return null;
|
||||
|
||||
if (parseDefault)
|
||||
{
|
||||
sRegionName = null;
|
||||
sRegionLabel = "DEFAULT";
|
||||
// prepend = "";
|
||||
state = this.m_defaultState;
|
||||
}
|
||||
else
|
||||
{
|
||||
sRegionName = scene.RegionInfo.RegionName;
|
||||
sRegionLabel = sRegionName;
|
||||
// prepend = sRegionName + ".";
|
||||
state = null;
|
||||
}
|
||||
string sRegionName;
|
||||
AutoBackupModuleState state = null;
|
||||
|
||||
sRegionName = scene.RegionInfo.RegionName;
|
||||
|
||||
// Read the config settings and set variables.
|
||||
IConfig regionConfig = (scene != null ? scene.Config.Configs[sRegionName] : null);
|
||||
IConfig config = this.m_configSource.Configs["AutoBackupModule"];
|
||||
if (config == null)
|
||||
{
|
||||
// defaultState would be disabled too if the section doesn't exist.
|
||||
state = this.m_defaultState;
|
||||
return state;
|
||||
}
|
||||
IConfig regionConfig = scene.Config.Configs[sRegionName];
|
||||
if (regionConfig == null)
|
||||
return null;
|
||||
|
||||
bool tmpEnabled = ResolveBoolean("AutoBackup", this.m_defaultState.Enabled, config, regionConfig);
|
||||
if (state == null && tmpEnabled != this.m_defaultState.Enabled)
|
||||
//Varies from default state
|
||||
{
|
||||
state = new AutoBackupModuleState();
|
||||
}
|
||||
state = new AutoBackupModuleState();
|
||||
|
||||
if (state != null)
|
||||
{
|
||||
state.Enabled = tmpEnabled;
|
||||
}
|
||||
|
||||
// If you don't want AutoBackup, we stop.
|
||||
if ((state == null && !this.m_defaultState.Enabled) || (state != null && !state.Enabled))
|
||||
{
|
||||
return state;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Info("[AUTO BACKUP]: Region " + sRegionLabel + " is AutoBackup ENABLED.");
|
||||
}
|
||||
|
||||
// Borrow an existing timer if one exists for the same interval; otherwise, make a new one.
|
||||
double interval =
|
||||
this.ResolveDouble("AutoBackupInterval", this.m_defaultState.IntervalMinutes,
|
||||
config, regionConfig) * 60000.0;
|
||||
if (state == null && interval != this.m_defaultState.IntervalMinutes * 60000.0)
|
||||
{
|
||||
state = new AutoBackupModuleState();
|
||||
}
|
||||
|
||||
if (this.m_timers.ContainsKey(interval))
|
||||
{
|
||||
if (state != null)
|
||||
{
|
||||
state.Timer = this.m_timers[interval];
|
||||
}
|
||||
m_log.Debug("[AUTO BACKUP]: Reusing timer for " + interval + " msec for region " +
|
||||
sRegionLabel);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 0 or negative interval == do nothing.
|
||||
if (interval <= 0.0 && state != null)
|
||||
{
|
||||
state.Enabled = false;
|
||||
return state;
|
||||
}
|
||||
if (state == null)
|
||||
{
|
||||
state = new AutoBackupModuleState();
|
||||
}
|
||||
Timer tim = new Timer(interval);
|
||||
state.Timer = tim;
|
||||
//Milliseconds -> minutes
|
||||
this.m_timers.Add(interval, tim);
|
||||
tim.Elapsed += this.HandleElapsed;
|
||||
tim.AutoReset = true;
|
||||
tim.Start();
|
||||
}
|
||||
|
||||
// Add the current region to the list of regions tied to this timer.
|
||||
if (scene != null)
|
||||
{
|
||||
if (state != null)
|
||||
{
|
||||
if (this.m_timerMap.ContainsKey(state.Timer))
|
||||
{
|
||||
this.m_timerMap[state.Timer].Add(scene);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<IScene> scns = new List<IScene>(1);
|
||||
scns.Add(scene);
|
||||
this.m_timerMap.Add(state.Timer, scns);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.m_timerMap.ContainsKey(this.m_defaultState.Timer))
|
||||
{
|
||||
this.m_timerMap[this.m_defaultState.Timer].Add(scene);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<IScene> scns = new List<IScene>(1);
|
||||
scns.Add(scene);
|
||||
this.m_timerMap.Add(this.m_defaultState.Timer, scns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool tmpBusyCheck = ResolveBoolean("AutoBackupBusyCheck",
|
||||
this.m_defaultState.BusyCheck, config, regionConfig);
|
||||
if (state == null && tmpBusyCheck != this.m_defaultState.BusyCheck)
|
||||
{
|
||||
state = new AutoBackupModuleState();
|
||||
}
|
||||
|
||||
if (state != null)
|
||||
{
|
||||
state.BusyCheck = tmpBusyCheck;
|
||||
}
|
||||
state.Enabled = regionConfig.GetBoolean("AutoBackup", m_defaultState.Enabled);
|
||||
|
||||
// Included Option To Skip Assets
|
||||
bool tmpSkipAssets = ResolveBoolean("AutoBackupSkipAssets",
|
||||
this.m_defaultState.SkipAssets, config, regionConfig);
|
||||
if (state == null && tmpSkipAssets != this.m_defaultState.SkipAssets)
|
||||
{
|
||||
state = new AutoBackupModuleState();
|
||||
}
|
||||
|
||||
if (state != null)
|
||||
{
|
||||
state.SkipAssets = tmpSkipAssets;
|
||||
}
|
||||
|
||||
// How long to keep backup files in days, 0 Disables this feature
|
||||
int tmpKeepFilesForDays = ResolveInt("AutoBackupKeepFilesForDays",
|
||||
this.m_defaultState.KeepFilesForDays, config, regionConfig);
|
||||
if (state == null && tmpKeepFilesForDays != this.m_defaultState.KeepFilesForDays)
|
||||
{
|
||||
state = new AutoBackupModuleState();
|
||||
}
|
||||
|
||||
if (state != null)
|
||||
{
|
||||
state.KeepFilesForDays = tmpKeepFilesForDays;
|
||||
}
|
||||
state.SkipAssets = regionConfig.GetBoolean("AutoBackupSkipAssets", m_defaultState.SkipAssets);
|
||||
|
||||
// Set file naming algorithm
|
||||
string stmpNamingType = ResolveString("AutoBackupNaming",
|
||||
this.m_defaultState.NamingType.ToString(), config, regionConfig);
|
||||
string stmpNamingType = regionConfig.GetString("AutoBackupNaming", m_defaultState.NamingType.ToString());
|
||||
NamingType tmpNamingType;
|
||||
if (stmpNamingType.Equals("Time", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
tmpNamingType = NamingType.Time;
|
||||
}
|
||||
else if (stmpNamingType.Equals("Sequential", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
tmpNamingType = NamingType.Sequential;
|
||||
}
|
||||
else if (stmpNamingType.Equals("Overwrite", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
tmpNamingType = NamingType.Overwrite;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("Unknown naming type specified for region " + sRegionLabel + ": " +
|
||||
m_log.Warn("Unknown naming type specified for region " + sRegionName + ": " +
|
||||
stmpNamingType);
|
||||
tmpNamingType = NamingType.Time;
|
||||
}
|
||||
m_defaultState.NamingType = tmpNamingType;
|
||||
|
||||
if (state == null && tmpNamingType != this.m_defaultState.NamingType)
|
||||
{
|
||||
state = new AutoBackupModuleState();
|
||||
}
|
||||
|
||||
if (state != null)
|
||||
{
|
||||
state.NamingType = tmpNamingType;
|
||||
}
|
||||
|
||||
string tmpScript = ResolveString("AutoBackupScript",
|
||||
this.m_defaultState.Script, config, regionConfig);
|
||||
if (state == null && tmpScript != this.m_defaultState.Script)
|
||||
{
|
||||
state = new AutoBackupModuleState();
|
||||
}
|
||||
|
||||
if (state != null)
|
||||
{
|
||||
state.Script = tmpScript;
|
||||
}
|
||||
|
||||
string tmpBackupDir = ResolveString("AutoBackupDir", ".", config, regionConfig);
|
||||
if (state == null && tmpBackupDir != this.m_defaultState.BackupDir)
|
||||
{
|
||||
state = new AutoBackupModuleState();
|
||||
}
|
||||
|
||||
if (state != null)
|
||||
{
|
||||
state.BackupDir = tmpBackupDir;
|
||||
// Let's give the user some convenience and auto-mkdir
|
||||
if (state.BackupDir != ".")
|
||||
{
|
||||
try
|
||||
{
|
||||
DirectoryInfo dirinfo = new DirectoryInfo(state.BackupDir);
|
||||
if (!dirinfo.Exists)
|
||||
{
|
||||
dirinfo.Create();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Warn(
|
||||
"[AUTO BACKUP]: BAD NEWS. You won't be able to save backups to directory " +
|
||||
state.BackupDir +
|
||||
" because it doesn't exist or there's a permissions issue with it. Here's the exception.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(state == null)
|
||||
return m_defaultState;
|
||||
|
||||
state.Script = regionConfig.GetString("AutoBackupScript", m_defaultState.Script);
|
||||
return state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function for ParseConfig.
|
||||
/// </summary>
|
||||
/// <param name="settingName"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <param name="global"></param>
|
||||
/// <param name="local"></param>
|
||||
/// <returns></returns>
|
||||
private bool ResolveBoolean(string settingName, bool defaultValue, IConfig global, IConfig local)
|
||||
{
|
||||
if(local != null)
|
||||
{
|
||||
return local.GetBoolean(settingName, global.GetBoolean(settingName, defaultValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
return global.GetBoolean(settingName, defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function for ParseConfig.
|
||||
/// </summary>
|
||||
/// <param name="settingName"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <param name="global"></param>
|
||||
/// <param name="local"></param>
|
||||
/// <returns></returns>
|
||||
private double ResolveDouble(string settingName, double defaultValue, IConfig global, IConfig local)
|
||||
{
|
||||
if (local != null)
|
||||
{
|
||||
return local.GetDouble(settingName, global.GetDouble(settingName, defaultValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
return global.GetDouble(settingName, defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function for ParseConfig.
|
||||
/// </summary>
|
||||
/// <param name="settingName"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <param name="global"></param>
|
||||
/// <param name="local"></param>
|
||||
/// <returns></returns>
|
||||
private int ResolveInt(string settingName, int defaultValue, IConfig global, IConfig local)
|
||||
{
|
||||
if (local != null)
|
||||
{
|
||||
return local.GetInt(settingName, global.GetInt(settingName, defaultValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
return global.GetInt(settingName, defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function for ParseConfig.
|
||||
/// </summary>
|
||||
/// <param name="settingName"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <param name="global"></param>
|
||||
/// <param name="local"></param>
|
||||
/// <returns></returns>
|
||||
private string ResolveString(string settingName, string defaultValue, IConfig global, IConfig local)
|
||||
{
|
||||
if (local != null)
|
||||
{
|
||||
return local.GetString(settingName, global.GetString(settingName, defaultValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
return global.GetString(settingName, defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when any auto-backup timer expires. This starts the code path for actually performing a backup.
|
||||
|
@ -650,63 +442,27 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
/// <param name="e"></param>
|
||||
private void HandleElapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
// TODO: heuristic thresholds are per-region, so we should probably run heuristics once per region
|
||||
// XXX: Running heuristics once per region could add undue performance penalty for something that's supposed to
|
||||
// check whether the region is too busy! Especially on sims with LOTS of regions.
|
||||
// Alternative: make heuristics thresholds global to the module rather than per-region. Less flexible,
|
||||
// but would allow us to be semantically correct while being easier on perf.
|
||||
// Alternative 2: Run heuristics once per unique set of heuristics threshold parameters! Ay yi yi...
|
||||
// Alternative 3: Don't support per-region heuristics at all; just accept them as a global only parameter.
|
||||
// Since this is pretty experimental, I haven't decided which alternative makes the most sense.
|
||||
if (this.m_closed)
|
||||
{
|
||||
if (!m_enabled || m_busy)
|
||||
return;
|
||||
}
|
||||
bool heuristicsRun = false;
|
||||
bool heuristicsPassed = false;
|
||||
if (!this.m_timerMap.ContainsKey((Timer) sender))
|
||||
|
||||
m_busy = true;
|
||||
if(m_doneFirst && m_KeepFilesForDays > 0)
|
||||
RemoveOldFiles();
|
||||
|
||||
foreach (IScene scene in m_Scenes)
|
||||
{
|
||||
m_log.Debug("[AUTO BACKUP]: Code-up error: timerMap doesn't contain timer " + sender);
|
||||
if (!m_enabled)
|
||||
return;
|
||||
DoRegionBackup(scene);
|
||||
}
|
||||
|
||||
List<IScene> tmap = this.m_timerMap[(Timer) sender];
|
||||
if (tmap != null && tmap.Count > 0)
|
||||
if (m_enabled)
|
||||
{
|
||||
foreach (IScene scene in tmap)
|
||||
{
|
||||
AutoBackupModuleState state = this.m_states[scene];
|
||||
bool heuristics = state.BusyCheck;
|
||||
|
||||
// Fast path: heuristics are on; already ran em; and sim is fine; OR, no heuristics for the region.
|
||||
if ((heuristics && heuristicsRun && heuristicsPassed) || !heuristics)
|
||||
{
|
||||
this.DoRegionBackup(scene);
|
||||
// Heuristics are on; ran but we're too busy -- keep going. Maybe another region will have heuristics off!
|
||||
}
|
||||
else if (heuristicsRun)
|
||||
{
|
||||
m_log.Info("[AUTO BACKUP]: Heuristics: too busy to backup " +
|
||||
scene.RegionInfo.RegionName + " right now.");
|
||||
continue;
|
||||
// Logical Deduction: heuristics are on but haven't been run
|
||||
}
|
||||
else
|
||||
{
|
||||
heuristicsPassed = this.RunHeuristics(scene);
|
||||
heuristicsRun = true;
|
||||
if (!heuristicsPassed)
|
||||
{
|
||||
m_log.Info("[AUTO BACKUP]: Heuristics: too busy to backup " +
|
||||
scene.RegionInfo.RegionName + " right now.");
|
||||
continue;
|
||||
}
|
||||
this.DoRegionBackup(scene);
|
||||
}
|
||||
|
||||
// Remove Old Backups
|
||||
this.RemoveOldFiles(state);
|
||||
}
|
||||
m_masterTimer.Start();
|
||||
m_busy = false;
|
||||
}
|
||||
|
||||
m_doneFirst = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -723,21 +479,29 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
return;
|
||||
}
|
||||
|
||||
AutoBackupModuleState state = this.m_states[scene];
|
||||
m_busy = true;
|
||||
|
||||
AutoBackupModuleState state;
|
||||
if(!m_states.TryGetValue(scene, out state))
|
||||
return;
|
||||
|
||||
if(state == null || !state.Enabled)
|
||||
return;
|
||||
|
||||
IRegionArchiverModule iram = scene.RequestModuleInterface<IRegionArchiverModule>();
|
||||
if(iram == null)
|
||||
return;
|
||||
|
||||
string savePath = BuildOarPath(scene.RegionInfo.RegionName,
|
||||
state.BackupDir,
|
||||
m_backupDir,
|
||||
state.NamingType);
|
||||
if (savePath == null)
|
||||
{
|
||||
m_log.Warn("[AUTO BACKUP]: savePath is null in HandleElapsed");
|
||||
return;
|
||||
}
|
||||
Guid guid = Guid.NewGuid();
|
||||
m_pendingSaves.Add(guid, scene);
|
||||
state.LiveRequests.Add(guid, savePath);
|
||||
((Scene) scene).EventManager.OnOarFileSaved += new EventManager.OarFileSaved(EventManager_OnOarFileSaved);
|
||||
|
||||
Guid guid = Guid.NewGuid();
|
||||
m_log.Info("[AUTO BACKUP]: Backing up region " + scene.RegionInfo.RegionName);
|
||||
|
||||
// Must pass options, even if dictionary is empty!
|
||||
|
@ -747,47 +511,37 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
options["noassets"] = true;
|
||||
|
||||
iram.ArchiveRegion(savePath, guid, options);
|
||||
ExecuteScript(state.Script, savePath);
|
||||
}
|
||||
|
||||
// For the given state, remove backup files older than the states KeepFilesForDays property
|
||||
private void RemoveOldFiles(AutoBackupModuleState state)
|
||||
private void RemoveOldFiles()
|
||||
{
|
||||
// 0 Means Disabled, Keep Files Indefinitely
|
||||
if (state.KeepFilesForDays > 0)
|
||||
string[] files;
|
||||
try
|
||||
{
|
||||
string[] files = Directory.GetFiles(state.BackupDir, "*.oar");
|
||||
DateTime CuttOffDate = DateTime.Now.AddDays(0 - state.KeepFilesForDays);
|
||||
|
||||
foreach (string file in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
FileInfo fi = new FileInfo(file);
|
||||
if (fi.CreationTime < CuttOffDate)
|
||||
fi.Delete();
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
m_log.Error("[AUTO BACKUP]: Error deleting old backup file '" + file + "': " + Ex.Message);
|
||||
}
|
||||
}
|
||||
files = Directory.GetFiles(m_backupDir, "*.oar");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by the Event Manager when the OnOarFileSaved event is fired.
|
||||
/// </summary>
|
||||
/// <param name="guid"></param>
|
||||
/// <param name="message"></param>
|
||||
void EventManager_OnOarFileSaved(Guid guid, string message)
|
||||
{
|
||||
// Ignore if the OAR save is being done by some other part of the system
|
||||
if (m_pendingSaves.ContainsKey(guid))
|
||||
catch (Exception Ex)
|
||||
{
|
||||
AutoBackupModuleState abms = m_states[(m_pendingSaves[guid])];
|
||||
ExecuteScript(abms.Script, abms.LiveRequests[guid]);
|
||||
m_pendingSaves.Remove(guid);
|
||||
abms.LiveRequests.Remove(guid);
|
||||
m_log.Error("[AUTO BACKUP]: Error reading backup folder " + m_backupDir + ": " + Ex.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
DateTime CuttOffDate = DateTime.Now.AddDays(-m_KeepFilesForDays);
|
||||
|
||||
foreach (string file in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
FileInfo fi = new FileInfo(file);
|
||||
if (fi.CreationTime < CuttOffDate)
|
||||
fi.Delete();
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
m_log.Error("[AUTO BACKUP]: Error deleting old backup file '" + file + "': " + Ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -817,63 +571,6 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
return output;
|
||||
}
|
||||
|
||||
/// <summary>Return value of true ==> not too busy; false ==> too busy to backup an OAR right now, or error.</summary>
|
||||
private bool RunHeuristics(IScene region)
|
||||
{
|
||||
try
|
||||
{
|
||||
return this.RunTimeDilationHeuristic(region) && this.RunAgentLimitHeuristic(region);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Warn("[AUTO BACKUP]: Exception in RunHeuristics", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the time dilation right at this instant is less than the threshold specified in AutoBackupDilationThreshold (default 0.5),
|
||||
/// then we return false and trip the busy heuristic's "too busy" path (i.e. don't save an OAR).
|
||||
/// AutoBackupDilationThreshold is a _LOWER BOUND_. Lower Time Dilation is bad, so if you go lower than our threshold, it's "too busy".
|
||||
/// </summary>
|
||||
/// <param name="region"></param>
|
||||
/// <returns>Returns true if we're not too busy; false means we've got worse time dilation than the threshold.</returns>
|
||||
private bool RunTimeDilationHeuristic(IScene region)
|
||||
{
|
||||
string regionName = region.RegionInfo.RegionName;
|
||||
return region.TimeDilation >=
|
||||
this.m_configSource.Configs["AutoBackupModule"].GetFloat(
|
||||
regionName + ".AutoBackupDilationThreshold", 0.5f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the root agent count right at this instant is less than the threshold specified in AutoBackupAgentThreshold (default 10),
|
||||
/// then we return false and trip the busy heuristic's "too busy" path (i.e., don't save an OAR).
|
||||
/// AutoBackupAgentThreshold is an _UPPER BOUND_. Higher Agent Count is bad, so if you go higher than our threshold, it's "too busy".
|
||||
/// </summary>
|
||||
/// <param name="region"></param>
|
||||
/// <returns>Returns true if we're not too busy; false means we've got more agents on the sim than the threshold.</returns>
|
||||
private bool RunAgentLimitHeuristic(IScene region)
|
||||
{
|
||||
string regionName = region.RegionInfo.RegionName;
|
||||
try
|
||||
{
|
||||
Scene scene = (Scene) region;
|
||||
// TODO: Why isn't GetRootAgentCount() a method in the IScene interface? Seems generally useful...
|
||||
return scene.GetRootAgentCount() <=
|
||||
this.m_configSource.Configs["AutoBackupModule"].GetInt(
|
||||
regionName + ".AutoBackupAgentThreshold", 10);
|
||||
}
|
||||
catch (InvalidCastException ice)
|
||||
{
|
||||
m_log.Debug(
|
||||
"[AUTO BACKUP]: I NEED MAINTENANCE: IScene is not a Scene; can't get root agent count!",
|
||||
ice);
|
||||
return true;
|
||||
// Non-obstructionist safest answer...
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run the script or executable specified by the "AutoBackupScript" config setting.
|
||||
/// Of course this is a security risk if you let anyone modify OpenSim.ini and they want to run some nasty bash script.
|
||||
|
@ -919,18 +616,6 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
" is yacking on stderr: " + e.Data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quickly stop all timers from firing.
|
||||
/// </summary>
|
||||
private void StopAllTimers()
|
||||
{
|
||||
foreach (Timer t in this.m_timerMap.Keys)
|
||||
{
|
||||
t.Close();
|
||||
}
|
||||
this.m_closed = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine the next unique filename by number, for "Sequential" AutoBackupNamingType.
|
||||
/// </summary>
|
||||
|
@ -1033,5 +718,3 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,26 +38,20 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
///
|
||||
public class AutoBackupModuleState
|
||||
{
|
||||
private Dictionary<Guid, string> m_liveRequests = null;
|
||||
|
||||
public AutoBackupModuleState()
|
||||
{
|
||||
this.Enabled = false;
|
||||
this.BackupDir = ".";
|
||||
this.BusyCheck = true;
|
||||
this.SkipAssets = false;
|
||||
this.Timer = null;
|
||||
this.NamingType = NamingType.Time;
|
||||
this.Script = null;
|
||||
this.KeepFilesForDays = 0;
|
||||
Enabled = false;
|
||||
SkipAssets = false;
|
||||
NamingType = NamingType.Time;
|
||||
Script = null;
|
||||
}
|
||||
|
||||
public Dictionary<Guid, string> LiveRequests
|
||||
public AutoBackupModuleState(AutoBackupModuleState copyFrom)
|
||||
{
|
||||
get {
|
||||
return this.m_liveRequests ??
|
||||
(this.m_liveRequests = new Dictionary<Guid, string>(1));
|
||||
}
|
||||
Enabled = copyFrom.Enabled;
|
||||
SkipAssets = copyFrom.SkipAssets;
|
||||
NamingType = copyFrom.NamingType;
|
||||
Script = copyFrom.Script;
|
||||
}
|
||||
|
||||
public bool Enabled
|
||||
|
@ -66,33 +60,6 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
set;
|
||||
}
|
||||
|
||||
public System.Timers.Timer Timer
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public double IntervalMinutes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.Timer == null)
|
||||
{
|
||||
return -1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.Timer.Interval / 60000.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool BusyCheck
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool SkipAssets
|
||||
{
|
||||
get;
|
||||
|
@ -105,36 +72,19 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
|
|||
set;
|
||||
}
|
||||
|
||||
public string BackupDir
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public NamingType NamingType
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public int KeepFilesForDays
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public new string ToString()
|
||||
{
|
||||
string retval = "";
|
||||
|
||||
retval += "[AUTO BACKUP]: AutoBackup: " + (Enabled ? "ENABLED" : "DISABLED") + "\n";
|
||||
retval += "[AUTO BACKUP]: Interval: " + IntervalMinutes + " minutes" + "\n";
|
||||
retval += "[AUTO BACKUP]: Do Busy Check: " + (BusyCheck ? "Yes" : "No") + "\n";
|
||||
retval += "[AUTO BACKUP]: Naming Type: " + NamingType.ToString() + "\n";
|
||||
retval += "[AUTO BACKUP]: Backup Dir: " + BackupDir + "\n";
|
||||
retval += "[AUTO BACKUP]: Script: " + Script + "\n";
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,8 +27,13 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Timers;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
using Mono.Addins;
|
||||
|
@ -38,9 +43,7 @@ using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
|
|||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
using Timer= System.Timers.Timer;
|
||||
|
||||
namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
||||
{
|
||||
|
@ -48,7 +51,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
/// Version 2.02 - Still hacky
|
||||
/// </summary>
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "TreePopulatorModule")]
|
||||
public class TreePopulatorModule : INonSharedRegionModule, ICommandableModule, IVegetationModule
|
||||
public class TreePopulatorModule : INonSharedRegionModule, ICommandableModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private readonly Commander m_commander = new Commander("tree");
|
||||
|
@ -82,20 +85,20 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
{
|
||||
Copse cp = (Copse)DeserializeObject(fileName);
|
||||
|
||||
this.m_name = cp.m_name;
|
||||
this.m_frozen = cp.m_frozen;
|
||||
this.m_tree_quantity = cp.m_tree_quantity;
|
||||
this.m_treeline_high = cp.m_treeline_high;
|
||||
this.m_treeline_low = cp.m_treeline_low;
|
||||
this.m_range = cp.m_range;
|
||||
this.m_tree_type = cp.m_tree_type;
|
||||
this.m_seed_point = cp.m_seed_point;
|
||||
this.m_initial_scale = cp.m_initial_scale;
|
||||
this.m_maximum_scale = cp.m_maximum_scale;
|
||||
this.m_initial_scale = cp.m_initial_scale;
|
||||
this.m_rate = cp.m_rate;
|
||||
this.m_planted = planted;
|
||||
this.m_trees = new List<UUID>();
|
||||
m_name = cp.m_name;
|
||||
m_frozen = cp.m_frozen;
|
||||
m_tree_quantity = cp.m_tree_quantity;
|
||||
m_treeline_high = cp.m_treeline_high;
|
||||
m_treeline_low = cp.m_treeline_low;
|
||||
m_range = cp.m_range;
|
||||
m_tree_type = cp.m_tree_type;
|
||||
m_seed_point = cp.m_seed_point;
|
||||
m_initial_scale = cp.m_initial_scale;
|
||||
m_maximum_scale = cp.m_maximum_scale;
|
||||
m_initial_scale = cp.m_initial_scale;
|
||||
m_rate = cp.m_rate;
|
||||
m_planted = planted;
|
||||
m_trees = new List<UUID>();
|
||||
}
|
||||
|
||||
public Copse(string copsedef)
|
||||
|
@ -103,61 +106,63 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
char[] delimiterChars = {':', ';'};
|
||||
string[] field = copsedef.Split(delimiterChars);
|
||||
|
||||
this.m_name = field[1].Trim();
|
||||
this.m_frozen = (copsedef[0] == 'F');
|
||||
this.m_tree_quantity = int.Parse(field[2]);
|
||||
this.m_treeline_high = float.Parse(field[3], Culture.NumberFormatInfo);
|
||||
this.m_treeline_low = float.Parse(field[4], Culture.NumberFormatInfo);
|
||||
this.m_range = double.Parse(field[5], Culture.NumberFormatInfo);
|
||||
this.m_tree_type = (Tree) Enum.Parse(typeof(Tree),field[6]);
|
||||
this.m_seed_point = Vector3.Parse(field[7]);
|
||||
this.m_initial_scale = Vector3.Parse(field[8]);
|
||||
this.m_maximum_scale = Vector3.Parse(field[9]);
|
||||
this.m_rate = Vector3.Parse(field[10]);
|
||||
this.m_planted = true;
|
||||
this.m_trees = new List<UUID>();
|
||||
m_name = field[1].Trim();
|
||||
m_frozen = (copsedef[0] == 'F');
|
||||
m_tree_quantity = int.Parse(field[2]);
|
||||
m_treeline_high = float.Parse(field[3], Culture.NumberFormatInfo);
|
||||
m_treeline_low = float.Parse(field[4], Culture.NumberFormatInfo);
|
||||
m_range = double.Parse(field[5], Culture.NumberFormatInfo);
|
||||
m_tree_type = (Tree) Enum.Parse(typeof(Tree),field[6]);
|
||||
m_seed_point = Vector3.Parse(field[7]);
|
||||
m_initial_scale = Vector3.Parse(field[8]);
|
||||
m_maximum_scale = Vector3.Parse(field[9]);
|
||||
m_rate = Vector3.Parse(field[10]);
|
||||
m_planted = true;
|
||||
m_trees = new List<UUID>();
|
||||
}
|
||||
|
||||
public Copse(string name, int quantity, float high, float low, double range, Vector3 point, Tree type, Vector3 scale, Vector3 max_scale, Vector3 rate, List<UUID> trees)
|
||||
{
|
||||
this.m_name = name;
|
||||
this.m_frozen = false;
|
||||
this.m_tree_quantity = quantity;
|
||||
this.m_treeline_high = high;
|
||||
this.m_treeline_low = low;
|
||||
this.m_range = range;
|
||||
this.m_tree_type = type;
|
||||
this.m_seed_point = point;
|
||||
this.m_initial_scale = scale;
|
||||
this.m_maximum_scale = max_scale;
|
||||
this.m_rate = rate;
|
||||
this.m_planted = false;
|
||||
this.m_trees = trees;
|
||||
m_name = name;
|
||||
m_frozen = false;
|
||||
m_tree_quantity = quantity;
|
||||
m_treeline_high = high;
|
||||
m_treeline_low = low;
|
||||
m_range = range;
|
||||
m_tree_type = type;
|
||||
m_seed_point = point;
|
||||
m_initial_scale = scale;
|
||||
m_maximum_scale = max_scale;
|
||||
m_rate = rate;
|
||||
m_planted = false;
|
||||
m_trees = trees;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string frozen = (this.m_frozen ? "F" : "A");
|
||||
string frozen = (m_frozen ? "F" : "A");
|
||||
|
||||
return string.Format("{0}TPM: {1}; {2}; {3:0.0}; {4:0.0}; {5:0.0}; {6}; {7:0.0}; {8:0.0}; {9:0.0}; {10:0.00};",
|
||||
frozen,
|
||||
this.m_name,
|
||||
this.m_tree_quantity,
|
||||
this.m_treeline_high,
|
||||
this.m_treeline_low,
|
||||
this.m_range,
|
||||
this.m_tree_type,
|
||||
this.m_seed_point.ToString(),
|
||||
this.m_initial_scale.ToString(),
|
||||
this.m_maximum_scale.ToString(),
|
||||
this.m_rate.ToString());
|
||||
m_name,
|
||||
m_tree_quantity,
|
||||
m_treeline_high,
|
||||
m_treeline_low,
|
||||
m_range,
|
||||
m_tree_type,
|
||||
m_seed_point.ToString(),
|
||||
m_initial_scale.ToString(),
|
||||
m_maximum_scale.ToString(),
|
||||
m_rate.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private List<Copse> m_copse;
|
||||
|
||||
private List<Copse> m_copses = new List<Copse>();
|
||||
private object mylock;
|
||||
private double m_update_ms = 1000.0; // msec between updates
|
||||
private bool m_active_trees = false;
|
||||
private bool m_enabled = true; // original default
|
||||
private bool m_allowGrow = true; // original default
|
||||
|
||||
Timer CalculateTrees;
|
||||
|
||||
|
@ -174,51 +179,51 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
|
||||
// ini file settings
|
||||
try
|
||||
IConfig moduleConfig = config.Configs["Trees"];
|
||||
if (moduleConfig != null)
|
||||
{
|
||||
m_active_trees = config.Configs["Trees"].GetBoolean("active_trees", m_active_trees);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_log.Debug("[TREES]: ini failure for active_trees - using default");
|
||||
m_enabled = moduleConfig.GetBoolean("enabled", m_enabled);
|
||||
m_active_trees = moduleConfig.GetBoolean("active_trees", m_active_trees);
|
||||
m_allowGrow = moduleConfig.GetBoolean("allowGrow", m_allowGrow);
|
||||
m_update_ms = moduleConfig.GetDouble("update_rate", m_update_ms);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_update_ms = config.Configs["Trees"].GetDouble("update_rate", m_update_ms);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_log.Debug("[TREES]: ini failure for update_rate - using default");
|
||||
}
|
||||
if(!m_enabled)
|
||||
return;
|
||||
|
||||
m_copses = new List<Copse>();
|
||||
mylock = new object();
|
||||
|
||||
InstallCommands();
|
||||
|
||||
m_log.Debug("[TREES]: Initialised tree module");
|
||||
m_log.Debug("[TREES]: Initialised tree populator module");
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
if(!m_enabled)
|
||||
return;
|
||||
m_scene = scene;
|
||||
m_scene.RegisterModuleCommander(m_commander);
|
||||
m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
|
||||
|
||||
m_scene.EventManager.OnPrimsLoaded += EventManager_OnPrimsLoaded;
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
}
|
||||
if(!m_enabled)
|
||||
return;
|
||||
if(m_active_trees && CalculateTrees != null)
|
||||
{
|
||||
CalculateTrees.Dispose();
|
||||
CalculateTrees = null;
|
||||
}
|
||||
m_scene.EventManager.OnPluginConsole -= EventManager_OnPluginConsole;
|
||||
m_scene.EventManager.OnPrimsLoaded -= EventManager_OnPrimsLoaded;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
ReloadCopse();
|
||||
if (m_copse.Count > 0)
|
||||
m_log.Info("[TREES]: Copse load complete");
|
||||
|
||||
if (m_active_trees)
|
||||
activeizeTreeze(true);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
|
@ -240,6 +245,16 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
|
||||
//--------------------------------------------------------------
|
||||
|
||||
private void EventManager_OnPrimsLoaded(Scene s)
|
||||
{
|
||||
ReloadCopse();
|
||||
if (m_copses.Count > 0)
|
||||
m_log.Info("[TREES]: Copses loaded" );
|
||||
|
||||
if (m_active_trees)
|
||||
activeizeTreeze(true);
|
||||
}
|
||||
|
||||
#region ICommandableModule Members
|
||||
|
||||
private void HandleTreeActive(Object[] args)
|
||||
|
@ -267,25 +282,57 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
string copsename = ((string)args[0]).Trim();
|
||||
Boolean freezeState = (Boolean) args[1];
|
||||
|
||||
foreach (Copse cp in m_copse)
|
||||
lock(mylock)
|
||||
{
|
||||
if (cp.m_name == copsename && (!cp.m_frozen && freezeState || cp.m_frozen && !freezeState))
|
||||
foreach (Copse cp in m_copses)
|
||||
{
|
||||
cp.m_frozen = freezeState;
|
||||
foreach (UUID tree in cp.m_trees)
|
||||
{
|
||||
SceneObjectPart sop = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart;
|
||||
sop.Name = (freezeState ? sop.Name.Replace("ATPM", "FTPM") : sop.Name.Replace("FTPM", "ATPM"));
|
||||
sop.ParentGroup.HasGroupChanged = true;
|
||||
}
|
||||
if (cp.m_name != copsename)
|
||||
continue;
|
||||
|
||||
m_log.InfoFormat("[TREES]: Activity for copse {0} is frozen {1}", copsename, freezeState);
|
||||
return;
|
||||
}
|
||||
else if (cp.m_name == copsename && (cp.m_frozen && freezeState || !cp.m_frozen && !freezeState))
|
||||
{
|
||||
m_log.InfoFormat("[TREES]: Copse {0} is already in the requested freeze state", copsename);
|
||||
return;
|
||||
if(!cp.m_frozen && freezeState || cp.m_frozen && !freezeState)
|
||||
{
|
||||
cp.m_frozen = freezeState;
|
||||
List<UUID> losttrees = new List<UUID>();
|
||||
foreach (UUID tree in cp.m_trees)
|
||||
{
|
||||
SceneObjectGroup sog = m_scene.GetSceneObjectGroup(tree);
|
||||
if(sog != null && !sog.IsDeleted)
|
||||
{
|
||||
SceneObjectPart sop = sog.RootPart;
|
||||
string name = sop.Name;
|
||||
if(freezeState)
|
||||
{
|
||||
if(name.StartsWith("FTPM"))
|
||||
continue;
|
||||
if(!name.StartsWith("ATPM"))
|
||||
continue;
|
||||
sop.Name = sop.Name.Replace("ATPM", "FTPM");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(name.StartsWith("ATPM"))
|
||||
continue;
|
||||
if(!name.StartsWith("FTPM"))
|
||||
continue;
|
||||
sop.Name = sop.Name.Replace("FTPM", "ATPM");
|
||||
}
|
||||
sop.ParentGroup.HasGroupChanged = true;
|
||||
sog.ScheduleGroupForFullUpdate();
|
||||
}
|
||||
else
|
||||
losttrees.Add(tree);
|
||||
}
|
||||
foreach (UUID tree in losttrees)
|
||||
cp.m_trees.Remove(tree);
|
||||
|
||||
m_log.InfoFormat("[TREES]: Activity for copse {0} is frozen {1}", copsename, freezeState);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[TREES]: Copse {0} is already in the requested freeze state", copsename);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_log.InfoFormat("[TREES]: Copse {0} was not found - command failed", copsename);
|
||||
|
@ -297,17 +344,21 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
|
||||
m_log.InfoFormat("[TREES]: Loading copse definition....");
|
||||
|
||||
copse = new Copse(((string)args[0]), false);
|
||||
foreach (Copse cp in m_copse)
|
||||
lock(mylock)
|
||||
{
|
||||
if (cp.m_name == copse.m_name)
|
||||
copse = new Copse(((string)args[0]), false);
|
||||
{
|
||||
m_log.InfoFormat("[TREES]: Copse: {0} is already defined - command failed", copse.m_name);
|
||||
return;
|
||||
foreach (Copse cp in m_copses)
|
||||
{
|
||||
if (cp.m_name == copse.m_name)
|
||||
{
|
||||
m_log.InfoFormat("[TREES]: Copse: {0} is already defined - command failed", copse.m_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_copses.Add(copse);
|
||||
}
|
||||
|
||||
m_copse.Add(copse);
|
||||
m_log.InfoFormat("[TREES]: Loaded copse: {0}", copse.ToString());
|
||||
}
|
||||
|
||||
|
@ -318,20 +369,24 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
m_log.InfoFormat("[TREES]: New tree planting for copse {0}", copsename);
|
||||
UUID uuid = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||
|
||||
foreach (Copse copse in m_copse)
|
||||
lock(mylock)
|
||||
{
|
||||
if (copse.m_name == copsename)
|
||||
foreach (Copse copse in m_copses)
|
||||
{
|
||||
if (!copse.m_planted)
|
||||
if (copse.m_name == copsename)
|
||||
{
|
||||
// The first tree for a copse is created here
|
||||
CreateTree(uuid, copse, copse.m_seed_point);
|
||||
copse.m_planted = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[TREES]: Copse {0} has already been planted", copsename);
|
||||
if (!copse.m_planted)
|
||||
{
|
||||
// The first tree for a copse is created here
|
||||
CreateTree(uuid, copse, copse.m_seed_point, true);
|
||||
copse.m_planted = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[TREES]: Copse {0} has already been planted", copsename);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -376,45 +431,49 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
string copsename = ((string)args[0]).Trim();
|
||||
Copse copseIdentity = null;
|
||||
|
||||
foreach (Copse cp in m_copse)
|
||||
lock(mylock)
|
||||
{
|
||||
if (cp.m_name == copsename)
|
||||
foreach (Copse cp in m_copses)
|
||||
{
|
||||
copseIdentity = cp;
|
||||
if (cp.m_name == copsename)
|
||||
{
|
||||
copseIdentity = cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (copseIdentity != null)
|
||||
{
|
||||
foreach (UUID tree in copseIdentity.m_trees)
|
||||
if (copseIdentity != null)
|
||||
{
|
||||
if (m_scene.Entities.ContainsKey(tree))
|
||||
foreach (UUID tree in copseIdentity.m_trees)
|
||||
{
|
||||
SceneObjectPart selectedTree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart;
|
||||
// Delete tree and alert clients (not silent)
|
||||
m_scene.DeleteSceneObject(selectedTree.ParentGroup, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[TREES]: Tree not in scene {0}", tree);
|
||||
if (m_scene.Entities.ContainsKey(tree))
|
||||
{
|
||||
SceneObjectPart selectedTree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart;
|
||||
// Delete tree and alert clients (not silent)
|
||||
m_scene.DeleteSceneObject(selectedTree.ParentGroup, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[TREES]: Tree not in scene {0}", tree);
|
||||
}
|
||||
}
|
||||
copseIdentity.m_trees = null;
|
||||
m_copses.Remove(copseIdentity);
|
||||
m_log.InfoFormat("[TREES]: Copse {0} has been removed", copsename);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[TREES]: Copse {0} was not found - command failed", copsename);
|
||||
}
|
||||
copseIdentity.m_trees = new List<UUID>();
|
||||
m_copse.Remove(copseIdentity);
|
||||
m_log.InfoFormat("[TREES]: Copse {0} has been removed", copsename);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[TREES]: Copse {0} was not found - command failed", copsename);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleTreeStatistics(Object[] args)
|
||||
{
|
||||
m_log.InfoFormat("[TREES]: Activity State: {0}; Update Rate: {1}", m_active_trees, m_update_ms);
|
||||
foreach (Copse cp in m_copse)
|
||||
m_log.InfoFormat("[TREES]: region {0}:", m_scene.Name);
|
||||
m_log.InfoFormat("[TREES]: Activity State: {0}; Update Rate: {1}", m_active_trees, m_update_ms);
|
||||
foreach (Copse cp in m_copses)
|
||||
{
|
||||
m_log.InfoFormat("[TREES]: Copse {0}; {1} trees; frozen {2}", cp.m_name, cp.m_trees.Count, cp.m_frozen);
|
||||
m_log.InfoFormat("[TREES]: Copse {0}; {1} trees; frozen {2}", cp.m_name, cp.m_trees.Count, cp.m_frozen);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -442,7 +501,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
treeRateCommand.AddArgument("updateRate", "The required update rate (minimum 1000.0)", "Double");
|
||||
|
||||
Command treeReloadCommand =
|
||||
new Command("reload", CommandIntentions.COMMAND_HAZARDOUS, HandleTreeReload, "Reload copse definitions from the in-scene trees");
|
||||
new Command("reload", CommandIntentions.COMMAND_HAZARDOUS, HandleTreeReload, "Reload copses from the in-scene trees");
|
||||
|
||||
Command treeRemoveCommand =
|
||||
new Command("remove", CommandIntentions.COMMAND_HAZARDOUS, HandleTreeRemove, "Remove a copse definition and all its in-scene trees");
|
||||
|
@ -499,34 +558,17 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
treeShape.Scale = scale;
|
||||
treeShape.State = (byte)treeType;
|
||||
|
||||
return m_scene.AddNewPrim(uuid, groupID, position, rotation, treeShape);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEntityCreator Members
|
||||
|
||||
protected static readonly PCode[] creationCapabilities = new PCode[] { PCode.NewTree, PCode.Tree };
|
||||
public PCode[] CreationCapabilities { get { return creationCapabilities; } }
|
||||
|
||||
public SceneObjectGroup CreateEntity(
|
||||
UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
|
||||
{
|
||||
if (Array.IndexOf(creationCapabilities, (PCode)shape.PCode) < 0)
|
||||
{
|
||||
m_log.DebugFormat("[VEGETATION]: PCode {0} not handled by {1}", shape.PCode, Name);
|
||||
return null;
|
||||
}
|
||||
|
||||
SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
|
||||
SceneObjectPart rootPart = sceneObject.GetPart(sceneObject.UUID);
|
||||
SceneObjectGroup sog = new SceneObjectGroup(uuid, position, rotation, treeShape);
|
||||
SceneObjectPart rootPart = sog.RootPart;
|
||||
|
||||
rootPart.AddFlag(PrimFlags.Phantom);
|
||||
|
||||
sceneObject.SetGroup(groupID, null);
|
||||
m_scene.AddNewSceneObject(sceneObject, true);
|
||||
sceneObject.InvalidateEffectivePerms();
|
||||
return sceneObject;
|
||||
sog.SetGroup(groupID, null);
|
||||
m_scene.AddNewSceneObject(sog, true, false);
|
||||
sog.IsSelected = false;
|
||||
rootPart.IsSelected = false;
|
||||
sog.InvalidateEffectivePerms();
|
||||
return sog;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -569,26 +611,27 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
|
||||
private void ReloadCopse()
|
||||
{
|
||||
m_copse = new List<Copse>();
|
||||
m_copses = new List<Copse>();
|
||||
|
||||
EntityBase[] objs = m_scene.GetEntities();
|
||||
foreach (EntityBase obj in objs)
|
||||
List<SceneObjectGroup> grps = m_scene.GetSceneObjectGroups();
|
||||
foreach (SceneObjectGroup grp in grps)
|
||||
{
|
||||
if (obj is SceneObjectGroup)
|
||||
if(grp.RootPart.Shape.PCode != (byte)PCode.NewTree && grp.RootPart.Shape.PCode != (byte)PCode.Tree)
|
||||
continue;
|
||||
|
||||
if (grp.Name.Length > 5 && (grp.Name.Substring(0, 5) == "ATPM:" || grp.Name.Substring(0, 5) == "FTPM:"))
|
||||
{
|
||||
SceneObjectGroup grp = (SceneObjectGroup)obj;
|
||||
|
||||
if (grp.Name.Length > 5 && (grp.Name.Substring(0, 5) == "ATPM:" || grp.Name.Substring(0, 5) == "FTPM:"))
|
||||
// Create a new copse definition or add uuid to an existing definition
|
||||
try
|
||||
{
|
||||
// Create a new copse definition or add uuid to an existing definition
|
||||
try
|
||||
{
|
||||
Boolean copsefound = false;
|
||||
Copse copse = new Copse(grp.Name);
|
||||
Boolean copsefound = false;
|
||||
Copse grpcopse = new Copse(grp.Name);
|
||||
|
||||
foreach (Copse cp in m_copse)
|
||||
lock(mylock)
|
||||
{
|
||||
foreach (Copse cp in m_copses)
|
||||
{
|
||||
if (cp.m_name == copse.m_name)
|
||||
if (cp.m_name == grpcopse.m_name)
|
||||
{
|
||||
copsefound = true;
|
||||
cp.m_trees.Add(grp.UUID);
|
||||
|
@ -598,15 +641,15 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
|
||||
if (!copsefound)
|
||||
{
|
||||
m_log.InfoFormat("[TREES]: Found copse {0}", grp.Name);
|
||||
m_copse.Add(copse);
|
||||
copse.m_trees.Add(grp.UUID);
|
||||
m_log.InfoFormat("[TREES]: adding copse {0}", grpcopse.m_name);
|
||||
grpcopse.m_trees.Add(grp.UUID);
|
||||
m_copses.Add(grpcopse);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_log.InfoFormat("[TREES]: Ill formed copse definition {0} - ignoring", grp.Name);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_log.InfoFormat("[TREES]: Ill formed copse definition {0} - ignoring", grp.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -617,8 +660,10 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
{
|
||||
if (activeYN)
|
||||
{
|
||||
CalculateTrees = new Timer(m_update_ms);
|
||||
if(CalculateTrees == null)
|
||||
CalculateTrees = new Timer(m_update_ms);
|
||||
CalculateTrees.Elapsed += CalculateTrees_Elapsed;
|
||||
CalculateTrees.AutoReset = false;
|
||||
CalculateTrees.Start();
|
||||
}
|
||||
else
|
||||
|
@ -629,154 +674,251 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
|
|||
|
||||
private void growTrees()
|
||||
{
|
||||
foreach (Copse copse in m_copse)
|
||||
{
|
||||
if (!copse.m_frozen)
|
||||
{
|
||||
foreach (UUID tree in copse.m_trees)
|
||||
{
|
||||
if (m_scene.Entities.ContainsKey(tree))
|
||||
{
|
||||
SceneObjectPart s_tree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart;
|
||||
if(!m_allowGrow)
|
||||
return;
|
||||
|
||||
if (s_tree.Scale.X < copse.m_maximum_scale.X && s_tree.Scale.Y < copse.m_maximum_scale.Y && s_tree.Scale.Z < copse.m_maximum_scale.Z)
|
||||
{
|
||||
s_tree.Scale += copse.m_rate;
|
||||
s_tree.ParentGroup.HasGroupChanged = true;
|
||||
s_tree.ScheduleFullUpdate();
|
||||
}
|
||||
}
|
||||
else
|
||||
foreach (Copse copse in m_copses)
|
||||
{
|
||||
if (copse.m_frozen)
|
||||
continue;
|
||||
|
||||
if(copse.m_trees.Count == 0)
|
||||
continue;
|
||||
|
||||
float maxscale = copse.m_maximum_scale.Z;
|
||||
float ratescale = 1.0f;
|
||||
List<UUID> losttrees = new List<UUID>();
|
||||
foreach (UUID tree in copse.m_trees)
|
||||
{
|
||||
SceneObjectGroup sog = m_scene.GetSceneObjectGroup(tree);
|
||||
|
||||
if (sog != null && !sog.IsDeleted)
|
||||
{
|
||||
SceneObjectPart s_tree = sog.RootPart;
|
||||
if (s_tree.Scale.Z < maxscale)
|
||||
{
|
||||
m_log.DebugFormat("[TREES]: Tree not in scene {0}", tree);
|
||||
ratescale = (float)Util.RandomClass.NextDouble();
|
||||
if(ratescale < 0.2f)
|
||||
ratescale = 0.2f;
|
||||
s_tree.Scale += copse.m_rate * ratescale;
|
||||
sog.HasGroupChanged = true;
|
||||
s_tree.ScheduleFullUpdate();
|
||||
}
|
||||
}
|
||||
else
|
||||
losttrees.Add(tree);
|
||||
}
|
||||
|
||||
foreach (UUID tree in losttrees)
|
||||
copse.m_trees.Remove(tree);
|
||||
}
|
||||
}
|
||||
|
||||
private void seedTrees()
|
||||
{
|
||||
foreach (Copse copse in m_copse)
|
||||
foreach (Copse copse in m_copses)
|
||||
{
|
||||
if (!copse.m_frozen)
|
||||
{
|
||||
foreach (UUID tree in copse.m_trees)
|
||||
{
|
||||
if (m_scene.Entities.ContainsKey(tree))
|
||||
{
|
||||
SceneObjectPart s_tree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart;
|
||||
if (copse.m_frozen)
|
||||
continue;
|
||||
|
||||
if (copse.m_trees.Count < copse.m_tree_quantity)
|
||||
{
|
||||
// Tree has grown enough to seed if it has grown by at least 25% of seeded to full grown height
|
||||
if (s_tree.Scale.Z > copse.m_initial_scale.Z + (copse.m_maximum_scale.Z - copse.m_initial_scale.Z) / 4.0)
|
||||
{
|
||||
if (Util.RandomClass.NextDouble() > 0.75)
|
||||
{
|
||||
SpawnChild(copse, s_tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[TREES]: Tree not in scene {0}", tree);
|
||||
}
|
||||
if(copse.m_trees.Count == 0)
|
||||
return;
|
||||
|
||||
bool low = copse.m_trees.Count < (int)(copse.m_tree_quantity * 0.8f);
|
||||
|
||||
if (!low && Util.RandomClass.NextDouble() < 0.75)
|
||||
return;
|
||||
|
||||
int maxbirths = (int)(copse.m_tree_quantity) - copse.m_trees.Count;
|
||||
if(maxbirths <= 1)
|
||||
return;
|
||||
|
||||
if(maxbirths > 20)
|
||||
maxbirths = 20;
|
||||
|
||||
float minscale = 0;
|
||||
if(!low && m_allowGrow)
|
||||
minscale = copse.m_maximum_scale.Z * 0.75f;;
|
||||
|
||||
int i = 0;
|
||||
UUID[] current = copse.m_trees.ToArray();
|
||||
while(--maxbirths > 0)
|
||||
{
|
||||
if(current.Length > 1)
|
||||
i = Util.RandomClass.Next(current.Length -1);
|
||||
|
||||
UUID tree = current[i];
|
||||
SceneObjectGroup sog = m_scene.GetSceneObjectGroup(tree);
|
||||
|
||||
if (sog != null && !sog.IsDeleted)
|
||||
{
|
||||
SceneObjectPart s_tree = sog.RootPart;
|
||||
|
||||
// Tree has grown enough to seed if it has grown by at least 25% of seeded to full grown height
|
||||
if (s_tree.Scale.Z > minscale)
|
||||
SpawnChild(copse, s_tree, true);
|
||||
}
|
||||
}
|
||||
else if(copse.m_trees.Contains(tree))
|
||||
copse.m_trees.Remove(tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void killTrees()
|
||||
{
|
||||
foreach (Copse copse in m_copse)
|
||||
foreach (Copse copse in m_copses)
|
||||
{
|
||||
if (!copse.m_frozen && copse.m_trees.Count >= copse.m_tree_quantity)
|
||||
if (copse.m_frozen)
|
||||
continue;
|
||||
|
||||
if (Util.RandomClass.NextDouble() < 0.25)
|
||||
return;
|
||||
|
||||
int maxbdeaths = copse.m_trees.Count - (int)(copse.m_tree_quantity * .98f) ;
|
||||
if(maxbdeaths < 1)
|
||||
return;
|
||||
|
||||
float odds;
|
||||
float scale = 1.0f / copse.m_maximum_scale.Z;
|
||||
|
||||
int ntries = maxbdeaths * 4;
|
||||
while(ntries-- > 0 )
|
||||
{
|
||||
foreach (UUID tree in copse.m_trees)
|
||||
int next = 0;
|
||||
if (copse.m_trees.Count > 1)
|
||||
next = Util.RandomClass.Next(copse.m_trees.Count - 1);
|
||||
UUID tree = copse.m_trees[next];
|
||||
SceneObjectGroup sog = m_scene.GetSceneObjectGroup(tree);
|
||||
if (sog != null && !sog.IsDeleted)
|
||||
{
|
||||
double killLikelyhood = 0.0;
|
||||
|
||||
if (m_scene.Entities.ContainsKey(tree))
|
||||
if(m_allowGrow)
|
||||
{
|
||||
SceneObjectPart selectedTree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart;
|
||||
double selectedTreeScale = Math.Sqrt(Math.Pow(selectedTree.Scale.X, 2) +
|
||||
Math.Pow(selectedTree.Scale.Y, 2) +
|
||||
Math.Pow(selectedTree.Scale.Z, 2));
|
||||
|
||||
foreach (UUID picktree in copse.m_trees)
|
||||
{
|
||||
if (picktree != tree)
|
||||
{
|
||||
SceneObjectPart pickedTree = ((SceneObjectGroup)m_scene.Entities[picktree]).RootPart;
|
||||
|
||||
double pickedTreeScale = Math.Sqrt(Math.Pow(pickedTree.Scale.X, 2) +
|
||||
Math.Pow(pickedTree.Scale.Y, 2) +
|
||||
Math.Pow(pickedTree.Scale.Z, 2));
|
||||
|
||||
double pickedTreeDistance = Vector3.Distance(pickedTree.AbsolutePosition, selectedTree.AbsolutePosition);
|
||||
|
||||
killLikelyhood += (selectedTreeScale / (pickedTreeScale * pickedTreeDistance)) * 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
if (Util.RandomClass.NextDouble() < killLikelyhood)
|
||||
{
|
||||
// Delete tree and alert clients (not silent)
|
||||
m_scene.DeleteSceneObject(selectedTree.ParentGroup, false);
|
||||
copse.m_trees.Remove(selectedTree.ParentGroup.UUID);
|
||||
break;
|
||||
}
|
||||
odds = sog.RootPart.Scale.Z * scale;
|
||||
odds = odds * odds * odds;
|
||||
odds *= (float)Util.RandomClass.NextDouble();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[TREES]: Tree not in scene {0}", tree);
|
||||
odds = (float)Util.RandomClass.NextDouble();
|
||||
odds = odds * odds * odds;
|
||||
}
|
||||
|
||||
if(odds > 0.9f)
|
||||
{
|
||||
m_scene.DeleteSceneObject(sog, false);
|
||||
if(maxbdeaths <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
copse.m_trees.Remove(tree);
|
||||
if(copse.m_trees.Count - (int)(copse.m_tree_quantity * .98f) <= 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SpawnChild(Copse copse, SceneObjectPart s_tree)
|
||||
private void SpawnChild(Copse copse, SceneObjectPart s_tree, bool low)
|
||||
{
|
||||
Vector3 position = new Vector3();
|
||||
|
||||
double randX = ((Util.RandomClass.NextDouble() * 2.0) - 1.0) * (s_tree.Scale.X * 3);
|
||||
double randY = ((Util.RandomClass.NextDouble() * 2.0) - 1.0) * (s_tree.Scale.X * 3);
|
||||
|
||||
|
||||
float randX = copse.m_maximum_scale.X * 1.25f;
|
||||
float randY = copse.m_maximum_scale.Y * 1.25f;
|
||||
|
||||
float r = (float)Util.RandomClass.NextDouble();
|
||||
randX *= 2.0f * r - 1.0f;
|
||||
position.X = s_tree.AbsolutePosition.X + (float)randX;
|
||||
|
||||
r = (float)Util.RandomClass.NextDouble();
|
||||
randY *= 2.0f * r - 1.0f;
|
||||
position.Y = s_tree.AbsolutePosition.Y + (float)randY;
|
||||
|
||||
if (position.X <= (m_scene.RegionInfo.RegionSizeX - 1) && position.X >= 0 &&
|
||||
position.Y <= (m_scene.RegionInfo.RegionSizeY - 1) && position.Y >= 0 &&
|
||||
Util.GetDistanceTo(position, copse.m_seed_point) <= copse.m_range)
|
||||
{
|
||||
UUID uuid = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||
if (position.X > (m_scene.RegionInfo.RegionSizeX - 1) || position.X <= 0 ||
|
||||
position.Y > (m_scene.RegionInfo.RegionSizeY - 1) || position.Y <= 0)
|
||||
return;
|
||||
|
||||
CreateTree(uuid, copse, position);
|
||||
}
|
||||
randX = position.X - copse.m_seed_point.X;
|
||||
randX *= randX;
|
||||
randY = position.Y - copse.m_seed_point.Y;
|
||||
randY *= randY;
|
||||
randX += randY;
|
||||
|
||||
if(randX > copse.m_range * copse.m_range)
|
||||
return;
|
||||
|
||||
UUID uuid = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||
CreateTree(uuid, copse, position, low);
|
||||
}
|
||||
|
||||
private void CreateTree(UUID uuid, Copse copse, Vector3 position)
|
||||
private void CreateTree(UUID uuid, Copse copse, Vector3 position, bool randomScale)
|
||||
{
|
||||
|
||||
position.Z = (float)m_scene.Heightmap[(int)position.X, (int)position.Y];
|
||||
if (position.Z >= copse.m_treeline_low && position.Z <= copse.m_treeline_high)
|
||||
{
|
||||
SceneObjectGroup tree = AddTree(uuid, UUID.Zero, copse.m_initial_scale, Quaternion.Identity, position, copse.m_tree_type, false);
|
||||
if (position.Z < copse.m_treeline_low || position.Z > copse.m_treeline_high)
|
||||
return;
|
||||
|
||||
tree.Name = copse.ToString();
|
||||
copse.m_trees.Add(tree.UUID);
|
||||
tree.SendGroupFullUpdate();
|
||||
Vector3 scale = copse.m_initial_scale;
|
||||
if(randomScale)
|
||||
{
|
||||
try
|
||||
{
|
||||
float t;
|
||||
float r = (float)Util.RandomClass.NextDouble();
|
||||
r *= (float)Util.RandomClass.NextDouble();
|
||||
r *= (float)Util.RandomClass.NextDouble();
|
||||
|
||||
t = copse.m_maximum_scale.X / copse.m_initial_scale.X;
|
||||
if(t < 1.0)
|
||||
t = 1 / t;
|
||||
t = t * r + 1.0f;
|
||||
scale.X *= t;
|
||||
|
||||
t = copse.m_maximum_scale.Y / copse.m_initial_scale.Y;
|
||||
if(t < 1.0)
|
||||
t = 1 / t;
|
||||
t = t * r + 1.0f;
|
||||
scale.Y *= t;
|
||||
|
||||
t = copse.m_maximum_scale.Z / copse.m_initial_scale.Z;
|
||||
if(t < 1.0)
|
||||
t = 1 / t;
|
||||
t = t * r + 1.0f;
|
||||
scale.Z *= t;
|
||||
}
|
||||
catch
|
||||
{
|
||||
scale = copse.m_initial_scale;
|
||||
}
|
||||
}
|
||||
|
||||
SceneObjectGroup tree = AddTree(uuid, UUID.Zero, scale, Quaternion.Identity, position, copse.m_tree_type, false);
|
||||
tree.Name = copse.ToString();
|
||||
copse.m_trees.Add(tree.UUID);
|
||||
tree.RootPart.ScheduleFullUpdate();
|
||||
}
|
||||
|
||||
private void CalculateTrees_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
growTrees();
|
||||
seedTrees();
|
||||
killTrees();
|
||||
if(!m_scene.IsRunning)
|
||||
return;
|
||||
|
||||
if(Monitor.TryEnter(mylock))
|
||||
{
|
||||
try
|
||||
{
|
||||
if(m_scene.LoginsEnabled )
|
||||
{
|
||||
growTrees();
|
||||
seedTrees();
|
||||
killTrees();
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
if(CalculateTrees != null)
|
||||
CalculateTrees.Start();
|
||||
Monitor.Exit(mylock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
|
||||
public float walkDivisor = 1.3f;
|
||||
public float runDivisor = 0.8f;
|
||||
private bool flying = false;
|
||||
private bool m_flying = false;
|
||||
private bool m_iscolliding = false;
|
||||
private bool m_iscollidingGround = false;
|
||||
private bool m_iscollidingObj = false;
|
||||
|
@ -298,10 +298,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
|
||||
public override bool Flying
|
||||
{
|
||||
get { return flying; }
|
||||
get { return m_flying; }
|
||||
set
|
||||
{
|
||||
flying = value;
|
||||
m_flying = value;
|
||||
// m_log.DebugFormat("[PHYSICS]: Set OdeCharacter Flying to {0}", flying);
|
||||
}
|
||||
}
|
||||
|
@ -899,9 +899,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
y = tx * sin + y * cos;
|
||||
}
|
||||
|
||||
public bool Collide(IntPtr me, IntPtr other, bool reverse, ref d.ContactGeom contact,
|
||||
public bool Collide(IntPtr me, IntPtr other, bool reverse, ref d.ContactGeom contact,
|
||||
ref d.ContactGeom altContact , ref bool useAltcontact, ref bool feetcollision)
|
||||
{
|
||||
{
|
||||
feetcollision = false;
|
||||
useAltcontact = false;
|
||||
|
||||
|
@ -943,12 +943,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
}
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
d.AABB aabb;
|
||||
d.GeomGetAABB(other,out aabb);
|
||||
float othertop = aabb.MaxZ - _position.Z;
|
||||
*/
|
||||
// if (offset.Z > 0 || othertop > -feetOff || contact.normal.Z > 0.35f)
|
||||
|
||||
if (gtype == d.GeomClassID.SphereClass && d.GeomGetBody(other) != IntPtr.Zero)
|
||||
{
|
||||
if(d.GeomSphereGetRadius(other) < 0.5)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (offset.Z > 0 || contact.normal.Z > 0.35f)
|
||||
{
|
||||
if (offset.Z <= 0)
|
||||
|
@ -965,6 +966,18 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
return true;
|
||||
}
|
||||
|
||||
if(m_flying)
|
||||
return true;
|
||||
|
||||
feetcollision = true;
|
||||
if (h < boneOff)
|
||||
{
|
||||
m_collideNormal.X = contact.normal.X;
|
||||
m_collideNormal.Y = contact.normal.Y;
|
||||
m_collideNormal.Z = contact.normal.Z;
|
||||
IsColliding = true;
|
||||
}
|
||||
|
||||
altContact = contact;
|
||||
useAltcontact = true;
|
||||
|
||||
|
@ -972,8 +985,21 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
|
||||
offset.Normalize();
|
||||
|
||||
if (contact.depth > 0.1f)
|
||||
contact.depth = 0.1f;
|
||||
float tdp = contact.depth;
|
||||
float t = offset.X;
|
||||
t = Math.Abs(t);
|
||||
if(t > 1e-6)
|
||||
{
|
||||
tdp /= t;
|
||||
tdp *= contact.normal.X;
|
||||
}
|
||||
else
|
||||
tdp *= 10;
|
||||
|
||||
if (tdp > 0.25f)
|
||||
tdp = 0.25f;
|
||||
|
||||
altContact.depth = tdp;
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
|
@ -987,15 +1013,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
altContact.normal.Y = -offset.Y;
|
||||
altContact.normal.Z = -offset.Z;
|
||||
}
|
||||
|
||||
feetcollision = true;
|
||||
if (h < boneOff)
|
||||
{
|
||||
m_collideNormal.X = contact.normal.X;
|
||||
m_collideNormal.Y = contact.normal.Y;
|
||||
m_collideNormal.Z = contact.normal.Z;
|
||||
IsColliding = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1098,7 +1115,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
|
||||
float ftmp;
|
||||
|
||||
if (flying)
|
||||
if (m_flying)
|
||||
{
|
||||
ftmp = timeStep;
|
||||
posch.X += vel.X * ftmp;
|
||||
|
@ -1122,7 +1139,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
|
||||
vec.Z = depth * PID_P * 50;
|
||||
|
||||
if (!flying)
|
||||
if (!m_flying)
|
||||
{
|
||||
vec.Z += -vel.Z * PID_D;
|
||||
if(n.Z < 0.4f)
|
||||
|
@ -1259,7 +1276,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
|
||||
// movement relative to surface if moving on it
|
||||
// dont disturbe vertical movement, ie jumps
|
||||
if (m_iscolliding && !flying && ctz.Z == 0 && m_collideNormal.Z > 0.2f && m_collideNormal.Z < 0.94f)
|
||||
if (m_iscolliding && !m_flying && ctz.Z == 0 && m_collideNormal.Z > 0.2f && m_collideNormal.Z < 0.94f)
|
||||
{
|
||||
float p = ctz.X * m_collideNormal.X + ctz.Y * m_collideNormal.Y;
|
||||
ctz.X *= (float)Math.Sqrt(1 - m_collideNormal.X * m_collideNormal.X);
|
||||
|
@ -1276,7 +1293,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
{
|
||||
|
||||
// if velocity is zero, use position control; otherwise, velocity control
|
||||
if (tviszero && m_iscolliding && !flying)
|
||||
if (tviszero && m_iscolliding && !m_flying)
|
||||
{
|
||||
// keep track of where we stopped. No more slippin' & slidin'
|
||||
if (!_zeroFlag)
|
||||
|
@ -1313,7 +1330,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
|
||||
if (m_iscolliding)
|
||||
{
|
||||
if (!flying)
|
||||
if (!m_flying)
|
||||
{
|
||||
// we are on a surface
|
||||
if (ctz.Z > 0f)
|
||||
|
@ -1361,7 +1378,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
}
|
||||
else // ie not colliding
|
||||
{
|
||||
if (flying || hoverPIDActive) //(!m_iscolliding && flying)
|
||||
if (m_flying || hoverPIDActive) //(!m_iscolliding && flying)
|
||||
{
|
||||
// we're in mid air suspended
|
||||
vec.X += (ctz.X - vel.X) * (PID_D);
|
||||
|
@ -1397,13 +1414,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
breakfactor = m_mass;
|
||||
vec.X -= breakfactor * vel.X;
|
||||
vec.Y -= breakfactor * vel.Y;
|
||||
if (flying)
|
||||
if (m_flying)
|
||||
vec.Z -= 0.5f * breakfactor * vel.Z;
|
||||
else
|
||||
vec.Z -= .16f* m_mass * vel.Z;
|
||||
}
|
||||
|
||||
if (flying || hoverPIDActive)
|
||||
if (m_flying || hoverPIDActive)
|
||||
{
|
||||
vec.Z -= m_parent_scene.gravityz * m_mass;
|
||||
|
||||
|
|
|
@ -345,6 +345,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
|
||||
&& !rootPrim.m_isSelected && !rootPrim.m_disabled)
|
||||
d.BodyEnable(rootPrim.Body);
|
||||
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
if (pValue < m_timestep) pValue = m_timestep;
|
||||
|
|
|
@ -1043,7 +1043,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
d.BodySetLinearVel(Body, 0, 0, 0); // stop it
|
||||
d.BodySetAngularVel(Body, 0, 0, 0);
|
||||
}
|
||||
d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
|
||||
if(prim_geom != IntPtr.Zero)
|
||||
d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
|
||||
disableBodySoft(); // stop collisions
|
||||
UnSubscribeEvents();
|
||||
}
|
||||
|
@ -1240,7 +1241,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
SentEmptyCollisionsEvent = true;
|
||||
// _parent_scene.RemoveCollisionEventReporting(this);
|
||||
}
|
||||
else if(Body == IntPtr.Zero || d.BodyIsEnabled(Body))
|
||||
else if(Body == IntPtr.Zero || (d.BodyIsEnabled(Body) && m_bodydisablecontrol >= 0 ))
|
||||
{
|
||||
SentEmptyCollisionsEvent = false;
|
||||
CollisionEventsThisFrame.Clear();
|
||||
|
@ -1847,8 +1848,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
ApplyCollisionCatFlags();
|
||||
|
||||
_zeroFlag = true;
|
||||
d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
|
||||
d.BodyEnable(Body);
|
||||
|
||||
}
|
||||
}
|
||||
resetCollisionAccounting();
|
||||
|
@ -2900,6 +2901,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
if (Body != IntPtr.Zero && !m_disabled)
|
||||
{
|
||||
_zeroFlag = true;
|
||||
d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
}
|
||||
|
@ -2933,6 +2935,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
if (!d.BodyIsEnabled(Body))
|
||||
{
|
||||
_zeroFlag = true;
|
||||
d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
}
|
||||
|
@ -2947,6 +2950,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
{
|
||||
_zeroFlag = true;
|
||||
d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
}
|
||||
|
@ -3012,6 +3016,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
{
|
||||
_zeroFlag = true;
|
||||
d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
}
|
||||
|
@ -3070,6 +3075,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
{
|
||||
_zeroFlag = true;
|
||||
d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
}
|
||||
|
@ -3312,8 +3318,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
if (m_disabled)
|
||||
enableBodySoft();
|
||||
else if (!d.BodyIsEnabled(Body))
|
||||
{
|
||||
d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
|
||||
d.BodyEnable(Body);
|
||||
|
||||
}
|
||||
}
|
||||
m_torque = newtorque;
|
||||
}
|
||||
|
@ -3323,7 +3331,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
{
|
||||
m_force = force;
|
||||
if (!m_isSelected && !m_outbounds && Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
{
|
||||
d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
}
|
||||
|
||||
private void changeAddForce(Vector3 theforce)
|
||||
|
@ -3339,7 +3350,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
if (m_disabled)
|
||||
enableBodySoft();
|
||||
else if (!d.BodyIsEnabled(Body))
|
||||
{
|
||||
d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_collisionscore = 0;
|
||||
|
@ -3359,7 +3373,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
if (m_disabled)
|
||||
enableBodySoft();
|
||||
else if (!d.BodyIsEnabled(Body))
|
||||
{
|
||||
d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_collisionscore = 0;
|
||||
|
@ -3382,7 +3399,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
if (m_disabled)
|
||||
enableBodySoft();
|
||||
else if (!d.BodyIsEnabled(Body))
|
||||
{
|
||||
d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
d.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z);
|
||||
}
|
||||
//resetCollisionAccounting();
|
||||
|
@ -3406,7 +3426,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
if (m_disabled)
|
||||
enableBodySoft();
|
||||
else if (!d.BodyIsEnabled(Body))
|
||||
{
|
||||
d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames);
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
d.BodySetAngularVel(Body, newAngVel.X, newAngVel.Y, newAngVel.Z);
|
||||
}
|
||||
//resetCollisionAccounting();
|
||||
|
@ -3571,12 +3594,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
d.BodySetAngularVel(Body,0f,0f,0f);
|
||||
d.BodySetLinearVel(Body,0f,0f,0f);
|
||||
_zeroFlag = true;
|
||||
d.BodySetAutoDisableSteps(Body, 1);
|
||||
d.BodyEnable(Body);
|
||||
m_bodydisablecontrol = -4;
|
||||
m_bodydisablecontrol = -3;
|
||||
}
|
||||
|
||||
if(m_bodydisablecontrol < 0)
|
||||
m_bodydisablecontrol ++;
|
||||
m_bodydisablecontrol++;
|
||||
|
||||
d.Vector3 lpos = d.GeomGetPosition(prim_geom); // root position that is seem by rest of simulator
|
||||
|
||||
|
@ -3741,13 +3765,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
|
||||
public void UpdatePositionAndVelocity(int frame)
|
||||
{
|
||||
if (_parent == null && !m_disabled && !m_building && !m_outbounds && Body != IntPtr.Zero)
|
||||
if (_parent == null && !m_isSelected && !m_disabled && !m_building && !m_outbounds && Body != IntPtr.Zero)
|
||||
{
|
||||
bool bodyenabled = d.BodyIsEnabled(Body);
|
||||
|
||||
if(m_bodydisablecontrol < 0)
|
||||
return;
|
||||
|
||||
bool bodyenabled = d.BodyIsEnabled(Body);
|
||||
if (bodyenabled || !_zeroFlag)
|
||||
{
|
||||
bool lastZeroFlag = _zeroFlag;
|
||||
|
@ -3891,7 +3914,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
// disable interpolators
|
||||
_velocity = Vector3.Zero;
|
||||
m_acceleration = Vector3.Zero;
|
||||
m_rotationalVelocity = Vector3.Zero;
|
||||
m_rotationalVelocity = Vector3.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -203,8 +203,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
private float metersInSpace = 25.6f;
|
||||
private float m_timeDilation = 1.0f;
|
||||
|
||||
private DateTime m_lastframe;
|
||||
private DateTime m_lastMeshExpire;
|
||||
private double m_lastframe;
|
||||
private double m_lastMeshExpire;
|
||||
|
||||
public float gravityx = 0f;
|
||||
public float gravityy = 0f;
|
||||
|
@ -481,7 +481,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision);
|
||||
|
||||
geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity);
|
||||
bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable);
|
||||
// bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable);
|
||||
|
||||
physics_logging = physicsconfig.GetBoolean("physics_logging", false);
|
||||
physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0);
|
||||
|
@ -629,8 +629,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
staticPrimspaceOffRegion[i] = newspace;
|
||||
}
|
||||
|
||||
m_lastframe = DateTime.UtcNow;
|
||||
m_lastframe = Util.GetTimeStamp();
|
||||
m_lastMeshExpire = m_lastframe;
|
||||
step_time = -1;
|
||||
}
|
||||
|
||||
internal void waitForSpaceUnlock(IntPtr space)
|
||||
|
@ -952,8 +953,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
SharedTmpcontact.surface.bounce = bounce;
|
||||
|
||||
d.ContactGeom altContact = new d.ContactGeom();
|
||||
bool useAltcontact = false;
|
||||
bool noskip = true;
|
||||
bool useAltcontact;
|
||||
bool noskip;
|
||||
|
||||
if(dop1ava || dop2ava)
|
||||
smoothMesh = false;
|
||||
|
@ -1000,7 +1001,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
Joint = CreateContacJoint(ref altContact,smoothMesh);
|
||||
else
|
||||
Joint = CreateContacJoint(ref curContact,smoothMesh);
|
||||
|
||||
if (Joint == IntPtr.Zero)
|
||||
break;
|
||||
|
||||
|
@ -1626,6 +1626,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
}
|
||||
m_log.InfoFormat("[ubOde] {0} prim actors loaded",_prims.Count);
|
||||
}
|
||||
m_lastframe = Util.GetTimeStamp() + 0.5;
|
||||
step_time = -0.5f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1639,13 +1641,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
/// <returns></returns>
|
||||
public override float Simulate(float reqTimeStep)
|
||||
{
|
||||
DateTime now = DateTime.UtcNow;
|
||||
TimeSpan timedif = now - m_lastframe;
|
||||
float timeStep = (float)timedif.TotalSeconds;
|
||||
double now = Util.GetTimeStamp();
|
||||
double timeStep = now - m_lastframe;
|
||||
m_lastframe = now;
|
||||
|
||||
// acumulate time so we can reduce error
|
||||
step_time += timeStep;
|
||||
step_time += (float)timeStep;
|
||||
|
||||
if (step_time < HalfOdeStep)
|
||||
return 0;
|
||||
|
@ -1854,14 +1855,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
}
|
||||
}
|
||||
|
||||
timedif = now - m_lastMeshExpire;
|
||||
|
||||
if (timedif.Seconds > 10)
|
||||
{
|
||||
mesher.ExpireReleaseMeshs();
|
||||
m_lastMeshExpire = now;
|
||||
}
|
||||
|
||||
// information block for in debug breakpoint only
|
||||
/*
|
||||
int ntopactivegeoms = d.SpaceGetNumGeoms(ActiveSpace);
|
||||
|
@ -1941,7 +1934,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
// if we lag too much skip frames
|
||||
m_timeDilation = 0.0f;
|
||||
step_time = 0;
|
||||
m_lastframe = DateTime.UtcNow; // skip also the time lost
|
||||
m_lastframe = Util.GetTimeStamp(); // skip also the time lost
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1949,6 +1942,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde
|
|||
if (m_timeDilation > 1)
|
||||
m_timeDilation = 1;
|
||||
}
|
||||
|
||||
if (m_timeDilation == 1 && now - m_lastMeshExpire > 30)
|
||||
{
|
||||
mesher.ExpireReleaseMeshs();
|
||||
m_lastMeshExpire = now;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return fps;
|
||||
|
|
|
@ -3534,32 +3534,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
public void doObjectRez(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param, bool atRoot)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
|
||||
return;
|
||||
|
||||
float dist = (float)llVecDist(llGetPos(), pos);
|
||||
|
||||
if (dist > m_ScriptDistanceFactor * 10.0f)
|
||||
return;
|
||||
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory);
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
Error("llRez(AtRoot/Object)", "Can't find object '" + inventory + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.InvType != (int)InventoryType.Object)
|
||||
{
|
||||
Error("llRez(AtRoot/Object)", "Can't create requested object; object is missing from database");
|
||||
return;
|
||||
}
|
||||
|
||||
Util.FireAndForget(x =>
|
||||
{
|
||||
if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
|
||||
return;
|
||||
|
||||
float dist = (float)llVecDist(llGetPos(), pos);
|
||||
|
||||
if (dist > m_ScriptDistanceFactor * 10.0f)
|
||||
return;
|
||||
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory);
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
Error("llRez(AtRoot/Object)", "Can't find object '" + inventory + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.InvType != (int)InventoryType.Object)
|
||||
{
|
||||
Error("llRez(AtRoot/Object)", "Can't create requested object; object is missing from database");
|
||||
return;
|
||||
}
|
||||
|
||||
List<SceneObjectGroup> new_groups = World.RezObject(m_host, item, pos, rot, vel, param, atRoot);
|
||||
Quaternion wrot = rot;
|
||||
wrot.Normalize();
|
||||
List<SceneObjectGroup> new_groups = World.RezObject(m_host, item, pos, wrot, vel, param, atRoot);
|
||||
|
||||
// If either of these are null, then there was an unknown error.
|
||||
if (new_groups == null)
|
||||
|
@ -3596,9 +3598,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
}
|
||||
}
|
||||
}
|
||||
// Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
|
||||
}
|
||||
|
||||
}
|
||||
}, null, "LSL_Api.doObjectRez");
|
||||
|
||||
//ScriptSleep((int)((groupmass * velmag) / 10));
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -123,6 +123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
|||
string osSetDynamicTextureURLBlendFace(string dynamicID, string contentType, string url, string extraParams,
|
||||
bool blend, int disp, int timer, int alpha, int face);
|
||||
string osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams, int timer);
|
||||
string osSetDynamicTextureDataFace(string dynamicID, string contentType, string data, string extraParams, int timer, int face);
|
||||
string osSetDynamicTextureDataBlend(string dynamicID, string contentType, string data, string extraParams,
|
||||
int timer, int alpha);
|
||||
string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams,
|
||||
|
@ -143,8 +144,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
|||
void osSetParcelSIPAddress(string SIPAddress);
|
||||
|
||||
// Avatar Info Commands
|
||||
string osGetAgentIP(string agent);
|
||||
LSL_List osGetAgents();
|
||||
string osGetAgentIP(string agent);
|
||||
|
||||
// Teleport commands
|
||||
void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
|
||||
|
@ -222,10 +223,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
|||
string osDrawLine(string drawList, int endX, int endY);
|
||||
string osDrawText(string drawList, string text);
|
||||
string osDrawEllipse(string drawList, int width, int height);
|
||||
string osDrawFilledEllipse(string drawList, int width, int height);
|
||||
string osDrawRectangle(string drawList, int width, int height);
|
||||
string osDrawFilledRectangle(string drawList, int width, int height);
|
||||
string osDrawPolygon(string drawList, LSL_List x, LSL_List y);
|
||||
string osDrawFilledPolygon(string drawList, LSL_List x, LSL_List y);
|
||||
string osDrawResetTransform(string drawList);
|
||||
string osDrawRotationTransform(string drawList, LSL_Float x);
|
||||
string osDrawScaleTransform(string drawList, LSL_Float x, LSL_Float y);
|
||||
string osDrawTranslationTransform(string drawList, LSL_Float x, LSL_Float y);
|
||||
string osSetFontName(string drawList, string fontName);
|
||||
string osSetFontSize(string drawList, int fontSize);
|
||||
string osSetPenSize(string drawList, int penSize);
|
||||
|
@ -389,6 +395,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
|||
void osSetProjectionParams(LSL_Key prim, bool projection, LSL_Key texture, double fov, double focus, double amb);
|
||||
|
||||
LSL_List osGetAvatarList();
|
||||
LSL_List osGetNPCList();
|
||||
|
||||
LSL_String osUnixTimeToTimestamp(long time);
|
||||
|
||||
|
|
|
@ -697,7 +697,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
|||
public const int PARCEL_DETAILS_GROUP = 3;
|
||||
public const int PARCEL_DETAILS_AREA = 4;
|
||||
public const int PARCEL_DETAILS_ID = 5;
|
||||
public const int PARCEL_DETAILS_SEE_AVATARS = 6; // not implemented
|
||||
public const int PARCEL_DETAILS_SEE_AVATARS = 6;
|
||||
public const int PARCEL_DETAILS_ANY_AVATAR_SOUNDS = 7;
|
||||
public const int PARCEL_DETAILS_GROUP_SOUNDS = 8;
|
||||
|
||||
//osSetParcelDetails
|
||||
public const int PARCEL_DETAILS_CLAIMDATE = 10;
|
||||
|
|
|
@ -153,6 +153,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
|||
return m_OSSL_Functions.osSetDynamicTextureData(dynamicID, contentType, data, extraParams, timer);
|
||||
}
|
||||
|
||||
public string osSetDynamicTextureDataFace(string dynamicID, string contentType, string data, string extraParams,
|
||||
int timer, int face)
|
||||
{
|
||||
return m_OSSL_Functions.osSetDynamicTextureDataFace(dynamicID, contentType, data, extraParams, timer, face);
|
||||
}
|
||||
|
||||
public string osSetDynamicTextureURLBlend(string dynamicID, string contentType, string url, string extraParams,
|
||||
int timer, int alpha)
|
||||
{
|
||||
|
@ -271,17 +277,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
|||
m_OSSL_Functions.osTeleportOwner(position, lookat);
|
||||
}
|
||||
|
||||
// Avatar info functions
|
||||
public string osGetAgentIP(string agent)
|
||||
{
|
||||
return m_OSSL_Functions.osGetAgentIP(agent);
|
||||
}
|
||||
|
||||
public LSL_List osGetAgents()
|
||||
{
|
||||
return m_OSSL_Functions.osGetAgents();
|
||||
}
|
||||
|
||||
public string osGetAgentIP(string agent)
|
||||
{
|
||||
return m_OSSL_Functions.osGetAgentIP(agent);
|
||||
}
|
||||
|
||||
// Animation Functions
|
||||
|
||||
public void osAvatarPlayAnimation(string avatar, string animation)
|
||||
|
@ -355,6 +360,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
|||
return m_OSSL_Functions.osDrawEllipse(drawList, width, height);
|
||||
}
|
||||
|
||||
public string osDrawFilledEllipse(string drawList, int width, int height)
|
||||
{
|
||||
return m_OSSL_Functions.osDrawFilledEllipse(drawList, width, height);
|
||||
}
|
||||
|
||||
public string osDrawRectangle(string drawList, int width, int height)
|
||||
{
|
||||
return m_OSSL_Functions.osDrawRectangle(drawList, width, height);
|
||||
|
@ -375,6 +385,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
|||
return m_OSSL_Functions.osDrawFilledPolygon(drawList, x, y);
|
||||
}
|
||||
|
||||
public string osDrawResetTransform(string drawList)
|
||||
{
|
||||
return m_OSSL_Functions.osDrawResetTransform(drawList);
|
||||
}
|
||||
|
||||
public string osDrawRotationTransform(string drawList, LSL_Float x)
|
||||
{
|
||||
return m_OSSL_Functions.osDrawRotationTransform(drawList, x);
|
||||
}
|
||||
|
||||
public string osDrawScaleTransform(string drawList, LSL_Float x, LSL_Float y)
|
||||
{
|
||||
return m_OSSL_Functions.osDrawScaleTransform(drawList, x, y);
|
||||
}
|
||||
|
||||
public string osDrawTranslationTransform(string drawList, LSL_Float x, LSL_Float y)
|
||||
{
|
||||
return m_OSSL_Functions.osDrawTranslationTransform(drawList, x, y);
|
||||
}
|
||||
|
||||
public string osSetFontSize(string drawList, int fontSize)
|
||||
{
|
||||
return m_OSSL_Functions.osSetFontSize(drawList, fontSize);
|
||||
|
@ -399,6 +429,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
|||
{
|
||||
return m_OSSL_Functions.osSetPenColor(drawList, color);
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
public string osSetPenColour(string drawList, string colour)
|
||||
{
|
||||
|
@ -1010,6 +1041,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
|||
return m_OSSL_Functions.osGetAvatarList();
|
||||
}
|
||||
|
||||
public LSL_List osGetNPCList()
|
||||
{
|
||||
return m_OSSL_Functions.osGetNPCList();
|
||||
}
|
||||
|
||||
public LSL_String osUnixTimeToTimestamp(long time)
|
||||
{
|
||||
return m_OSSL_Functions.osUnixTimeToTimestamp(time);
|
||||
|
|
|
@ -39,7 +39,6 @@ using OMV_Quaternion = OpenMetaverse.Quaternion;
|
|||
|
||||
namespace OpenSim.Region.ScriptEngine.Shared
|
||||
{
|
||||
[Serializable]
|
||||
public partial class LSL_Types
|
||||
{
|
||||
// Types are kept is separate .dll to avoid having to add whatever .dll it is in it to script AppDomain
|
||||
|
@ -526,7 +525,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
|
|||
}
|
||||
|
||||
[Serializable]
|
||||
public class list
|
||||
public class list: MarshalByRefObject
|
||||
{
|
||||
private object[] m_data;
|
||||
|
||||
|
|
|
@ -109,6 +109,7 @@ namespace OpenSim.Tests.Common
|
|||
public bool IsLandPrimCountTainted() { return false; }
|
||||
public bool IsForcefulBansAllowed() { return false; }
|
||||
public void UpdateLandObject(int localID, LandData data) {}
|
||||
public void SendParcelsOverlay(IClientAPI client) {}
|
||||
public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) {}
|
||||
public void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) {}
|
||||
public void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) {}
|
||||
|
|
|
@ -118,8 +118,7 @@ namespace OpenSim.Tests.Stress
|
|||
so.UUID,
|
||||
m_tests.Vrm.GetContentType(),
|
||||
string.Format("PenColour BLACK; MoveTo 40,220; FontSize 32; Text {0};", text),
|
||||
"",
|
||||
0);
|
||||
"");
|
||||
|
||||
Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
|
||||
|
||||
|
|
Binary file not shown.
|
@ -1,349 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>OpenMetaverse.StructuredData</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDType">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Unknown">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Boolean">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Integer">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Real">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.String">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.UUID">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Date">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.URI">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Binary">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Map">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Array">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDException">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSD">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSD.SerializeMembers(System.Object)">
|
||||
<summary>
|
||||
Uses reflection to create an SDMap from all of the SD
|
||||
serializable types in an object
|
||||
</summary>
|
||||
<param name="obj">Class or struct containing serializable types</param>
|
||||
<returns>An SDMap holding the serialized values from the
|
||||
container object</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSD.DeserializeMembers(System.Object@,OpenMetaverse.StructuredData.OSDMap)">
|
||||
<summary>
|
||||
Uses reflection to deserialize member variables in an object from
|
||||
an SDMap
|
||||
</summary>
|
||||
<param name="obj">Reference to an object to fill with deserialized
|
||||
values</param>
|
||||
<param name="serialized">Serialized values to put in the target
|
||||
object</param>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDBoolean">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDInteger">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDReal">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDString">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDUUID">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDDate">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDUri">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDBinary">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDMap">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDArray">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDParser">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDBinary(System.Byte[])">
|
||||
<summary>
|
||||
Deserializes binary LLSD
|
||||
</summary>
|
||||
<param name="binaryData">Serialized data</param>
|
||||
<returns>OSD containting deserialized data</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDBinary(System.IO.Stream)">
|
||||
<summary>
|
||||
Deserializes binary LLSD
|
||||
</summary>
|
||||
<param name="stream">Stream to read the data from</param>
|
||||
<returns>OSD containting deserialized data</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDBinary(OpenMetaverse.StructuredData.OSD)">
|
||||
<summary>
|
||||
Serializes OSD to binary format. It does no prepend header
|
||||
</summary>
|
||||
<param name="osd">OSD to serialize</param>
|
||||
<returns>Serialized data</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDBinary(OpenMetaverse.StructuredData.OSD,System.Boolean)">
|
||||
<summary>
|
||||
Serializes OSD to binary format
|
||||
</summary>
|
||||
<param name="osd">OSD to serialize</param>
|
||||
<param name="prependHeader"></param>
|
||||
<returns>Serialized data</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDBinaryStream(OpenMetaverse.StructuredData.OSD)">
|
||||
<summary>
|
||||
Serializes OSD to binary format. It does no prepend header
|
||||
</summary>
|
||||
<param name="data">OSD to serialize</param>
|
||||
<returns>Serialized data</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDBinaryStream(OpenMetaverse.StructuredData.OSD,System.Boolean)">
|
||||
<summary>
|
||||
Serializes OSD to binary format
|
||||
</summary>
|
||||
<param name="data">OSD to serialize</param>
|
||||
<param name="prependHeader"></param>
|
||||
<returns>Serialized data</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SkipWhiteSpace(System.IO.Stream)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="stream"></param>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.FindByte(System.IO.Stream,System.Byte)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="stream"></param>
|
||||
<param name="toFind"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.FindString(System.IO.Stream,System.String)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="stream"></param>
|
||||
<param name="toFind"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.ConsumeBytes(System.IO.Stream,System.Int32)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="stream"></param>
|
||||
<param name="consumeBytes"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.NetworkToHostInt(System.Byte[])">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="binaryNetEnd"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.NetworkToHostDouble(System.Byte[])">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="binaryNetEnd"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.HostToNetworkIntBytes(System.Int32)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="intHostEnd"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDNotationElement(System.IO.StringReader)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.PeekAndSkipWhitespace(System.IO.StringReader)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.ReadAndSkipWhitespace(System.IO.StringReader)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.GetLengthInBrackets(System.IO.StringReader)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.GetStringDelimitedBy(System.IO.StringReader,System.Char)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<param name="delimiter"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.BufferCharactersEqual(System.IO.StringReader,System.Char[],System.Int32)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<param name="buffer"></param>
|
||||
<param name="offset"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.UnescapeCharacter(System.String,System.Char)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="s"></param>
|
||||
<param name="c"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.EscapeCharacter(System.String,System.Char)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="s"></param>
|
||||
<param name="c"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDXml(System.Byte[])">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="xmlData"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDXml(System.String)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="xmlData"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDXml(System.Xml.XmlTextReader)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="xmlData"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDXmlBytes(OpenMetaverse.StructuredData.OSD)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="data"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDXmlString(OpenMetaverse.StructuredData.OSD)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="data"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDXmlElement(System.Xml.XmlTextWriter,OpenMetaverse.StructuredData.OSD)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="writer"></param>
|
||||
<param name="data"></param>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.TryValidateLLSDXml(System.Xml.XmlTextReader,System.String@)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="xmlData"></param>
|
||||
<param name="error"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.ParseLLSDXmlElement(System.Xml.XmlTextReader)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
Binary file not shown.
36656
bin/OpenMetaverse.XML
36656
bin/OpenMetaverse.XML
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -1464,13 +1464,21 @@
|
|||
|
||||
|
||||
[Trees]
|
||||
; Enable this to allow the tree module to manage your sim trees, including growing, reproducing and dying
|
||||
; default is false
|
||||
; enable the trees module. default true
|
||||
enabled = true
|
||||
|
||||
; active_trees allows module to change its trees in time.
|
||||
; some will be deleted, others created and rest may grow
|
||||
; default is false. You can change it with console comand tree active true | false later
|
||||
active_trees = false
|
||||
; the trees change execution time rate (in ms)
|
||||
update_rate = 1000
|
||||
|
||||
; Density of tree population
|
||||
tree_density = 1000.0
|
||||
|
||||
; allow the trees to grow.
|
||||
; DANGER
|
||||
; this option causes high network use on the order of
|
||||
; NumberOfTrees * NumberAvatars * 1000 / update_rate udp packets per second
|
||||
allowGrow = false
|
||||
|
||||
[VectorRender]
|
||||
; the font to use for rendering text (default: Arial)
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
; higher threat level OSSL functions, as detailed later on.
|
||||
OSFunctionThreatLevel = VeryLow
|
||||
|
||||
; Each of the OSSL functions can be enabled or disabled individually.
|
||||
; Some of the OSSL functions can be enabled or disabled individually.
|
||||
; To disable, set the value to 'false'.
|
||||
; To enable for everyone, set the value to 'true'.
|
||||
; To enable for individuals or groups, set it to a comma separated list. This checks
|
||||
|
@ -45,12 +45,10 @@
|
|||
; "PARCEL_OWNER" -- enable for parcel owner
|
||||
; "PARCEL_GROUP_MEMBER" -- enable for any member of the parcel group
|
||||
; uuid -- enable for specified ID (may be avatar or group ID)
|
||||
|
||||
; The OSSL function name is prepended with "Allow_" and it checks against
|
||||
; the owners of the containing prim. There can also be entries beginning with
|
||||
; 'Creators_". The 'Creators_" parameters can only be a list of UUIDs and it is
|
||||
; checked against the creator of the script itself.
|
||||
|
||||
; from this we can also create macros that can be include in the list as
|
||||
; ${XEngine|macroname} see examples below
|
||||
|
||||
; parcel macros
|
||||
; Allowing ossl functions for anyone owning a parcel can be dangerous especially if
|
||||
; a region is selling or otherwise giving away parcel ownership. By default, parcel
|
||||
; ownership or group membership does not enable OSSL functions. Uncomment the
|
||||
|
@ -62,49 +60,31 @@
|
|||
; osslParcelO = "PARCEL_OWNER,"
|
||||
; osslParcelOG = "PARCEL_GROUP_MEMBER,PARCEL_OWNER,"
|
||||
|
||||
; There are a block of functions for creating and controlling NPCs.
|
||||
; NPC macros
|
||||
; These can be mis-used so limit use to those you can trust.
|
||||
osslNPC = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
|
||||
; ThreatLevel None
|
||||
Allow_osDrawEllipse = true
|
||||
Allow_osDrawFilledPolygon = true
|
||||
Allow_osDrawFilledRectangle = true
|
||||
Allow_osDrawImage = true
|
||||
Allow_osDrawLine = true
|
||||
Allow_osDrawPolygon = true
|
||||
Allow_osDrawRectangle = true
|
||||
Allow_osDrawText = true
|
||||
osslNPC = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
|
||||
; The OSSL function name is prepended with "Allow_" and it checks against
|
||||
; the owners of the containing prim. There can also be entries beginning with
|
||||
; 'Creators_". The 'Creators_" parameters can only be a list of UUIDs and it is
|
||||
; checked against the creator of the script itself.
|
||||
|
||||
; *************************************************
|
||||
|
||||
; ThreatLevel None
|
||||
Allow_osGetAgents = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osGetAvatarList = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osGetCurrentSunHour = true
|
||||
Allow_osGetGender = true
|
||||
Allow_osGetHealth = true
|
||||
Allow_osGetHealRate = true
|
||||
Allow_osGetInventoryDesc = true
|
||||
Allow_osGetMapTexture = true
|
||||
Allow_osGetRegionSize = true
|
||||
Allow_osGetNPCList = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osGetRezzingObject = true
|
||||
Allow_osGetSunParam = true
|
||||
Allow_osGetTerrainHeight = true
|
||||
Allow_osIsNpc = true
|
||||
Allow_osIsUUID = true
|
||||
Allow_osList2Double = true
|
||||
Allow_osMax = true
|
||||
Allow_osMin = true
|
||||
Allow_osMovePen = true
|
||||
Allow_osNpcGetOwner = ${XEngine|osslNPC}
|
||||
Allow_osParseJSON = true
|
||||
Allow_osParseJSONNew = true
|
||||
Allow_osSetFontName = true
|
||||
Allow_osSetFontSize = true
|
||||
Allow_osSetPenCap = true
|
||||
Allow_osSetPenColor = true
|
||||
Allow_osSetPenSize = true
|
||||
Allow_osSetSunParam = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osTeleportOwner = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osWindActiveModelPluginName = true
|
||||
Allow_osCheckODE = true ; Here for completeness. This function cannot be turned off
|
||||
|
||||
; ThreatLevel Nuisance
|
||||
Allow_osSetEstateSunSettings = ESTATE_MANAGER,ESTATE_OWNER
|
||||
|
@ -114,11 +94,11 @@
|
|||
Allow_osEjectFromGroup = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osForceBreakAllLinks = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osForceBreakLink = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osGetDrawStringSize = true
|
||||
Allow_osGetWindParam = true
|
||||
Allow_osInviteToGroup = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osReplaceString = true
|
||||
Allow_osSetDynamicTextureData = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osSetDynamicTextureDataFace = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osSetDynamicTextureDataBlend = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osSetDynamicTextureDataBlendFace = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osSetDynamicTextureURL = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
|
||||
|
@ -171,7 +151,6 @@
|
|||
Allow_osForceCreateLink = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osForceDropAttachment = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osForceDropAttachmentAt = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osGetAgentIP = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osGetLinkPrimitiveParams = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osGetPhysicsEngineType = true
|
||||
Allow_osGetPrimitiveParams = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
||||
|
@ -238,3 +217,49 @@
|
|||
Allow_osTeleportAgent = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
||||
Allow_osTeleportObject = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
|
||||
|
||||
; funtions ThreatLevel Severe with additional internal restrictions
|
||||
Allow_osGetAgentIP = true ; always restricted to Administrators (true or false to disable)
|
||||
|
||||
; available funtions out of Threat level control (for reference only)
|
||||
; Allow_osClearInertia = true
|
||||
; Allow_osCheckODE = true
|
||||
; Allow_osCollisionSound = true
|
||||
; Allow_osDrawEllipse = true
|
||||
; Allow_osDrawFilledEllipse = true
|
||||
; Allow_osDrawFilledPolygon = true
|
||||
; Allow_osDrawFilledRectangle = true
|
||||
; Allow_osDrawResetTransform = true
|
||||
; Allow_osDrawRotationTransform = true
|
||||
; Allow_osDrawScaleTransform = true
|
||||
; Allow_osDrawTranslationTransform = true
|
||||
; Allow_osDrawImage = true
|
||||
; Allow_osDrawLine = true
|
||||
; Allow_osDrawPolygon = true
|
||||
; Allow_osDrawRectangle = true
|
||||
; Allow_osDrawText = true
|
||||
; Allow_osGetCurrentSunHour = true
|
||||
; Allow_osGetPhysicsEngineName = true
|
||||
; Allow_osGetInertiaData = true
|
||||
; Allow_osGetInventoryDesc = true
|
||||
; Allow_osGetLinkNumber = true
|
||||
; Allow_osGetMapTexture = true
|
||||
; Allow_osGetRegionSize = true
|
||||
; Allow_osGetSunParam = true
|
||||
; Allow_osGetTerrainHeight = true
|
||||
; Allow_osGetDrawStringSize = true
|
||||
; Allow_osIsNpc = true
|
||||
; Allow_osIsUUID = true
|
||||
; Allow_osList2Double = true
|
||||
; Allow_osMax = true
|
||||
; Allow_osMin = true
|
||||
; Allow_osMovePen = true
|
||||
; Allow_osSetInertia = true
|
||||
; Allow_osSetInertiaAsBox = true
|
||||
; Allow_osSetInertiaAsSphere = true
|
||||
; Allow_osSetInertiaAsCylinder = true
|
||||
; Allow_osSetFontName = true
|
||||
; Allow_osSetFontSize = true
|
||||
; Allow_osSetPenCap = true
|
||||
; Allow_osSetPenColor = true
|
||||
; Allow_osSetPenSize = true
|
||||
; Allow_osVolumeDetect = true
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue