Merge branch 'master' of /home/opensim/var/repo/opensim
						commit
						90a4d965d9
					
				|  | @ -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 : "", | ||||
|  |  | |||
|  | @ -53,19 +53,36 @@ namespace OpenSim.Framework | |||
|                 LogManager.GetLogger( | ||||
|                 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 | ||||
|         // used for performance and debugging | ||||
|         /// <summary> | ||||
|         /// 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"; | ||||
| 
 | ||||
|         // number of milliseconds a call can take before it is considered | ||||
|         // a "long" call for warning & debugging purposes | ||||
|         public const int LongCallTime = 500; | ||||
|         /// <summary> | ||||
|         /// Number of milliseconds a call can take before it is considered | ||||
|         /// 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 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<TRequest, TResponse>(string verb, | ||||
|                 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); | ||||
| 
 | ||||
|             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); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// 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> | ||||
|         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</exception> | ||||
|         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); | ||||
|             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; | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -83,7 +83,7 @@ namespace Flotsam.RegionModules.AssetCache | |||
|         private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); | ||||
|         private int m_WaitOnInprogressTimeout = 3000; | ||||
| #else | ||||
|         private List<string> m_CurrentlyWriting = new List<string>(); | ||||
|         private HashSet<string> m_CurrentlyWriting = new HashSet<string>(); | ||||
| #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 | ||||
|                 { | ||||
|  |  | |||
|  | @ -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<INPCModule>(); | ||||
|             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) | ||||
|  |  | |||
|  | @ -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); | ||||
|                 } | ||||
|  |  | |||
|  | @ -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); | ||||
|             } | ||||
|  |  | |||
|  | @ -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); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<UUID> folderIDs) | ||||
|         { | ||||
|             return DeleteFolders(principalID, folderIDs, true); | ||||
|         } | ||||
| 
 | ||||
|         public virtual bool DeleteFolders(UUID principalID, List<UUID> 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()); | ||||
|             } | ||||
| 
 | ||||
|  |  | |||
|  | @ -226,7 +226,8 @@ namespace OpenSim.Services.LLLoginService | |||
|         public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo, | ||||
|             GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService, | ||||
|             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() | ||||
|         { | ||||
|             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<InventoryFolderBase> invSkel, ILibraryService libService) | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue