diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 6fb649773e..bba8ff1913 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -116,6 +116,10 @@ namespace OpenSim.Region.ClientStack.Linden m_scene.EventManager.OnRegisterCaps -= RegisterCaps; m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps; + + foreach (Thread t in m_workerThreads) + Watchdog.AbortThread(t.ManagedThreadId); + m_scene = null; } @@ -165,12 +169,6 @@ namespace OpenSim.Region.ClientStack.Linden #endregion - ~WebFetchInvDescModule() - { - foreach (Thread t in m_workerThreads) - Watchdog.AbortThread(t.ManagedThreadId); - } - private class PollServiceInventoryEventArgs : PollServiceEventArgs { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index 322addd805..161f160ba3 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -60,8 +60,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles // The pair of Dictionaries are used to handle the switching of classified ads // by maintaining a cache of classified id to creator id mappings and an interest // count. The entries are removed when the interest count reaches 0. - Dictionary classifiedCache = new Dictionary(); - Dictionary classifiedInterest = new Dictionary(); + Dictionary m_classifiedCache = new Dictionary(); + Dictionary m_classifiedInterest = new Dictionary(); public Scene Scene { @@ -102,7 +102,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles /// /// Gets or sets a value indicating whether this - /// is enabled. + /// is enabled. /// /// /// true if enabled; otherwise, false. @@ -331,16 +331,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles classifieds[cid] = name; - if(!classifiedCache.ContainsKey(cid)) + lock (m_classifiedCache) { - lock(classifiedCache) - classifiedCache.Add(cid,creatorId); - lock(classifiedInterest) - classifiedInterest.Add(cid, 0); - } + if (!m_classifiedCache.ContainsKey(cid)) + { + m_classifiedCache.Add(cid,creatorId); + m_classifiedInterest.Add(cid, 0); + } - lock(classifiedInterest) - classifiedInterest[cid] ++; + m_classifiedInterest[cid]++; + } } remoteClient.SendAvatarClassifiedReply(new UUID(args[0]), classifieds); @@ -352,19 +352,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles UserClassifiedAdd ad = new UserClassifiedAdd(); ad.ClassifiedId = queryClassifiedID; - if(classifiedCache.ContainsKey(queryClassifiedID)) - { - target = classifiedCache[queryClassifiedID]; + lock (m_classifiedCache) + { + if (m_classifiedCache.ContainsKey(queryClassifiedID)) + { + target = m_classifiedCache[queryClassifiedID]; - lock(classifiedInterest) - classifiedInterest[queryClassifiedID] --; + m_classifiedInterest[queryClassifiedID] --; - if(classifiedInterest[queryClassifiedID] == 0) - { - lock(classifiedInterest) - classifiedInterest.Remove(queryClassifiedID); - lock(classifiedCache) - classifiedCache.Remove(queryClassifiedID); + if (m_classifiedInterest[queryClassifiedID] == 0) + { + m_classifiedInterest.Remove(queryClassifiedID); + m_classifiedCache.Remove(queryClassifiedID); + } } } @@ -1339,4 +1339,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } #endregion Web Util } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs index 1e434b9394..2fc8ee361a 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs @@ -1,11 +1,41 @@ -using System; -using System.Collections.Generic; +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Threading; using OpenSim.Framework; using OpenMetaverse; namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory { + /// + /// Cache root and system inventory folders to reduce number of potentially remote inventory calls and associated holdups. + /// public class InventoryCache { private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour @@ -16,8 +46,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory public void Cache(UUID userID, InventoryFolderBase root) { - lock (m_RootFolders) - m_RootFolders.AddOrUpdate(userID, root, CACHE_EXPIRATION_SECONDS); + m_RootFolders.AddOrUpdate(userID, root, CACHE_EXPIRATION_SECONDS); } public InventoryFolderBase GetRootFolder(UUID userID) @@ -31,14 +60,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory public void Cache(UUID userID, AssetType type, InventoryFolderBase folder) { - lock (m_FolderTypes) + Dictionary ff = null; + if (!m_FolderTypes.TryGetValue(userID, out ff)) + { + ff = new Dictionary(); + m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS); + } + + // We need to lock here since two threads could potentially retrieve the same dictionary + // and try to add a folder for that type simultaneously. Dictionary<>.Add() is not described as thread-safe in the SDK + // even if the folders are identical. + lock (ff) { - Dictionary ff = null; - if (!m_FolderTypes.TryGetValue(userID, out ff)) - { - ff = new Dictionary(); - m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS); - } if (!ff.ContainsKey(type)) ff.Add(type, folder); } @@ -50,8 +83,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory if (m_FolderTypes.TryGetValue(userID, out ff)) { InventoryFolderBase f = null; - if (ff.TryGetValue(type, out f)) - return f; + + lock (ff) + { + if (ff.TryGetValue(type, out f)) + return f; + } } return null; @@ -59,8 +96,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory public void Cache(UUID userID, InventoryCollection inv) { - lock (m_Inventories) - m_Inventories.AddOrUpdate(userID, inv, 120); + m_Inventories.AddOrUpdate(userID, inv, 120); } public InventoryCollection GetUserInventory(UUID userID) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 97445269ac..d5f14bf437 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1664,6 +1664,75 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.SetFaceColorAlpha(face, color, null); } + /* + public void llSetContentType(LSL_Key id, LSL_Integer type) + { + m_host.AddScriptLPS(1); + + if (m_UrlModule == null) + return; + + // Make sure the content type is text/plain to start with + m_UrlModule.HttpContentType(new UUID(id), "text/plain"); + + // Is the object owner online and in the region + ScenePresence agent = World.GetScenePresence(m_host.ParentGroup.OwnerID); + if (agent == null || agent.IsChildAgent) + return; // Fail if the owner is not in the same region + + // Is it the embeded browser? + string userAgent = m_UrlModule.GetHttpHeader(new UUID(id), "user-agent"); + if (userAgent.IndexOf("SecondLife") < 0) + return; // Not the embedded browser. Is this check good enough? + + // Use the IP address of the client and check against the request + // seperate logins from the same IP will allow all of them to get non-text/plain as long + // as the owner is in the region. Same as SL! + string logonFromIPAddress = agent.ControllingClient.RemoteEndPoint.Address.ToString(); + string requestFromIPAddress = m_UrlModule.GetHttpHeader(new UUID(id), "remote_addr"); + //m_log.Debug("IP from header='" + requestFromIPAddress + "' IP from endpoint='" + logonFromIPAddress + "'"); + if (requestFromIPAddress == null || requestFromIPAddress.Trim() == "") + return; + if (logonFromIPAddress == null || logonFromIPAddress.Trim() == "") + return; + + // If the request isnt from the same IP address then the request cannot be from the owner + if (!requestFromIPAddress.Trim().Equals(logonFromIPAddress.Trim())) + return; + + switch (type) + { + case ScriptBaseClass.CONTENT_TYPE_HTML: + m_UrlModule.HttpContentType(new UUID(id), "text/html"); + break; + case ScriptBaseClass.CONTENT_TYPE_XML: + m_UrlModule.HttpContentType(new UUID(id), "application/xml"); + break; + case ScriptBaseClass.CONTENT_TYPE_XHTML: + m_UrlModule.HttpContentType(new UUID(id), "application/xhtml+xml"); + break; + case ScriptBaseClass.CONTENT_TYPE_ATOM: + m_UrlModule.HttpContentType(new UUID(id), "application/atom+xml"); + break; + case ScriptBaseClass.CONTENT_TYPE_JSON: + m_UrlModule.HttpContentType(new UUID(id), "application/json"); + break; + case ScriptBaseClass.CONTENT_TYPE_LLSD: + m_UrlModule.HttpContentType(new UUID(id), "application/llsd+xml"); + break; + case ScriptBaseClass.CONTENT_TYPE_FORM: + m_UrlModule.HttpContentType(new UUID(id), "application/x-www-form-urlencoded"); + break; + case ScriptBaseClass.CONTENT_TYPE_RSS: + m_UrlModule.HttpContentType(new UUID(id), "application/rss+xml"); + break; + default: + m_UrlModule.HttpContentType(new UUID(id), "text/plain"); + break; + } + } + */ + public void SetTexGen(SceneObjectPart part, int face,int style) { if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) @@ -5117,13 +5186,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_Rotation(x,y,z,s); } - - // Xantor 29/apr/2008 - // converts a Quaternion to X,Y,Z axis rotations + /// + /// Returns the axis of rotation for a quaternion + /// + /// + /// public LSL_Vector llRot2Axis(LSL_Rotation rot) { m_host.AddScriptLPS(1); - double x, y, z; if (Math.Abs(rot.s) > 1) // normalization needed rot.Normalize(); @@ -8238,7 +8308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return null; string ph = rules.Data[idx++].ToString(); - parentgrp.ScriptSetPhantomStatus(ph.Equals("1")); + part.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); break; @@ -8291,7 +8361,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return null; string temp = rules.Data[idx++].ToString(); - parentgrp.ScriptSetTemporaryStatus(temp.Equals("1")); + part.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); break; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index daf89e575d..2260ec833f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -340,6 +340,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llSetCameraParams(LSL_List rules); void llSetClickAction(int action); void llSetColor(LSL_Vector color, int face); + void llSetContentType(LSL_Key id, LSL_Integer type); void llSetDamage(double damage); void llSetForce(LSL_Vector force, int local); void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local); @@ -434,6 +435,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llSetKeyframedMotion(LSL_List frames, LSL_List options); LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); LSL_List llGetPhysicsMaterial(); - void llSetContentType(LSL_Key id, LSL_Integer content_type); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 6efa73f5e1..15b21ac087 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -361,6 +361,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int HTTP_CUSTOM_HEADER = 5; public const int HTTP_PRAGMA_NO_CACHE = 6; + // llSetContentType + public const int CONTENT_TYPE_TEXT = 0; //text/plain + public const int CONTENT_TYPE_HTML = 1; //text/html + public const int CONTENT_TYPE_XML = 2; //application/xml + public const int CONTENT_TYPE_XHTML = 3; //application/xhtml+xml + public const int CONTENT_TYPE_ATOM = 4; //application/atom+xml + public const int CONTENT_TYPE_JSON = 5; //application/json + public const int CONTENT_TYPE_LLSD = 6; //application/llsd+xml + public const int CONTENT_TYPE_FORM = 7; //application/x-www-form-urlencoded + public const int CONTENT_TYPE_RSS = 8; //application/rss+xml + public const int PRIM_MATERIAL = 2; public const int PRIM_PHYSICS = 3; public const int PRIM_TEMP_ON_REZ = 4; @@ -772,8 +783,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase /// process message parameter as regex /// public const int OS_LISTEN_REGEX_MESSAGE = 0x2; - - public const int CONTENT_TYPE_TEXT = 0; - public const int CONTENT_TYPE_HTML = 1; } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 6f3677c4be..b58686ba43 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -1535,6 +1535,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llSetColor(color, face); } + public void llSetContentType(LSL_Key id, LSL_Integer type) + { + m_LSL_Functions.llSetContentType(id, type); + } + public void llSetDamage(double damage) { m_LSL_Functions.llSetDamage(damage); @@ -2014,10 +2019,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_LSL_Functions.llGetPhysicsMaterial(); } - - public void llSetContentType(LSL_Key id, LSL_Integer content_type) - { - m_LSL_Functions.llSetContentType(id, content_type); - } } } diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index da6c016ae9..057c49207f 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -196,6 +196,7 @@ namespace OpenSim.Services.LLLoginService private BuddyList m_buddyList = null; private string currency; + private string classifiedFee; static LLLoginResponse() { @@ -233,7 +234,7 @@ namespace OpenSim.Services.LLLoginService GridRegion destination, List invSkel, FriendInfo[] friendsList, ILibraryService libService, string where, string startlocation, Vector3 position, Vector3 lookAt, List gestures, string message, GridRegion home, IPEndPoint clientIP, string mapTileURL, string profileURL, string openIDURL, string searchURL, string currency, - string DSTZone, string destinationsURL, string avatarsURL, UUID realID) + string DSTZone, string destinationsURL, string avatarsURL, UUID realID, string classifiedFee) : this() { FillOutInventoryData(invSkel, libService); @@ -258,6 +259,8 @@ namespace OpenSim.Services.LLLoginService SearchURL = searchURL; Currency = currency; + ClassifiedFee = classifiedFee; + FillOutHomeData(pinfo, home); LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z); @@ -472,6 +475,7 @@ namespace OpenSim.Services.LLLoginService searchURL = String.Empty; currency = String.Empty; + ClassifiedFee = "0"; } @@ -565,6 +569,9 @@ namespace OpenSim.Services.LLLoginService // responseData["real_currency"] = currency; responseData["currency"] = currency; } + + if (ClassifiedFee != String.Empty) + responseData["classified_fee"] = ClassifiedFee; responseData["login"] = "true"; @@ -670,6 +677,9 @@ namespace OpenSim.Services.LLLoginService if (searchURL != String.Empty) map["search"] = OSD.FromString(searchURL); + if (ClassifiedFee != String.Empty) + map["classified_fee"] = OSD.FromString(ClassifiedFee); + if (m_buddyList != null) { map["buddy-list"] = ArrayListToOSDArray(m_buddyList.ToArray()); @@ -1081,6 +1091,12 @@ namespace OpenSim.Services.LLLoginService set { currency = value; } } + public string ClassifiedFee + { + get { return classifiedFee; } + set { classifiedFee = value; } + } + public string DestinationsURL { get; set; diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 351c1accaa..81712f6909 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -78,6 +78,7 @@ namespace OpenSim.Services.LLLoginService protected string m_OpenIDURL; protected string m_SearchURL; protected string m_Currency; + protected string m_ClassifiedFee; protected string m_DestinationGuide; protected string m_AvatarPicker; @@ -119,6 +120,7 @@ namespace OpenSim.Services.LLLoginService m_OpenIDURL = m_LoginServerConfig.GetString("OpenIDServerURL", String.Empty); m_SearchURL = m_LoginServerConfig.GetString("SearchURL", string.Empty); m_Currency = m_LoginServerConfig.GetString("Currency", string.Empty); + m_ClassifiedFee = m_LoginServerConfig.GetString("ClassifiedFee", string.Empty); m_DestinationGuide = m_LoginServerConfig.GetString ("DestinationGuide", string.Empty); m_AvatarPicker = m_LoginServerConfig.GetString ("AvatarPicker", string.Empty); @@ -466,7 +468,7 @@ namespace OpenSim.Services.LLLoginService 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_DestinationGuide, m_AvatarPicker, realID); + m_DestinationGuide, m_AvatarPicker, realID, m_ClassifiedFee); m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to {0} {1}", firstName, lastName); diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index d9f1ca1725..466aed2a8b 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -311,6 +311,9 @@ HGAssetServiceConnector = "HGAssetService@8002/OpenSim.Server.Handlers.dll:Asset ;; Ask co-operative viewers to use a different currency name ;Currency = "" + ;; Set minimum fee to publish classified + ; ClassifiedFee = 0 + WelcomeMessage = "Welcome, Avatar!" AllowRemoteSetLoginLevel = "false" diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index 7d6492bf94..da1b43ae9d 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -274,6 +274,9 @@ MapGetServiceConnector = "8002/OpenSim.Server.Handlers.dll:MapGetServiceConnecto ; Ask co-operative viewers to use a different currency name ;Currency = "" + ;; Set minimum fee to publish classified + ; ClassifiedFee = 0 + WelcomeMessage = "Welcome, Avatar!" AllowRemoteSetLoginLevel = "false" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 8c23c41418..6b991a8027 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -115,6 +115,9 @@ ;; Ask co-operative viewers to use a different currency name ;Currency = "" + ;; Set minimum fee to publish classified + ; ClassifiedFee = 0 + ;; Regular expressions for controlling which client versions are accepted/denied. ;; An empty string means nothing is checked. ;;