diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 4ea4a1a6d2..6fa36b5d15 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -677,7 +677,7 @@ namespace OpenSim.Framework.Servers.HttpServer
if (tickdiff > 3000)
{
m_log.InfoFormat(
- "[BASE HTTP SERVER]: slow {0} for {1} {2} {3} from {4} took {5} ms",
+ "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms",
requestMethod,
uriString,
requestHandler != null ? requestHandler.Name : "",
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs
index d2aa538ce1..2aa4af5202 100644
--- a/OpenSim/Framework/WebUtil.cs
+++ b/OpenSim/Framework/WebUtil.cs
@@ -53,19 +53,36 @@ namespace OpenSim.Framework
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
- private static int m_requestNumber = 0;
+ ///
+ /// Request number for diagnostic purposes.
+ ///
+ public static int RequestNumber = 0;
- // this is the header field used to communicate the local request id
- // used for performance and debugging
+ ///
+ /// this is the header field used to communicate the local request id
+ /// used for performance and debugging
+ ///
public const string OSHeaderRequestID = "opensim-request-id";
- // number of milliseconds a call can take before it is considered
- // a "long" call for warning & debugging purposes
- public const int LongCallTime = 500;
+ ///
+ /// Number of milliseconds a call can take before it is considered
+ /// a "long" call for warning & debugging purposes
+ ///
+ public const int LongCallTime = 3000;
- // dictionary of end points
+ ///
+ /// The maximum length of any data logged because of a long request time.
+ ///
+ ///
+ /// This is to truncate any really large post data, such as an asset. In theory, the first section should
+ /// give us useful information about the call (which agent it relates to if applicable, etc.).
+ ///
+ public const int MaxRequestDiagLength = 100;
+
+ ///
+ /// Dictionary of end points
+ ///
private static Dictionary m_endpointSerializer = new Dictionary();
-
private static object EndPointLock(string url)
{
@@ -128,12 +145,13 @@ namespace OpenSim.Framework
private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed)
{
- int reqnum = m_requestNumber++;
+ int reqnum = RequestNumber++;
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
string errorMessage = "unknown error";
int tickstart = Util.EnvironmentTickCount();
int tickdata = 0;
+ string strBuffer = null;
try
{
@@ -148,7 +166,7 @@ namespace OpenSim.Framework
// If there is some input, write it into the request
if (data != null)
{
- string strBuffer = OSDParser.SerializeJsonString(data);
+ strBuffer = OSDParser.SerializeJsonString(data);
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer);
if (compressed)
@@ -208,11 +226,18 @@ namespace OpenSim.Framework
}
finally
{
- // This just dumps a warning for any operation that takes more than 100 ms
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > LongCallTime)
- m_log.DebugFormat("[WEB UTIL]: osd request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing",
- reqnum,url,method,tickdiff,tickdata);
+ m_log.InfoFormat(
+ "[OSD REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
+ reqnum,
+ method,
+ url,
+ tickdiff,
+ tickdata,
+ strBuffer != null
+ ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer)
+ : "");
}
m_log.DebugFormat(
@@ -290,17 +315,17 @@ namespace OpenSim.Framework
private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout)
{
- int reqnum = m_requestNumber++;
+ int reqnum = RequestNumber++;
string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown";
// m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method);
string errorMessage = "unknown error";
int tickstart = Util.EnvironmentTickCount();
int tickdata = 0;
+ string queryString = null;
try
{
-
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.Timeout = timeout;
@@ -311,7 +336,7 @@ namespace OpenSim.Framework
if (data != null)
{
- string queryString = BuildQueryString(data);
+ queryString = BuildQueryString(data);
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString);
request.ContentLength = buffer.Length;
@@ -354,11 +379,19 @@ namespace OpenSim.Framework
{
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > LongCallTime)
- m_log.InfoFormat("[WEB UTIL]: form request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing",
- reqnum,url,method,tickdiff,tickdata);
+ m_log.InfoFormat(
+ "[SERVICE FORM]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
+ reqnum,
+ method,
+ url,
+ tickdiff,
+ tickdata,
+ queryString != null
+ ? (queryString.Length > MaxRequestDiagLength) ? queryString.Remove(MaxRequestDiagLength) : queryString
+ : "");
}
- m_log.WarnFormat("[WEB UTIL]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage);
+ m_log.WarnFormat("[SERVICE FORM]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage);
return ErrorResponseMap(errorMessage);
}
@@ -639,8 +672,6 @@ namespace OpenSim.Framework
return new string[0];
}
-
-
}
public static class AsynchronousRestObjectRequester
@@ -663,6 +694,12 @@ namespace OpenSim.Framework
public static void MakeRequest(string verb,
string requestUrl, TRequest obj, Action action)
{
+ int reqnum = WebUtil.RequestNumber++;
+ // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
+
+ int tickstart = Util.EnvironmentTickCount();
+ int tickdata = 0;
+
// m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl);
Type type = typeof(TRequest);
@@ -673,12 +710,13 @@ namespace OpenSim.Framework
XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
request.Method = verb;
+ MemoryStream buffer = null;
if (verb == "POST")
{
request.ContentType = "text/xml";
- MemoryStream buffer = new MemoryStream();
+ buffer = new MemoryStream();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
@@ -700,6 +738,9 @@ namespace OpenSim.Framework
requestStream.Write(buffer.ToArray(), 0, length);
requestStream.Close();
+ // capture how much time was spent writing
+ tickdata = Util.EnvironmentTickCountSubtract(tickstart);
+
request.BeginGetResponse(delegate(IAsyncResult ar)
{
response = request.EndGetResponse(ar);
@@ -725,88 +766,108 @@ namespace OpenSim.Framework
}, null);
}, null);
-
-
- return;
}
-
- request.BeginGetResponse(delegate(IAsyncResult res2)
+ else
{
- try
+ request.BeginGetResponse(delegate(IAsyncResult res2)
{
- // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't
- // documented in MSDN
- response = request.EndGetResponse(res2);
-
- Stream respStream = null;
try
{
- respStream = response.GetResponseStream();
- deserial = (TResponse)deserializer.Deserialize(respStream);
- }
- catch (System.InvalidOperationException)
- {
- }
- finally
- {
- respStream.Close();
- response.Close();
- }
- }
- catch (WebException e)
- {
- if (e.Status == WebExceptionStatus.ProtocolError)
- {
- if (e.Response is HttpWebResponse)
+ // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't
+ // documented in MSDN
+ response = request.EndGetResponse(res2);
+
+ Stream respStream = null;
+ try
{
- HttpWebResponse httpResponse = (HttpWebResponse)e.Response;
-
- if (httpResponse.StatusCode != HttpStatusCode.NotFound)
- {
- // We don't appear to be handling any other status codes, so log these feailures to that
- // people don't spend unnecessary hours hunting phantom bugs.
- m_log.DebugFormat(
- "[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}",
- verb, requestUrl, httpResponse.StatusCode);
- }
+ respStream = response.GetResponseStream();
+ deserial = (TResponse)deserializer.Deserialize(respStream);
+ }
+ catch (System.InvalidOperationException)
+ {
+ }
+ finally
+ {
+ respStream.Close();
+ response.Close();
}
}
- else
+ catch (WebException e)
+ {
+ if (e.Status == WebExceptionStatus.ProtocolError)
+ {
+ if (e.Response is HttpWebResponse)
+ {
+ HttpWebResponse httpResponse = (HttpWebResponse)e.Response;
+
+ if (httpResponse.StatusCode != HttpStatusCode.NotFound)
+ {
+ // We don't appear to be handling any other status codes, so log these feailures to that
+ // people don't spend unnecessary hours hunting phantom bugs.
+ m_log.DebugFormat(
+ "[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}",
+ verb, requestUrl, httpResponse.StatusCode);
+ }
+ }
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}",
+ verb, requestUrl, e.Status, e.Message);
+ }
+ }
+ catch (Exception e)
{
m_log.ErrorFormat(
- "[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}",
- verb, requestUrl, e.Status, e.Message);
+ "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}",
+ verb, requestUrl, e.Message, e.StackTrace);
}
- }
- catch (Exception e)
+
+ // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString());
+
+ try
+ {
+ action(deserial);
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat(
+ "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}",
+ verb, requestUrl, e.Message, e.StackTrace);
+ }
+
+ }, null);
+ }
+
+ int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
+ if (tickdiff > WebUtil.LongCallTime)
+ {
+ string originalRequest = null;
+
+ if (buffer != null)
{
- m_log.ErrorFormat(
- "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}",
- verb, requestUrl, e.Message, e.StackTrace);
+ originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
+
+ if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
+ originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
}
- // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString());
-
- try
- {
- action(deserial);
- }
- catch (Exception e)
- {
- m_log.ErrorFormat(
- "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}",
- verb, requestUrl, e.Message, e.StackTrace);
- }
-
- }, null);
+ m_log.InfoFormat(
+ "[ASYNC REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
+ reqnum,
+ verb,
+ requestUrl,
+ tickdiff,
+ tickdata,
+ originalRequest);
+ }
}
}
public static class SynchronousRestFormsRequester
{
- private static readonly ILog m_log =
- LogManager.GetLogger(
- MethodBase.GetCurrentMethod().DeclaringType);
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
///
/// Perform a synchronous REST request.
@@ -820,6 +881,12 @@ namespace OpenSim.Framework
/// the request. You'll want to make sure you deal with this as they're not uncommon
public static string MakeRequest(string verb, string requestUrl, string obj)
{
+ int reqnum = WebUtil.RequestNumber++;
+ // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
+
+ int tickstart = Util.EnvironmentTickCount();
+ int tickdata = 0;
+
WebRequest request = WebRequest.Create(requestUrl);
request.Method = verb;
string respstring = String.Empty;
@@ -855,6 +922,9 @@ namespace OpenSim.Framework
{
if (requestStream != null)
requestStream.Close();
+
+ // capture how much time was spent writing
+ tickdata = Util.EnvironmentTickCountSubtract(tickstart);
}
}
@@ -893,6 +963,18 @@ namespace OpenSim.Framework
m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving {0} {1}", verb, requestUrl);
}
}
+
+ int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
+ if (tickdiff > WebUtil.LongCallTime)
+ m_log.InfoFormat(
+ "[FORMS]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
+ reqnum,
+ verb,
+ requestUrl,
+ tickdiff,
+ tickdata,
+ obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj);
+
return respstring;
}
}
@@ -915,17 +997,24 @@ namespace OpenSim.Framework
/// the request. You'll want to make sure you deal with this as they're not uncommon
public static TResponse MakeRequest(string verb, string requestUrl, TRequest obj)
{
+ int reqnum = WebUtil.RequestNumber++;
+ // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
+
+ int tickstart = Util.EnvironmentTickCount();
+ int tickdata = 0;
+
Type type = typeof(TRequest);
TResponse deserial = default(TResponse);
WebRequest request = WebRequest.Create(requestUrl);
request.Method = verb;
+ MemoryStream buffer = null;
if ((verb == "POST") || (verb == "PUT"))
{
request.ContentType = "text/xml";
- MemoryStream buffer = new MemoryStream();
+ buffer = new MemoryStream();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
@@ -958,6 +1047,9 @@ namespace OpenSim.Framework
{
if (requestStream != null)
requestStream.Close();
+
+ // capture how much time was spent writing
+ tickdata = Util.EnvironmentTickCountSubtract(tickstart);
}
}
@@ -1005,6 +1097,29 @@ namespace OpenSim.Framework
verb, requestUrl, e.Message, e.StackTrace);
}
+ int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
+ if (tickdiff > WebUtil.LongCallTime)
+ {
+ string originalRequest = null;
+
+ if (buffer != null)
+ {
+ originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
+
+ if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
+ originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
+ }
+
+ m_log.InfoFormat(
+ "[SynchronousRestObjectRequester]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
+ reqnum,
+ verb,
+ requestUrl,
+ tickdiff,
+ tickdata,
+ originalRequest);
+ }
+
return deserial;
}
}
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 389fb7b871..dd6026bd93 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -83,7 +83,7 @@ namespace Flotsam.RegionModules.AssetCache
private Dictionary m_CurrentlyWriting = new Dictionary();
private int m_WaitOnInprogressTimeout = 3000;
#else
- private List m_CurrentlyWriting = new List();
+ private HashSet m_CurrentlyWriting = new HashSet();
#endif
private bool m_FileCacheEnabled = true;
@@ -261,10 +261,14 @@ namespace Flotsam.RegionModules.AssetCache
try
{
- // If the file is already cached, don't cache it, just touch it so access time is updated
+ // If the file is already cached just update access time.
if (File.Exists(filename))
{
- File.SetLastAccessTime(filename, DateTime.Now);
+ lock (m_CurrentlyWriting)
+ {
+ if (!m_CurrentlyWriting.Contains(filename))
+ File.SetLastAccessTime(filename, DateTime.Now);
+ }
}
else
{
diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
index 0babeb5140..3a9146557d 100644
--- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
@@ -96,6 +96,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
ScenePresence killingAvatar = null;
// string killingAvatarMessage;
+ // check to see if it is an NPC and just remove it
+ INPCModule NPCmodule = deadAvatar.Scene.RequestModuleInterface();
+ if (NPCmodule != null && NPCmodule.DeleteNPC(deadAvatar.UUID, deadAvatar.Scene))
+ {
+ return;
+ }
+
if (killerObjectLocalID == 0)
deadAvatarMessage = "You committed suicide!";
else
@@ -145,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
catch (InvalidOperationException)
{ }
- deadAvatar.Health = 100;
+ deadAvatar.setHealthWithUpdate(100.0f);
deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient);
}
@@ -154,14 +161,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
try
{
ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
-
- if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0)
+ if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0
+ || avatar.Scene.RegionInfo.RegionSettings.AllowDamage)
{
avatar.Invulnerable = false;
}
else
{
avatar.Invulnerable = true;
+ if (avatar.Health < 100.0f)
+ {
+ avatar.setHealthWithUpdate(100.0f);
+ }
}
}
catch (Exception)
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index e47c339638..cd588e5d86 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -30,7 +30,6 @@ using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Threading;
-
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Client;
@@ -595,7 +594,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
{
-// Thread.Sleep(5000);
+ // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before
+ // they regard the new region as the current region after receiving the AgentMovementComplete
+ // response. If close is sent before then, it will cause the viewer to quit instead.
+ // However, if this delay is longer, then a viewer can teleport back to this region and experience
+ // a failure because the old ScenePresence has not yet been cleaned up.
+ Thread.Sleep(2000);
+
sp.Close();
sp.Scene.IncomingCloseAgent(sp.UUID);
}
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index 93e75b3622..d58fc0feac 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -146,6 +146,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
public void Close()
{
}
+
public UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID)
{
UUID urlcode = UUID.Random();
@@ -175,6 +176,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
uri,
new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode));
+ m_log.DebugFormat(
+ "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}",
+ uri, itemID, host.Name, host.LocalId);
+
engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
}
@@ -217,6 +222,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
uri,
new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode));
+ m_log.DebugFormat(
+ "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}",
+ uri, itemID, host.Name, host.LocalId);
+
engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
}
@@ -237,6 +246,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
foreach (UUID req in data.requests.Keys)
m_RequestMap.Remove(req);
+ m_log.DebugFormat(
+ "[URL MODULE]: Releasing url {0} for {1} in {2}",
+ url, data.itemID, data.hostID);
+
RemoveUrl(data);
m_UrlMap.Remove(url);
}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index e5a9a996ba..7e49a5e2cc 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1140,9 +1140,19 @@ namespace OpenSim.Region.Framework.Scenes
bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
MakeRootAgent(AbsolutePosition, flying);
+ ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
+
+// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
if ((m_callbackURI != null) && !m_callbackURI.Equals(""))
{
+ // We cannot sleep here since this would hold up the inbound packet processing thread, as
+ // CompleteMovement() is executed synchronously. However, it might be better to delay the release
+ // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete
+ // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this
+ // region as the current region, meaning that a close sent before then will fail the teleport.
+// System.Threading.Thread.Sleep(2000);
+
m_log.DebugFormat(
"[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
client.Name, client.AgentId, m_callbackURI);
@@ -1151,9 +1161,6 @@ namespace OpenSim.Region.Framework.Scenes
m_callbackURI = null;
}
-// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
-
- ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
ValidateAndSendAppearanceAndAgentData();
// Create child agents in neighbouring regions
@@ -1168,7 +1175,6 @@ namespace OpenSim.Region.Framework.Scenes
friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
}
-
// m_log.DebugFormat(
// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
@@ -3306,23 +3312,53 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- if (Invulnerable)
+ // Gods do not take damage and Invulnerable is set depending on parcel/region flags
+ if (Invulnerable || GodLevel > 0)
return;
-
+
+ // The following may be better in the ICombatModule
+ // probably tweaking of the values for ground and normal prim collisions will be needed
float starthealth = Health;
uint killerObj = 0;
+ SceneObjectPart part = null;
foreach (uint localid in coldata.Keys)
{
- SceneObjectPart part = Scene.GetSceneObjectPart(localid);
-
- if (part != null && part.ParentGroup.Damage != -1.0f)
- Health -= part.ParentGroup.Damage;
+ if (localid == 0)
+ {
+ part = null;
+ }
else
{
- if (coldata[localid].PenetrationDepth >= 0.10f)
+ part = Scene.GetSceneObjectPart(localid);
+ }
+ if (part != null)
+ {
+ // Ignore if it has been deleted or volume detect
+ if (!part.ParentGroup.IsDeleted && !part.ParentGroup.IsVolumeDetect)
+ {
+ if (part.ParentGroup.Damage > 0.0f)
+ {
+ // Something with damage...
+ Health -= part.ParentGroup.Damage;
+ part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false);
+ }
+ else
+ {
+ // An ordinary prim
+ if (coldata[localid].PenetrationDepth >= 0.10f)
+ Health -= coldata[localid].PenetrationDepth * 5.0f;
+ }
+ }
+ }
+ else
+ {
+ // 0 is the ground
+ // what about collisions with other avatars?
+ if (localid == 0 && coldata[localid].PenetrationDepth >= 0.10f)
Health -= coldata[localid].PenetrationDepth * 5.0f;
}
+
if (Health <= 0.0f)
{
if (localid != 0)
@@ -3338,7 +3374,16 @@ namespace OpenSim.Region.Framework.Scenes
ControllingClient.SendHealth(Health);
}
if (Health <= 0)
+ {
m_scene.EventManager.TriggerAvatarKill(killerObj, this);
+ }
+ if (starthealth == Health && Health < 100.0f)
+ {
+ Health += 0.03f;
+ if (Health > 100.0f)
+ Health = 100.0f;
+ ControllingClient.SendHealth(Health);
+ }
}
}
diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs
index 0e7a3584e2..15156d0537 100644
--- a/OpenSim/Services/InventoryService/XInventoryService.cs
+++ b/OpenSim/Services/InventoryService/XInventoryService.cs
@@ -52,6 +52,7 @@ namespace OpenSim.Services.InventoryService
: this(config, "InventoryService")
{
}
+
public XInventoryService(IConfigSource config, string configName) : base(config)
{
if (configName != string.Empty)
@@ -363,6 +364,11 @@ namespace OpenSim.Services.InventoryService
// We don't check the principal's ID here
//
public virtual bool DeleteFolders(UUID principalID, List folderIDs)
+ {
+ return DeleteFolders(principalID, folderIDs, true);
+ }
+
+ public virtual bool DeleteFolders(UUID principalID, List folderIDs, bool onlyIfTrash)
{
if (!m_AllowDelete)
return false;
@@ -371,11 +377,12 @@ namespace OpenSim.Services.InventoryService
//
foreach (UUID id in folderIDs)
{
- if (!ParentIsTrash(id))
+ if (onlyIfTrash && !ParentIsTrash(id))
continue;
+ //m_log.InfoFormat("[XINVENTORY SERVICE]: Delete folder {0}", id);
InventoryFolderBase f = new InventoryFolderBase();
f.ID = id;
- PurgeFolder(f);
+ PurgeFolder(f, onlyIfTrash);
m_Database.DeleteFolders("folderID", id.ToString());
}
@@ -383,11 +390,16 @@ namespace OpenSim.Services.InventoryService
}
public virtual bool PurgeFolder(InventoryFolderBase folder)
+ {
+ return PurgeFolder(folder, true);
+ }
+
+ public virtual bool PurgeFolder(InventoryFolderBase folder, bool onlyIfTrash)
{
if (!m_AllowDelete)
return false;
- if (!ParentIsTrash(folder.ID))
+ if (onlyIfTrash && !ParentIsTrash(folder.ID))
return false;
XInventoryFolder[] subFolders = m_Database.GetFolders(
@@ -396,7 +408,7 @@ namespace OpenSim.Services.InventoryService
foreach (XInventoryFolder x in subFolders)
{
- PurgeFolder(ConvertToOpenSim(x));
+ PurgeFolder(ConvertToOpenSim(x), onlyIfTrash);
m_Database.DeleteFolders("folderID", x.folderID.ToString());
}
diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
index 01de15990d..9ec744f80f 100644
--- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
@@ -226,7 +226,8 @@ namespace OpenSim.Services.LLLoginService
public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo,
GridRegion destination, List invSkel, FriendInfo[] friendsList, ILibraryService libService,
string where, string startlocation, Vector3 position, Vector3 lookAt, List gestures, string message,
- GridRegion home, IPEndPoint clientIP, string mapTileURL, string profileURL, string openIDURL, string searchURL, string currency)
+ GridRegion home, IPEndPoint clientIP, string mapTileURL, string profileURL, string openIDURL, string searchURL, string currency,
+ string DSTZone)
: this()
{
FillOutInventoryData(invSkel, libService);
@@ -255,7 +256,45 @@ namespace OpenSim.Services.LLLoginService
FillOutRegionData(destination);
FillOutSeedCap(aCircuit, destination, clientIP);
-
+
+ switch (DSTZone)
+ {
+ case "none":
+ DST = "N";
+ break;
+ case "local":
+ DST = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N";
+ break;
+ default:
+ TimeZoneInfo dstTimeZone = null;
+ string[] tzList = DSTZone.Split(';');
+
+ foreach (string tzName in tzList)
+ {
+ try
+ {
+ dstTimeZone = TimeZoneInfo.FindSystemTimeZoneById(tzName);
+ }
+ catch
+ {
+ continue;
+ }
+ break;
+ }
+
+ if (dstTimeZone == null)
+ {
+ m_log.WarnFormat(
+ "[LLOGIN RESPONSE]: No valid timezone found for DST in {0}, falling back to system time.", tzList);
+ DST = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N";
+ }
+ else
+ {
+ DST = dstTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N";
+ }
+
+ break;
+ }
}
private void FillOutInventoryData(List invSkel, ILibraryService libService)
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
index db8a9cb2a9..9acba114da 100644
--- a/OpenSim/Services/LLLoginService/LLLoginService.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -82,6 +82,8 @@ namespace OpenSim.Services.LLLoginService
protected string m_AllowedClients;
protected string m_DeniedClients;
+ protected string m_DSTZone;
+
IConfig m_LoginServerConfig;
// IConfig m_ClientsConfig;
@@ -118,6 +120,8 @@ namespace OpenSim.Services.LLLoginService
m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty);
m_DeniedClients = m_LoginServerConfig.GetString("DeniedClients", string.Empty);
+ m_DSTZone = m_LoginServerConfig.GetString("DSTZone", "America/Los_Angeles;Pacific Standard Time");
+
// Clean up some of these vars
if (m_MapTileURL != String.Empty)
{
@@ -240,6 +244,7 @@ namespace OpenSim.Services.LLLoginService
m_log.InfoFormat("[LLOGIN SERVICE]: Login request for {0} {1} at {2} using viewer {3}, channel {4}, IP {5}, Mac {6}, Id0 {7}",
firstName, lastName, startLocation, clientVersion, channel, clientIP.Address.ToString(), mac, id0);
+
try
{
//
@@ -416,8 +421,11 @@ namespace OpenSim.Services.LLLoginService
//
// Finally, fill out the response and return it
//
- LLLoginResponse response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService,
- where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP, m_MapTileURL, m_ProfileURL, m_OpenIDURL, m_SearchURL, m_Currency);
+ LLLoginResponse response
+ = new LLLoginResponse(
+ account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService,
+ where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP,
+ m_MapTileURL, m_ProfileURL, m_OpenIDURL, m_SearchURL, m_Currency, m_DSTZone);
m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client.");
return response;
@@ -431,7 +439,10 @@ namespace OpenSim.Services.LLLoginService
}
}
- protected GridRegion FindDestination(UserAccount account, UUID scopeID, GridUserInfo pinfo, UUID sessionID, string startLocation, GridRegion home, out GridRegion gatekeeper, out string where, out Vector3 position, out Vector3 lookAt, out TeleportFlags flags)
+ protected GridRegion FindDestination(
+ UserAccount account, UUID scopeID, GridUserInfo pinfo, UUID sessionID, string startLocation,
+ GridRegion home, out GridRegion gatekeeper,
+ out string where, out Vector3 position, out Vector3 lookAt, out TeleportFlags flags)
{
flags = TeleportFlags.ViaLogin;
diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example
index e9c3c838a9..28d2c5bcb9 100644
--- a/bin/Robust.HG.ini.example
+++ b/bin/Robust.HG.ini.example
@@ -275,6 +275,18 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
;AllowedClients = ""
;DeniedClients = ""
+ ;# {DSTZone} {} {Override Daylight Saving Time rules} {* none local} "America/Los_Angeles;Pacific Standard Time"
+ ;; Viewers do not receive timezone information from the server - almost all (?) default to Pacific Standard Time
+ ;; However, they do rely on the server to tell them whether it's Daylight Saving Time or not.
+ ;; Hence, calculating DST based on a different timezone can result in a misleading viewer display and inconsistencies between grids.
+ ;; By default, this setting uses various timezone names to calculate DST with regards to the viewer's standard PST.
+ ;; Options are
+ ;; "none" no DST
+ ;; "local" use the server's only timezone to calculate DST. This is previous OpenSimulator behaviour.
+ ;; "America/Los_Angeles;Pacific Standard Time" use these timezone names to look up Daylight savings.
+ ;; 'America/Los_Angeles' is used on Linux/Mac systems whilst 'Pacific Standard Time' is used on Windows
+ DSTZone = "America/Los_Angeles;Pacific Standard Time"
+
[MapImageService]
LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService"
; Set this if you want to change the default
diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example
index 273794d572..c58307b38f 100644
--- a/bin/Robust.ini.example
+++ b/bin/Robust.ini.example
@@ -250,6 +250,27 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
;AllowedClients = ""
;DeniedClients = ""
+ ;# {DSTZone} {} {Override Daylight Saving Time rules} {* none local} "America/Los_Angeles;Pacific Standard Time"
+ ;; Viewers do not listen to timezone sent by the server. They use Pacific Standard Time instead,
+ ;; but rely on the server to calculate Daylight Saving Time. Sending another DST than US Pacific
+ ;; would result in time inconsistencies between grids (during summer and around DST transition period)
+ ;; default let OpenSim calculate US Pacific DST
+ ;; "none" disable DST (equivallent to "local" with system set to GMT)
+ ;; "local" force legacy behaviour (using local system time to calculate DST)
+ ; DSTZone = "America/Los_Angeles;Pacific Standard Time"
+
+ ;# {DSTZone} {} {Override Daylight Saving Time rules} {* none local} "America/Los_Angeles;Pacific Standard Time"
+ ;; Viewers do not receive timezone information from the server - almost all (?) default to Pacific Standard Time
+ ;; However, they do rely on the server to tell them whether it's Daylight Saving Time or not.
+ ;; Hence, calculating DST based on a different timezone can result in a misleading viewer display and inconsistencies between grids.
+ ;; By default, this setting uses various timezone names to calculate DST with regards to the viewer's standard PST.
+ ;; Options are
+ ;; "none" no DST
+ ;; "local" use the server's only timezone to calculate DST. This is previous OpenSimulator behaviour.
+ ;; "America/Los_Angeles;Pacific Standard Time" use these timezone names to look up Daylight savings.
+ ;; 'America/Los_Angeles' is used on Linux/Mac systems whilst 'Pacific Standard Time' is used on Windows
+ DSTZone = "America/Los_Angeles;Pacific Standard Time"
+
[MapImageService]
LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService"
; Set this if you want to change the default
diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini
index d307387e85..74d9d2eb3e 100644
--- a/bin/config-include/Standalone.ini
+++ b/bin/config-include/Standalone.ini
@@ -95,6 +95,18 @@
WelcomeMessage = "Welcome, Avatar!"
+ ;# {DSTZone} {} {Override Daylight Saving Time rules} {* none local} "America/Los_Angeles;Pacific Standard Time"
+ ;; Viewers do not receive timezone information from the server - almost all (?) default to Pacific Standard Time
+ ;; However, they do rely on the server to tell them whether it's Daylight Saving Time or not.
+ ;; Hence, calculating DST based on a different timezone can result in a misleading viewer display and inconsistencies between grids.
+ ;; By default, this setting uses various timezone names to calculate DST with regards to the viewer's standard PST.
+ ;; Options are
+ ;; "none" no DST
+ ;; "local" use the server's only timezone to calculate DST. This is previous OpenSimulator behaviour.
+ ;; "America/Los_Angeles;Pacific Standard Time" use these timezone names to look up Daylight savings.
+ ;; 'America/Los_Angeles' is used on Linux/Mac systems whilst 'Pacific Standard Time' is used on Windows
+ DSTZone = "America/Los_Angeles;Pacific Standard Time"
+
[MapImageService]
LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService"
; in minutes