Merge branch 'master' of /home/opensim/var/repo/opensim

integration
BlueWall 2012-05-04 18:55:44 -04:00
commit 90a4d965d9
13 changed files with 415 additions and 115 deletions

View File

@ -677,7 +677,7 @@ namespace OpenSim.Framework.Servers.HttpServer
if (tickdiff > 3000) if (tickdiff > 3000)
{ {
m_log.InfoFormat( 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, requestMethod,
uriString, uriString,
requestHandler != null ? requestHandler.Name : "", requestHandler != null ? requestHandler.Name : "",

View File

@ -53,19 +53,36 @@ namespace OpenSim.Framework
LogManager.GetLogger( LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType); MethodBase.GetCurrentMethod().DeclaringType);
private static int m_requestNumber = 0; /// <summary>
/// Request number for diagnostic purposes.
/// </summary>
public static int RequestNumber = 0;
// this is the header field used to communicate the local request id /// <summary>
// used for performance and debugging /// this is the header field used to communicate the local request id
/// used for performance and debugging
/// </summary>
public const string OSHeaderRequestID = "opensim-request-id"; public const string OSHeaderRequestID = "opensim-request-id";
// number of milliseconds a call can take before it is considered /// <summary>
// a "long" call for warning & debugging purposes /// Number of milliseconds a call can take before it is considered
public const int LongCallTime = 500; /// a "long" call for warning & debugging purposes
/// </summary>
public const int LongCallTime = 3000;
// dictionary of end points /// <summary>
/// The maximum length of any data logged because of a long request time.
/// </summary>
/// <remarks>
/// 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.).
/// </remarks>
public const int MaxRequestDiagLength = 100;
/// <summary>
/// Dictionary of end points
/// </summary>
private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>(); private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>();
private static object EndPointLock(string url) 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) 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); // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
string errorMessage = "unknown error"; string errorMessage = "unknown error";
int tickstart = Util.EnvironmentTickCount(); int tickstart = Util.EnvironmentTickCount();
int tickdata = 0; int tickdata = 0;
string strBuffer = null;
try try
{ {
@ -148,7 +166,7 @@ namespace OpenSim.Framework
// If there is some input, write it into the request // If there is some input, write it into the request
if (data != null) if (data != null)
{ {
string strBuffer = OSDParser.SerializeJsonString(data); strBuffer = OSDParser.SerializeJsonString(data);
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer);
if (compressed) if (compressed)
@ -208,11 +226,18 @@ namespace OpenSim.Framework
} }
finally finally
{ {
// This just dumps a warning for any operation that takes more than 100 ms
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > LongCallTime) if (tickdiff > LongCallTime)
m_log.DebugFormat("[WEB UTIL]: osd request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing", m_log.InfoFormat(
reqnum,url,method,tickdiff,tickdata); "[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( m_log.DebugFormat(
@ -290,17 +315,17 @@ namespace OpenSim.Framework
private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout) 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"; 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); // m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method);
string errorMessage = "unknown error"; string errorMessage = "unknown error";
int tickstart = Util.EnvironmentTickCount(); int tickstart = Util.EnvironmentTickCount();
int tickdata = 0; int tickdata = 0;
string queryString = null;
try try
{ {
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST"; request.Method = "POST";
request.Timeout = timeout; request.Timeout = timeout;
@ -311,7 +336,7 @@ namespace OpenSim.Framework
if (data != null) if (data != null)
{ {
string queryString = BuildQueryString(data); queryString = BuildQueryString(data);
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString);
request.ContentLength = buffer.Length; request.ContentLength = buffer.Length;
@ -354,11 +379,19 @@ namespace OpenSim.Framework
{ {
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > LongCallTime) if (tickdiff > LongCallTime)
m_log.InfoFormat("[WEB UTIL]: form request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing", m_log.InfoFormat(
reqnum,url,method,tickdiff,tickdata); "[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); return ErrorResponseMap(errorMessage);
} }
@ -639,8 +672,6 @@ namespace OpenSim.Framework
return new string[0]; return new string[0];
} }
} }
public static class AsynchronousRestObjectRequester public static class AsynchronousRestObjectRequester
@ -663,6 +694,12 @@ namespace OpenSim.Framework
public static void MakeRequest<TRequest, TResponse>(string verb, public static void MakeRequest<TRequest, TResponse>(string verb,
string requestUrl, TRequest obj, Action<TResponse> action) string requestUrl, TRequest obj, Action<TResponse> 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); // m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl);
Type type = typeof(TRequest); Type type = typeof(TRequest);
@ -673,12 +710,13 @@ namespace OpenSim.Framework
XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
request.Method = verb; request.Method = verb;
MemoryStream buffer = null;
if (verb == "POST") if (verb == "POST")
{ {
request.ContentType = "text/xml"; request.ContentType = "text/xml";
MemoryStream buffer = new MemoryStream(); buffer = new MemoryStream();
XmlWriterSettings settings = new XmlWriterSettings(); XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8; settings.Encoding = Encoding.UTF8;
@ -700,6 +738,9 @@ namespace OpenSim.Framework
requestStream.Write(buffer.ToArray(), 0, length); requestStream.Write(buffer.ToArray(), 0, length);
requestStream.Close(); requestStream.Close();
// capture how much time was spent writing
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
request.BeginGetResponse(delegate(IAsyncResult ar) request.BeginGetResponse(delegate(IAsyncResult ar)
{ {
response = request.EndGetResponse(ar); response = request.EndGetResponse(ar);
@ -725,88 +766,108 @@ namespace OpenSim.Framework
}, null); }, null);
}, null); }, null);
return;
} }
else
request.BeginGetResponse(delegate(IAsyncResult res2)
{ {
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 try
{ {
respStream = response.GetResponseStream(); // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't
deserial = (TResponse)deserializer.Deserialize(respStream); // documented in MSDN
} response = request.EndGetResponse(res2);
catch (System.InvalidOperationException)
{ Stream respStream = null;
} try
finally
{
respStream.Close();
response.Close();
}
}
catch (WebException e)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
if (e.Response is HttpWebResponse)
{ {
HttpWebResponse httpResponse = (HttpWebResponse)e.Response; respStream = response.GetResponseStream();
deserial = (TResponse)deserializer.Deserialize(respStream);
if (httpResponse.StatusCode != HttpStatusCode.NotFound) }
{ catch (System.InvalidOperationException)
// 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( finally
"[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}", {
verb, requestUrl, httpResponse.StatusCode); 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( m_log.ErrorFormat(
"[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}",
verb, requestUrl, e.Status, e.Message); 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( originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
"[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}",
verb, requestUrl, e.Message, e.StackTrace); if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
} }
// m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); m_log.InfoFormat(
"[ASYNC REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
try reqnum,
{ verb,
action(deserial); requestUrl,
} tickdiff,
catch (Exception e) tickdata,
{ originalRequest);
m_log.ErrorFormat( }
"[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}",
verb, requestUrl, e.Message, e.StackTrace);
}
}, null);
} }
} }
public static class SynchronousRestFormsRequester public static class SynchronousRestFormsRequester
{ {
private static readonly ILog m_log = private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
/// <summary> /// <summary>
/// Perform a synchronous REST request. /// 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</exception> /// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
public static string MakeRequest(string verb, string requestUrl, string obj) 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); WebRequest request = WebRequest.Create(requestUrl);
request.Method = verb; request.Method = verb;
string respstring = String.Empty; string respstring = String.Empty;
@ -855,6 +922,9 @@ namespace OpenSim.Framework
{ {
if (requestStream != null) if (requestStream != null)
requestStream.Close(); 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); 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; 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</exception> /// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj) public static TResponse MakeRequest<TRequest, TResponse>(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); Type type = typeof(TRequest);
TResponse deserial = default(TResponse); TResponse deserial = default(TResponse);
WebRequest request = WebRequest.Create(requestUrl); WebRequest request = WebRequest.Create(requestUrl);
request.Method = verb; request.Method = verb;
MemoryStream buffer = null;
if ((verb == "POST") || (verb == "PUT")) if ((verb == "POST") || (verb == "PUT"))
{ {
request.ContentType = "text/xml"; request.ContentType = "text/xml";
MemoryStream buffer = new MemoryStream(); buffer = new MemoryStream();
XmlWriterSettings settings = new XmlWriterSettings(); XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8; settings.Encoding = Encoding.UTF8;
@ -958,6 +1047,9 @@ namespace OpenSim.Framework
{ {
if (requestStream != null) if (requestStream != null)
requestStream.Close(); 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); 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; return deserial;
} }
} }

View File

@ -83,7 +83,7 @@ namespace Flotsam.RegionModules.AssetCache
private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>();
private int m_WaitOnInprogressTimeout = 3000; private int m_WaitOnInprogressTimeout = 3000;
#else #else
private List<string> m_CurrentlyWriting = new List<string>(); private HashSet<string> m_CurrentlyWriting = new HashSet<string>();
#endif #endif
private bool m_FileCacheEnabled = true; private bool m_FileCacheEnabled = true;
@ -261,10 +261,14 @@ namespace Flotsam.RegionModules.AssetCache
try 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)) if (File.Exists(filename))
{ {
File.SetLastAccessTime(filename, DateTime.Now); lock (m_CurrentlyWriting)
{
if (!m_CurrentlyWriting.Contains(filename))
File.SetLastAccessTime(filename, DateTime.Now);
}
} }
else else
{ {

View File

@ -96,6 +96,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
ScenePresence killingAvatar = null; ScenePresence killingAvatar = null;
// string killingAvatarMessage; // string killingAvatarMessage;
// check to see if it is an NPC and just remove it
INPCModule NPCmodule = deadAvatar.Scene.RequestModuleInterface<INPCModule>();
if (NPCmodule != null && NPCmodule.DeleteNPC(deadAvatar.UUID, deadAvatar.Scene))
{
return;
}
if (killerObjectLocalID == 0) if (killerObjectLocalID == 0)
deadAvatarMessage = "You committed suicide!"; deadAvatarMessage = "You committed suicide!";
else else
@ -145,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
catch (InvalidOperationException) catch (InvalidOperationException)
{ } { }
deadAvatar.Health = 100; deadAvatar.setHealthWithUpdate(100.0f);
deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient); deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient);
} }
@ -154,14 +161,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
try try
{ {
ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); 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; avatar.Invulnerable = false;
} }
else else
{ {
avatar.Invulnerable = true; avatar.Invulnerable = true;
if (avatar.Health < 100.0f)
{
avatar.setHealthWithUpdate(100.0f);
}
} }
} }
catch (Exception) catch (Exception)

View File

@ -30,7 +30,6 @@ using System.Collections.Generic;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Capabilities; using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Client; using OpenSim.Framework.Client;
@ -595,7 +594,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 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.Close();
sp.Scene.IncomingCloseAgent(sp.UUID); sp.Scene.IncomingCloseAgent(sp.UUID);
} }

View File

@ -146,6 +146,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
public void Close() public void Close()
{ {
} }
public UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID) public UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID)
{ {
UUID urlcode = UUID.Random(); UUID urlcode = UUID.Random();
@ -175,6 +176,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
uri, uri,
new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); 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 }); engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
} }
@ -217,6 +222,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
uri, uri,
new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); 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 }); 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) foreach (UUID req in data.requests.Keys)
m_RequestMap.Remove(req); m_RequestMap.Remove(req);
m_log.DebugFormat(
"[URL MODULE]: Releasing url {0} for {1} in {2}",
url, data.itemID, data.hostID);
RemoveUrl(data); RemoveUrl(data);
m_UrlMap.Remove(url); m_UrlMap.Remove(url);
} }

View File

@ -1140,9 +1140,19 @@ namespace OpenSim.Region.Framework.Scenes
bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
MakeRootAgent(AbsolutePosition, flying); MakeRootAgent(AbsolutePosition, flying);
ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
if ((m_callbackURI != null) && !m_callbackURI.Equals("")) 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( m_log.DebugFormat(
"[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
client.Name, client.AgentId, m_callbackURI); client.Name, client.AgentId, m_callbackURI);
@ -1151,9 +1161,6 @@ namespace OpenSim.Region.Framework.Scenes
m_callbackURI = null; m_callbackURI = null;
} }
// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
ValidateAndSendAppearanceAndAgentData(); ValidateAndSendAppearanceAndAgentData();
// Create child agents in neighbouring regions // Create child agents in neighbouring regions
@ -1168,7 +1175,6 @@ namespace OpenSim.Region.Framework.Scenes
friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
} }
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); // 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; 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; float starthealth = Health;
uint killerObj = 0; uint killerObj = 0;
SceneObjectPart part = null;
foreach (uint localid in coldata.Keys) foreach (uint localid in coldata.Keys)
{ {
SceneObjectPart part = Scene.GetSceneObjectPart(localid); if (localid == 0)
{
if (part != null && part.ParentGroup.Damage != -1.0f) part = null;
Health -= part.ParentGroup.Damage; }
else 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; Health -= coldata[localid].PenetrationDepth * 5.0f;
} }
if (Health <= 0.0f) if (Health <= 0.0f)
{ {
if (localid != 0) if (localid != 0)
@ -3338,7 +3374,16 @@ namespace OpenSim.Region.Framework.Scenes
ControllingClient.SendHealth(Health); ControllingClient.SendHealth(Health);
} }
if (Health <= 0) if (Health <= 0)
{
m_scene.EventManager.TriggerAvatarKill(killerObj, this); 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);
}
} }
} }

View File

@ -52,6 +52,7 @@ namespace OpenSim.Services.InventoryService
: this(config, "InventoryService") : this(config, "InventoryService")
{ {
} }
public XInventoryService(IConfigSource config, string configName) : base(config) public XInventoryService(IConfigSource config, string configName) : base(config)
{ {
if (configName != string.Empty) if (configName != string.Empty)
@ -363,6 +364,11 @@ namespace OpenSim.Services.InventoryService
// We don't check the principal's ID here // We don't check the principal's ID here
// //
public virtual bool DeleteFolders(UUID principalID, List<UUID> folderIDs) public virtual bool DeleteFolders(UUID principalID, List<UUID> folderIDs)
{
return DeleteFolders(principalID, folderIDs, true);
}
public virtual bool DeleteFolders(UUID principalID, List<UUID> folderIDs, bool onlyIfTrash)
{ {
if (!m_AllowDelete) if (!m_AllowDelete)
return false; return false;
@ -371,11 +377,12 @@ namespace OpenSim.Services.InventoryService
// //
foreach (UUID id in folderIDs) foreach (UUID id in folderIDs)
{ {
if (!ParentIsTrash(id)) if (onlyIfTrash && !ParentIsTrash(id))
continue; continue;
//m_log.InfoFormat("[XINVENTORY SERVICE]: Delete folder {0}", id);
InventoryFolderBase f = new InventoryFolderBase(); InventoryFolderBase f = new InventoryFolderBase();
f.ID = id; f.ID = id;
PurgeFolder(f); PurgeFolder(f, onlyIfTrash);
m_Database.DeleteFolders("folderID", id.ToString()); m_Database.DeleteFolders("folderID", id.ToString());
} }
@ -383,11 +390,16 @@ namespace OpenSim.Services.InventoryService
} }
public virtual bool PurgeFolder(InventoryFolderBase folder) public virtual bool PurgeFolder(InventoryFolderBase folder)
{
return PurgeFolder(folder, true);
}
public virtual bool PurgeFolder(InventoryFolderBase folder, bool onlyIfTrash)
{ {
if (!m_AllowDelete) if (!m_AllowDelete)
return false; return false;
if (!ParentIsTrash(folder.ID)) if (onlyIfTrash && !ParentIsTrash(folder.ID))
return false; return false;
XInventoryFolder[] subFolders = m_Database.GetFolders( XInventoryFolder[] subFolders = m_Database.GetFolders(
@ -396,7 +408,7 @@ namespace OpenSim.Services.InventoryService
foreach (XInventoryFolder x in subFolders) foreach (XInventoryFolder x in subFolders)
{ {
PurgeFolder(ConvertToOpenSim(x)); PurgeFolder(ConvertToOpenSim(x), onlyIfTrash);
m_Database.DeleteFolders("folderID", x.folderID.ToString()); m_Database.DeleteFolders("folderID", x.folderID.ToString());
} }

View File

@ -226,7 +226,8 @@ namespace OpenSim.Services.LLLoginService
public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo, public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo,
GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService, GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService,
string where, string startlocation, Vector3 position, Vector3 lookAt, List<InventoryItemBase> gestures, string message, string where, string startlocation, Vector3 position, Vector3 lookAt, List<InventoryItemBase> 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() : this()
{ {
FillOutInventoryData(invSkel, libService); FillOutInventoryData(invSkel, libService);
@ -255,7 +256,45 @@ namespace OpenSim.Services.LLLoginService
FillOutRegionData(destination); FillOutRegionData(destination);
FillOutSeedCap(aCircuit, destination, clientIP); 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<InventoryFolderBase> invSkel, ILibraryService libService) private void FillOutInventoryData(List<InventoryFolderBase> invSkel, ILibraryService libService)

View File

@ -82,6 +82,8 @@ namespace OpenSim.Services.LLLoginService
protected string m_AllowedClients; protected string m_AllowedClients;
protected string m_DeniedClients; protected string m_DeniedClients;
protected string m_DSTZone;
IConfig m_LoginServerConfig; IConfig m_LoginServerConfig;
// IConfig m_ClientsConfig; // IConfig m_ClientsConfig;
@ -118,6 +120,8 @@ namespace OpenSim.Services.LLLoginService
m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty); m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty);
m_DeniedClients = m_LoginServerConfig.GetString("DeniedClients", 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 // Clean up some of these vars
if (m_MapTileURL != String.Empty) 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}", 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); firstName, lastName, startLocation, clientVersion, channel, clientIP.Address.ToString(), mac, id0);
try try
{ {
// //
@ -416,8 +421,11 @@ namespace OpenSim.Services.LLLoginService
// //
// Finally, fill out the response and return it // Finally, fill out the response and return it
// //
LLLoginResponse response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService, LLLoginResponse response
where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP, m_MapTileURL, m_ProfileURL, m_OpenIDURL, m_SearchURL, m_Currency); = 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."); m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client.");
return response; 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; flags = TeleportFlags.ViaLogin;

View File

@ -275,6 +275,18 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
;AllowedClients = "" ;AllowedClients = ""
;DeniedClients = "" ;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] [MapImageService]
LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService"
; Set this if you want to change the default ; Set this if you want to change the default

View File

@ -250,6 +250,27 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
;AllowedClients = "" ;AllowedClients = ""
;DeniedClients = "" ;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] [MapImageService]
LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService"
; Set this if you want to change the default ; Set this if you want to change the default

View File

@ -95,6 +95,18 @@
WelcomeMessage = "Welcome, Avatar!" 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] [MapImageService]
LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService"
; in minutes ; in minutes