diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs index 73fc22ce4e..57fbbf7893 100644 --- a/OpenSim/Addons/Groups/GroupsModule.cs +++ b/OpenSim/Addons/Groups/GroupsModule.cs @@ -764,7 +764,7 @@ namespace OpenSim.Groups } // check funds - // is there is a money module present ? + // is there a money module present ? IMoneyModule money = scene.RequestModuleInterface(); if (money != null) { @@ -784,7 +784,7 @@ namespace OpenSim.Groups if (money != null) money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, MoneyTransactionType.GroupCreate); - remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); + remoteClient.SendCreateGroupReply(groupID, true, "Group created successfully"); // Update the founder with new group information. SendAgentGroupDataUpdate(remoteClient, false); diff --git a/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesHandler.cs b/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesHandler.cs index 155196c5b6..3e01bbb756 100644 --- a/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesHandler.cs @@ -29,8 +29,6 @@ using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; -using System.Drawing; -using System.Drawing.Imaging; using System.Reflection; using System.IO; using System.Web; @@ -38,12 +36,7 @@ using log4net; using Nini.Config; using OpenMetaverse; using OpenMetaverse.StructuredData; -using OpenMetaverse.Imaging; -using OpenSim.Framework; -using OpenSim.Framework.Capabilities; -using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; -using OpenSim.Region.Framework.Interfaces; using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; using OSDMap = OpenMetaverse.StructuredData.OSDMap; @@ -70,7 +63,6 @@ namespace OpenSim.Capabilities.Handlers NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); string[] ids = query.GetValues("ids"); - if (m_UserManagement == null) { m_log.Error("[GET_DISPLAY_NAMES]: Cannot fetch display names without a user management component"); @@ -78,35 +70,39 @@ namespace OpenSim.Capabilities.Handlers return new byte[0]; } + Dictionary names = m_UserManagement.GetUsersNames(ids); + OSDMap osdReply = new OSDMap(); OSDArray agents = new OSDArray(); osdReply["agents"] = agents; - foreach (string id in ids) + foreach (KeyValuePair kvp in names) { - UUID uuid = UUID.Zero; - if (UUID.TryParse(id, out uuid)) - { - string name = m_UserManagement.GetUserName(uuid); - if (!string.IsNullOrEmpty(name)) - { - string[] parts = name.Split(new char[] {' '}); - OSDMap osdname = new OSDMap(); - // a date that is valid -// osdname["display_name_next_update"] = OSD.FromDate(new DateTime(1970,1,1)); - // but send one that blocks edition, since we actually don't suport this - osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddDays(8)); - osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddMonths(1)); - osdname["display_name"] = OSD.FromString(name); - osdname["legacy_first_name"] = parts[0]; - osdname["legacy_last_name"] = parts[1]; - osdname["username"] = OSD.FromString(name); - osdname["id"] = OSD.FromUUID(uuid); - osdname["is_display_name_default"] = OSD.FromBoolean(true); + if (string.IsNullOrEmpty(kvp.Value)) + continue; + if(kvp.Key == UUID.Zero) + continue; - agents.Add(osdname); - } + string[] parts = kvp.Value.Split(new char[] {' '}); + OSDMap osdname = new OSDMap(); + if(parts[0] == "Unknown") + { + osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddHours(1)); + osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddHours(2)); } + else + { + osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddDays(8)); + osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddMonths(1)); + } + osdname["display_name"] = OSD.FromString(kvp.Value); + osdname["legacy_first_name"] = parts[0]; + osdname["legacy_last_name"] = parts[1]; + osdname["username"] = OSD.FromString(kvp.Value); + osdname["id"] = OSD.FromUUID(kvp.Key); + osdname["is_display_name_default"] = OSD.FromBoolean(true); + + agents.Add(osdname); } // Full content request @@ -116,8 +112,6 @@ namespace OpenSim.Capabilities.Handlers string reply = OSDParser.SerializeLLSDXmlString(osdReply); return System.Text.Encoding.UTF8.GetBytes(reply); - } - } } diff --git a/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesServerConnector.cs b/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesServerConnector.cs index d42de56e9f..8f70c97880 100644 --- a/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesServerConnector.cs @@ -61,8 +61,6 @@ namespace OpenSim.Capabilities.Handlers if (m_UserManagement == null) throw new Exception(String.Format("Failed to load UserManagement from {0}; config is {1}", umService, m_ConfigName)); - - string rurl = serverConfig.GetString("GetTextureRedirectURL"); server.AddStreamHandler( new GetDisplayNamesHandler("/CAPS/agents/", m_UserManagement, "GetDisplayNames", null)); diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 848d574fe3..c046010a3c 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -1256,9 +1256,11 @@ namespace OpenSim.Framework void SendAttachedSoundGainChange(UUID objectID, float gain); void SendNameReply(UUID profileId, string firstname, string lastname); - void SendAlertMessage(string message); + void SendAlertMessage(string message); + void SendAlertMessage(string message, string into); void SendAgentAlertMessage(string message, bool modal); + void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message, string url); /// diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 5250d30483..96b91fffaf 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -382,7 +382,8 @@ namespace OpenSim.Framework public static ulong RegionGridLocToHandle(uint X, uint Y) { - ulong handle = X << 40; // shift to higher half and mult by 256) + ulong handle = X; + handle <<= 40; // shift to higher half and mult by 256) handle |= (Y << 8); // mult by 256) return handle; } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 19619c1e1a..60bfaa518b 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -41,6 +41,7 @@ using log4net; using OpenSim.Framework; using OpenSim.Framework.Capabilities; using OpenSim.Region.Framework; +using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Framework.Servers; @@ -89,23 +90,11 @@ namespace OpenSim.Region.ClientStack.Linden LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_Scene; + private UUID m_AgentID; private Caps m_HostCapsObj; private ModelCost m_ModelCost; - private static readonly string m_requestPath = "0000/"; - // private static readonly string m_mapLayerPath = "0001/"; - private static readonly string m_newInventory = "0002/"; - //private static readonly string m_requestTexture = "0003/"; - private static readonly string m_notecardUpdatePath = "0004/"; - private static readonly string m_notecardTaskUpdatePath = "0005/"; - // private static readonly string m_fetchInventoryPath = "0006/"; - private static readonly string m_copyFromNotecardPath = "0007/"; // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. - private static readonly string m_getObjectPhysicsDataPath = "0101/"; - private static readonly string m_getObjectCostPath = "0102/"; - private static readonly string m_ResourceCostSelectedPath = "0103/"; - private static readonly string m_UpdateAgentInformationPath = "0500/"; - private static readonly string m_animSetTaskUpdatePath = "0260/"; // These are callbacks which will be setup by the scene so that we can update scene data when we // receive capability calls @@ -134,6 +123,9 @@ namespace OpenSim.Region.ClientStack.Linden private float m_PrimScaleMin = 0.001f; + private bool m_AllowCapHomeLocation = true; + private bool m_AllowCapGroupMemberData = true; + private enum FileAgentInventoryState : int { idle = 0, @@ -143,27 +135,16 @@ namespace OpenSim.Region.ClientStack.Linden } private FileAgentInventoryState m_FileAgentInventoryState = FileAgentInventoryState.idle; - public BunchOfCaps(Scene scene, Caps caps) + public BunchOfCaps(Scene scene, UUID agentID, Caps caps) { m_Scene = scene; + m_AgentID = agentID; m_HostCapsObj = caps; // create a model upload cost provider - m_ModelCost = new ModelCost(); - // tell it about scene object limits - m_ModelCost.NonPhysicalPrimScaleMax = m_Scene.m_maxNonphys; - m_ModelCost.PhysicalPrimScaleMax = m_Scene.m_maxPhys; - m_ModelCost.ObjectLinkedPartsMax = m_Scene.m_linksetCapacity; - -// m_ModelCost.ObjectLinkedPartsMax = ?? -// m_ModelCost.PrimScaleMin = ?? - + m_ModelCost = new ModelCost(scene); + m_PrimScaleMin = m_ModelCost.PrimScaleMin; - float modelTextureUploadFactor = m_ModelCost.ModelTextureCostFactor; - float modelUploadFactor = m_ModelCost.ModelMeshCostFactor; - float modelMinUploadCostFactor = m_ModelCost.ModelMinCostFactor; - float modelPrimCreationCost = m_ModelCost.primCreationCost; - float modelMeshByteCost = m_ModelCost.bytecost; IConfigSource config = m_Scene.Config; if (config != null) @@ -183,12 +164,7 @@ namespace OpenSim.Region.ClientStack.Linden IConfig EconomyConfig = config.Configs["Economy"]; if (EconomyConfig != null) { - modelUploadFactor = EconomyConfig.GetFloat("MeshModelUploadCostFactor", modelUploadFactor); - modelTextureUploadFactor = EconomyConfig.GetFloat("MeshModelUploadTextureCostFactor", modelTextureUploadFactor); - modelMinUploadCostFactor = EconomyConfig.GetFloat("MeshModelMinCostFactor", modelMinUploadCostFactor); - // next 2 are normalized so final cost is afected by modelUploadFactor above and normal cost - modelPrimCreationCost = EconomyConfig.GetFloat("ModelPrimCreationCost", modelPrimCreationCost); - modelMeshByteCost = EconomyConfig.GetFloat("ModelMeshByteCost", modelMeshByteCost); + m_ModelCost.Econfig(EconomyConfig); m_enableModelUploadTextureToInventory = EconomyConfig.GetBoolean("MeshModelAllowTextureToInventory", m_enableModelUploadTextureToInventory); @@ -203,12 +179,18 @@ namespace OpenSim.Region.ClientStack.Linden if (id != null) m_testAssetsCreatorID = id; } + } - m_ModelCost.ModelMeshCostFactor = modelUploadFactor; - m_ModelCost.ModelTextureCostFactor = modelTextureUploadFactor; - m_ModelCost.ModelMinCostFactor = modelMinUploadCostFactor; - m_ModelCost.primCreationCost = modelPrimCreationCost; - m_ModelCost.bytecost = modelMeshByteCost; + IConfig CapsConfig = config.Configs["ClientStack.LindenCaps"]; + if (CapsConfig != null) + { + string homeLocationUrl = CapsConfig.GetString("Cap_HomeLocation", "localhost"); + if(homeLocationUrl == String.Empty) + m_AllowCapHomeLocation = false; + + string GroupMemberDataUrl = CapsConfig.GetString("Cap_GroupMemberData", "localhost"); + if(GroupMemberDataUrl == String.Empty) + m_AllowCapGroupMemberData = false; } } @@ -225,51 +207,71 @@ namespace OpenSim.Region.ClientStack.Linden m_FileAgentInventoryState = FileAgentInventoryState.idle; } + public string GetNewCapPath() + { + return "/CAPS/" + UUID.Random(); + } + /// /// Register a bunch of CAPS http service handlers /// public void RegisterHandlers() { - string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; + // this path is also defined elsewhere so keeping it + string seedcapsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath +"0000/"; - RegisterRegionServiceHandlers(capsBase); - RegisterInventoryServiceHandlers(capsBase); + // the root of all evil path needs to be capsBase + m_requestPath + m_HostCapsObj.RegisterHandler( + "SEED", new RestStreamHandler("POST", seedcapsBase, SeedCapRequest, "SEED", null)); + +// m_log.DebugFormat( +// "[CAPS]: Registered seed capability {0} for {1}", seedcapsBase, m_HostCapsObj.AgentID); + + RegisterRegionServiceHandlers(); + RegisterInventoryServiceHandlers(); } - public void RegisterRegionServiceHandlers(string capsBase) + public void RegisterRegionServiceHandlers() { try { - // the root of all evil - m_HostCapsObj.RegisterHandler( - "SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null)); - -// m_log.DebugFormat( -// "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID); - //m_capsHandlers["MapLayer"] = // new LLSDStreamhandler("POST", - // capsBase + m_mapLayerPath, + // GetNewCapPath(), // GetMapLayer); - IRequestHandler getObjectPhysicsDataHandler - = new RestStreamHandler( - "POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData, "GetObjectPhysicsData", null); + IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler( + "POST", GetNewCapPath(), GetObjectPhysicsData, "GetObjectPhysicsData", null); m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler); - IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost); + IRequestHandler getObjectCostHandler = new RestStreamHandler( + "POST", GetNewCapPath(), GetObjectCost, "GetObjectCost", null ); m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler); - IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler("POST", capsBase + m_ResourceCostSelectedPath, ResourceCostSelected); + + IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler( + "POST", GetNewCapPath(), ResourceCostSelected, "ResourceCostSelected", null); m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler); - - - IRequestHandler req - = new RestStreamHandler( - "POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory, "UpdateScript", null); + IRequestHandler req = new RestStreamHandler( + "POST", GetNewCapPath(), ScriptTaskInventory, "UpdateScript", null); m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req); m_HostCapsObj.RegisterHandler("UpdateScriptTask", req); + if(m_AllowCapHomeLocation) + { + IRequestHandler HomeLocationHandler = new RestStreamHandler( + "POST", GetNewCapPath(), HomeLocation, "HomeLocation", null); + m_HostCapsObj.RegisterHandler("HomeLocation", HomeLocationHandler); + } + + if(m_AllowCapGroupMemberData) + { + IRequestHandler GroupMemberDataHandler = new RestStreamHandler( + "POST", GetNewCapPath(), GroupMemberData, "GroupMemberData", null); + m_HostCapsObj.RegisterHandler("GroupMemberData", GroupMemberDataHandler); + } + + // IRequestHandler animSetRequestHandler // = new RestStreamHandler( // "POST", capsBase + m_animSetTaskUpdatePath, AnimSetTaskInventory, "UpdateScript", null); @@ -282,65 +284,29 @@ namespace OpenSim.Region.ClientStack.Linden } } - public void RegisterInventoryServiceHandlers(string capsBase) + public void RegisterInventoryServiceHandlers() { try { - m_HostCapsObj.RegisterHandler( - "NewFileAgentInventory", + m_HostCapsObj.RegisterHandler("NewFileAgentInventory", new LLSDStreamhandler( - "POST", - capsBase + m_newInventory, - NewAgentInventoryRequest, - "NewFileAgentInventory", - null)); - - IRequestHandler req - = new RestStreamHandler( - "POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory, "Update*", null); + "POST", GetNewCapPath(), NewAgentInventoryRequest, "NewFileAgentInventory", null)); + IRequestHandler req = new RestStreamHandler( + "POST", GetNewCapPath(), NoteCardAgentInventory, "Update*", null); m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); m_HostCapsObj.RegisterHandler("UpdateAnimSetAgentInventory", req); m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); - - - IRequestHandler UpdateAgentInformationHandler - = new RestStreamHandler( - "POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation, "UpdateAgentInformation", null); + IRequestHandler UpdateAgentInformationHandler = new RestStreamHandler( + "POST", GetNewCapPath(), UpdateAgentInformation, "UpdateAgentInformation", null); m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler); - m_HostCapsObj.RegisterHandler( - "CopyInventoryFromNotecard", - new RestStreamHandler( - "POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard, "CopyInventoryFromNotecard", null)); + IRequestHandler CopyInventoryFromNotecardHandler = new RestStreamHandler( + "POST", GetNewCapPath(), CopyInventoryFromNotecard, "CopyInventoryFromNotecard", null); + m_HostCapsObj.RegisterHandler("CopyInventoryFromNotecard", CopyInventoryFromNotecardHandler); - // As of RC 1.22.9 of the Linden client this is - // supported - - //m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest); - - // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and - // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires - // enhancements (probably filling out the folder part of the LLSD reply) to our CAPS service, - // but when I went on the Linden grid, the - // simulators I visited (version 1.21) were, surprisingly, no longer supplying this capability. Instead, - // the 1.19.1.4 client appeared to be happily flowing inventory data over UDP - // - // This is very probably just a temporary measure - once the CAPS service appears again on the Linden grid - // we will be - // able to get the data we need to implement the necessary part of the protocol to fix the issue above. - // m_capsHandlers["FetchInventoryDescendents"] = - // new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryRequest); - - // m_capsHandlers["FetchInventoryDescendents"] = - // new LLSDStreamhandler("POST", - // capsBase + m_fetchInventory, - // FetchInventory)); - // m_capsHandlers["RequestTextureDownload"] = new RestStreamHandler("POST", - // capsBase + m_requestTexture, - // RequestTexture); } catch (Exception e) { @@ -409,30 +375,28 @@ namespace OpenSim.Region.ClientStack.Linden LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate(); LLSDHelpers.DeserialiseOSDMap(hash, llsdUpdateRequest); - string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; - string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + string uploaderPath = GetNewCapPath(); TaskInventoryScriptUpdater uploader = new TaskInventoryScriptUpdater( llsdUpdateRequest.item_id, llsdUpdateRequest.task_id, llsdUpdateRequest.is_script_running, - capsBase + uploaderPath, + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); uploader.OnUpLoad += TaskScriptUpdated; m_HostCapsObj.HttpListener.AddStreamHandler( new BinaryStreamHandler( - "POST", capsBase + uploaderPath, uploader.uploaderCaps, "TaskInventoryScriptUpdater", null)); + "POST", uploaderPath, uploader.uploaderCaps, "TaskInventoryScriptUpdater", null)); string protocol = "http://"; if (m_HostCapsObj.SSLCaps) protocol = "https://"; - string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase + - uploaderPath; + string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + uploaderPath; LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); uploadResponse.uploader = uploaderURL; @@ -653,11 +617,10 @@ namespace OpenSim.Region.ClientStack.Linden } string assetDes = llsdRequest.description; - string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; UUID newAsset = UUID.Random(); UUID newInvItem = UUID.Random(); UUID parentFolder = llsdRequest.folder_id; - string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + string uploaderPath = GetNewCapPath(); UUID texturesFolder = UUID.Zero; if(!IsAtestUpload && m_enableModelUploadTextureToInventory) @@ -665,26 +628,23 @@ namespace OpenSim.Region.ClientStack.Linden AssetUploader uploader = new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, - llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile, cost, + llsdRequest.asset_type, uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile, cost, texturesFolder, nreqtextures, nreqmeshs, nreqinstances, IsAtestUpload, llsdRequest.next_owner_mask, llsdRequest.group_mask, llsdRequest.everyone_mask); m_HostCapsObj.HttpListener.AddStreamHandler( new BinaryStreamHandler( "POST", - capsBase + uploaderPath, + uploaderPath, uploader.uploaderCaps, "NewAgentInventoryRequest", m_HostCapsObj.AgentID.ToString())); string protocol = "http://"; - if (m_HostCapsObj.SSLCaps) protocol = "https://"; - string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase + - uploaderPath; - + string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + uploaderPath; LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); uploadResponse.uploader = uploaderURL; @@ -1313,24 +1273,22 @@ namespace OpenSim.Region.ClientStack.Linden LLSDItemUpdate llsdRequest = new LLSDItemUpdate(); LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest); - string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; - string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + string uploaderPath = GetNewCapPath(); ItemUpdater uploader = - new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); + new ItemUpdater(llsdRequest.item_id, uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); uploader.OnUpLoad += ItemUpdated; m_HostCapsObj.HttpListener.AddStreamHandler( new BinaryStreamHandler( - "POST", capsBase + uploaderPath, uploader.uploaderCaps, "NoteCardAgentInventory", null)); + "POST", uploaderPath, uploader.uploaderCaps, "NoteCardAgentInventory", null)); string protocol = "http://"; if (m_HostCapsObj.SSLCaps) protocol = "https://"; - string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase + - uploaderPath; + string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + uploaderPath; LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); uploadResponse.uploader = uploaderURL; @@ -1576,6 +1534,266 @@ namespace OpenSim.Region.ClientStack.Linden string response = OSDParser.SerializeLLSDXmlString(resp); return response; } + + public bool OSDMapTOVector3(OSDMap map, out Vector3 v) + { + v = Vector3.Zero; + if(!map.ContainsKey("X")) + return false; + if(!map.ContainsKey("Y")) + return false; + if(!map.ContainsKey("Z")) + return false; + v.X = (float)map["X"].AsReal(); + v.Y = (float)map["Y"].AsReal(); + v.Z = (float)map["Z"].AsReal(); + return true; + } + + public string HomeLocation(string request, string path, string param, IOSHttpRequest httpRequest, + IOSHttpResponse httpResponse) + { + OSDMap resp = new OSDMap(); + + resp["success"] = "false"; + + + bool fail = true; + string message = "Set Home request failed"; + int locationID = 1; + Vector3 pos = Vector3.Zero; + Vector3 lookAt = Vector3.Zero; + + IClientAPI client = null; + ScenePresence sp; + + while(true) + { + if(m_Scene.GridUserService == null) + break; + + if(m_Scene.UserManagementModule == null) + break; + + m_Scene.TryGetScenePresence(m_AgentID, out sp); + if(sp == null || sp.IsChildAgent || sp.IsDeleted || sp.IsInTransit) + break; + + client = sp.ControllingClient; + + if(!m_Scene.UserManagementModule.IsLocalGridUser(m_AgentID)) + break; + + OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); + if(!req.ContainsKey("HomeLocation")) + break; + + OSDMap HLocation = (OSDMap)req["HomeLocation"]; + if(!HLocation.ContainsKey("LocationPos")) + break; + if(!HLocation.ContainsKey("LocationLookAt")) + break; + + locationID = HLocation["LocationId"].AsInteger(); + + if(!OSDMapTOVector3((OSDMap)HLocation["LocationPos"], out pos)) + break; + + if(!OSDMapTOVector3((OSDMap)HLocation["LocationLookAt"], out lookAt)) + break; + + ILandObject land = m_Scene.LandChannel.GetLandObject(pos); + if(land == null) + break; + + ulong gpowers = client.GetGroupPowers(land.LandData.GroupID); + SceneObjectGroup telehub = null; + if (m_Scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero) + // Does the telehub exist in the scene? + telehub = m_Scene.GetSceneObjectGroup(m_Scene.RegionInfo.RegionSettings.TelehubObject); + + if (!m_Scene.Permissions.IsAdministrator(m_AgentID) && // (a) gods and land managers can set home + !m_Scene.Permissions.IsGod(m_AgentID) && + m_AgentID != land.LandData.OwnerID && // (b) land owners can set home + // (c) members of the land-associated group in roles that can set home + ((gpowers & (ulong)GroupPowers.AllowSetHome) != (ulong)GroupPowers.AllowSetHome) && + // (d) parcels with telehubs can be the home of anyone + (telehub == null || !land.ContainsPoint((int)telehub.AbsolutePosition.X, (int)telehub.AbsolutePosition.Y))) + { + message = "You are not allowed to set your home location in this parcel."; + break; + } + + string userId; + UUID test; + if (!m_Scene.UserManagementModule.GetUserUUI(m_AgentID, out userId)) + { + message = "Set Home request failed. (User Lookup)"; + break; + } + + if (!UUID.TryParse(userId, out test)) + { + message = "Set Home request failed. (HG visitor)"; + break; + } + + if (m_Scene.GridUserService.SetHome(userId, land.RegionUUID, pos, lookAt)) + fail = false; + + break; + } + + string response; + + if(fail) + { + if(client != null) + client.SendAlertMessage(message, "HomePositionSet"); + response = OSDParser.SerializeLLSDXmlString(resp); + return response; + } + + // so its http but still needs a udp reply to inform user? crap :p + if(client != null) + client.SendAlertMessage("Home position set.","HomePositionSet"); + + resp["success"] = "true"; + OSDMap homeloc = new OSDMap(); + OSDMap homelocpos = new OSDMap(); + // for some odd reason viewers send pos as reals but read as integer + homelocpos["X"] = new OSDReal(pos.X); + homelocpos["Y"] = new OSDReal(pos.Y); + homelocpos["Z"] = new OSDReal(pos.Z); + homeloc["LocationPos"] = homelocpos; + + resp["HomeLocation"] = homeloc; + + response = OSDParser.SerializeLLSDXmlString(resp); + return response; + } + + private static int CompareRolesByMembersDesc(GroupRolesData x, GroupRolesData y) + { + return -(x.Members.CompareTo(y.Members)); + } + + public string GroupMemberData(string request, string path, string param, IOSHttpRequest httpRequest, + IOSHttpResponse httpResponse) + { + OSDMap resp = new OSDMap(); + + string response; + + bool fail = true; + IClientAPI client = null; + ScenePresence sp; + IGroupsModule m_GroupsModule; + UUID groupID = UUID.Zero; + + while(true) + { + m_GroupsModule = m_Scene.RequestModuleInterface(); + if(m_GroupsModule == null) + break; + + m_Scene.TryGetScenePresence(m_AgentID, out sp); + if(sp == null || sp.IsChildAgent || sp.IsDeleted || sp.IsInTransit) + break; + + client = sp.ControllingClient; + + OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); + if(!req.ContainsKey("group_id")) + break; + + groupID = req["group_id"].AsUUID(); + if(groupID == UUID.Zero) + break; + + List roles = m_GroupsModule.GroupRoleDataRequest(client, groupID); + if(roles == null || roles.Count == 0) + break; + + List members = m_GroupsModule.GroupMembersRequest(client, groupID); + if(members == null || members.Count == 0) + break; + + int memberCount = members.Count; + + Dictionary titles = new Dictionary(); + int i = 0; + + ulong defaultPowers = 0; + + + // build titles array and index + roles.Sort(CompareRolesByMembersDesc); + + OSDArray osdtitles = new OSDArray(); + foreach(GroupRolesData grd in roles) + { + if(grd.Title == null) + continue; + string title = grd.Title; + if(i==0) + defaultPowers = grd.Powers; + + if(!titles.ContainsKey(title)) + { + titles[title] = i++; + osdtitles.Add(new OSDString(title)); + } + } + + if(titles.Count == 0) + break; + + OSDMap osdmembers = new OSDMap(); + foreach(GroupMembersData gmd in members) + { + OSDMap m = new OSDMap(); + if(gmd.OnlineStatus != null && gmd.OnlineStatus != "") + m["last_login"] = new OSDString(gmd.OnlineStatus); + if(gmd.AgentPowers != defaultPowers) + m["powers"] = new OSDString((gmd.AgentPowers).ToString("X")); + if(gmd.Title != null && titles.ContainsKey(gmd.Title) && titles[gmd.Title] != 0) + m["title"] = new OSDInteger(titles[gmd.Title]); + if(gmd.IsOwner) + m["owner"] = new OSDString("true"); + if(gmd.Contribution != 0) + m["donated_square_meters"] = new OSDInteger(gmd.Contribution); + + osdmembers[(gmd.AgentID).ToString()] = m; + } + + OSDMap osddefaults = new OSDMap(); + osddefaults["default_powers"] = new OSDString(defaultPowers.ToString("X")); + + resp["group_id"] = new OSDUUID(groupID); + resp["agent_id"] = new OSDUUID(m_AgentID); + resp["member_count"] = new OSDInteger(memberCount); + resp["defaults"] = osddefaults; + resp["titles"] = osdtitles; + resp["members"] = osdmembers; + + fail = false; + break; + } + + if(fail) + { + resp["group_id"] = new OSDUUID(groupID); + resp["agent_id"] = new OSDUUID(m_AgentID); + resp["member_count"] = new OSDInteger(0); + resp["defaults"] = new OSDMap(); + resp["titles"] = new OSDArray(); + resp["members"] = new OSDMap(); + } + + response = OSDParser.SerializeLLSDXmlString(resp); + return response; + } } public class AssetUploader diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs index c241075b52..5b4e0da88c 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs @@ -84,7 +84,7 @@ namespace OpenSim.Region.ClientStack.Linden private void OnRegisterCaps(UUID agentID, Caps caps) { - new BunchOfCaps(m_Scene, caps); + new BunchOfCaps(m_Scene, agentID, caps); } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs index 29bde6c063..fb22694bd2 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs @@ -45,6 +45,8 @@ using ComponentAce.Compression.Libs.zlib; using OSDArray = OpenMetaverse.StructuredData.OSDArray; using OSDMap = OpenMetaverse.StructuredData.OSDMap; +using Nini.Config; + namespace OpenSim.Region.ClientStack.Linden { public struct ModelPrimLimits @@ -100,6 +102,25 @@ namespace OpenSim.Region.ClientStack.Linden public float PhysicalPrimScaleMax = 10f; public int ObjectLinkedPartsMax = 512; + + public ModelCost(Scene scene) + { + PrimScaleMin = scene.m_minNonphys; + NonPhysicalPrimScaleMax = scene.m_maxNonphys; + PhysicalPrimScaleMax = scene.m_maxPhys; + ObjectLinkedPartsMax = scene.m_linksetCapacity; + } + + public void Econfig(IConfig EconomyConfig) + { + ModelMeshCostFactor = EconomyConfig.GetFloat("MeshModelUploadCostFactor", ModelMeshCostFactor); + ModelTextureCostFactor = EconomyConfig.GetFloat("MeshModelUploadTextureCostFactor", ModelTextureCostFactor); + ModelMinCostFactor = EconomyConfig.GetFloat("MeshModelMinCostFactor", ModelMinCostFactor); + // next 2 are normalized so final cost is afected by modelUploadFactor above and normal cost + primCreationCost = EconomyConfig.GetFloat("ModelPrimCreationCost", primCreationCost); + bytecost = EconomyConfig.GetFloat("ModelMeshByteCost", bytecost); + } + // storage for a single mesh asset cost parameters private class ameshCostParam { diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index f3acacd649..11e8075f40 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -577,6 +577,13 @@ namespace OpenSim.Region.ClientStack.Linden //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item); } + public void ChatterBoxForceClose(UUID toAgent, UUID sessionID, string reason) + { + OSD item = EventQueueHelper.ChatterBoxForceClose(sessionID, reason); + + Enqueue(item, toAgent); + } + public void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID) { OSD item = EventQueueHelper.ParcelProperties(parcelPropertiesMessage); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs index d552914e81..5e0bd71797 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs @@ -342,6 +342,18 @@ namespace OpenSim.Region.ClientStack.Linden return chatterBoxSessionAgentListUpdates; } + public static OSD ChatterBoxForceClose(UUID sessionID, string reason) + { + OSDMap body = new OSDMap(2); + body.Add("session_id", new OSDUUID(sessionID)); + body.Add("reason", new OSDString(reason)); + + OSDMap chatterBoxForceClose = new OSDMap(2); + chatterBoxForceClose.Add("message", new OSDString("ForceCloseChatterBoxSession")); + chatterBoxForceClose.Add("body", body); + return chatterBoxForceClose; + } + public static OSD GroupMembershipData(UUID receiverAgent, GroupMembershipData[] data) { OSDArray AgentData = new OSDArray(1); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 6beb9b42a9..f580e5a641 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -1711,11 +1711,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendKillObject(List localIDs) { - // think we do need this // foreach (uint id in localIDs) // m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle); - // remove pending entities + // remove pending entities to reduce looping chances. lock (m_entityProps.SyncRoot) m_entityProps.Remove(localIDs); lock (m_entityUpdates.SyncRoot) @@ -2412,6 +2411,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(alertPack, ThrottleOutPacketType.Task); } + public void SendAlertMessage(string message, string info) + { + AlertMessagePacket alertPack = (AlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AlertMessage); + alertPack.AlertData = new AlertMessagePacket.AlertDataBlock(); + alertPack.AlertData.Message = Util.StringToBytes256(message); + alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[1]; + alertPack.AlertInfo[0] = new AlertMessagePacket.AlertInfoBlock(); + alertPack.AlertInfo[0].Message = Util.StringToBytes256(info); + alertPack.AlertInfo[0].ExtraParams = new Byte[0]; + OutPacket(alertPack, ThrottleOutPacketType.Task); + } + /// /// Send an agent alert message to the client. /// @@ -4007,7 +4018,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP bool doCulling = m_scene.ObjectsCullingByDistance; float cullingrange = 64.0f; HashSet GroupsNeedFullUpdate = new HashSet(); - List kills = new List(); // Vector3 mycamera = Vector3.Zero; Vector3 mypos = Vector3.Zero; ScenePresence mysp = (ScenePresence)SceneAgent; @@ -4047,8 +4057,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Don't send updates for objects that have been marked deleted. // Instead send another kill object, because the first one may have gotten // into a race condition - if (!m_killRecord.Contains(grp.LocalId)) + if (part == grp.RootPart && !m_killRecord.Contains(grp.LocalId)) + { m_killRecord.Add(grp.LocalId); + maxUpdatesBytes -= 30; + } continue; } @@ -4336,16 +4349,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_killRecord.Clear(); } - if (kills.Count > 0) - { - foreach(SceneObjectGroup grp in kills) - { - foreach(SceneObjectPart p in grp.Parts) - SendEntityUpdate(p,PrimUpdateFlags.Kill); - } - kills.Clear(); - } - if(GroupsNeedFullUpdate.Count > 0) { foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) @@ -4471,12 +4474,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (kills.Count > 0) { + List partIDs = new List(); foreach(SceneObjectGroup grp in kills) { + SendEntityUpdate(grp.RootPart,PrimUpdateFlags.Kill); foreach(SceneObjectPart p in grp.Parts) - SendEntityUpdate(p,PrimUpdateFlags.Kill); + { + if(p != grp.RootPart) + partIDs.Add(p.LocalId); + } } kills.Clear(); + if(partIDs.Count > 0) + { + lock (m_entityProps.SyncRoot) + m_entityProps.Remove(partIDs); + lock (m_entityUpdates.SyncRoot) + m_entityUpdates.Remove(partIDs); + } } if(GroupsNeedFullUpdate.Count > 0) @@ -11418,12 +11433,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_GroupsModule.GroupMembersRequest(this, groupMembersRequestPacket.GroupData.GroupID); int memberCount = members.Count; - - while (true) + int indx = 0; + while (indx < memberCount) { - int blockCount = members.Count; - if (blockCount > 40) - blockCount = 40; + int blockCount = memberCount - indx; + if (blockCount > 25) + blockCount = 25; GroupMembersReplyPacket groupMembersReply = (GroupMembersReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupMembersReply); @@ -11444,8 +11459,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < blockCount; i++) { - GroupMembersData m = members[0]; - members.RemoveAt(0); + GroupMembersData m = members[indx++]; groupMembersReply.MemberData[i] = new GroupMembersReplyPacket.MemberDataBlock(); @@ -11463,8 +11477,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m.IsOwner; } OutPacket(groupMembersReply, ThrottleOutPacketType.Task); - if (members.Count == 0) - return true; } } return true; diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index b72593cad9..eabeaf1133 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -481,6 +481,151 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement return user.FirstName + " " + user.LastName; } + public virtual Dictionary GetUsersNames(string[] ids) + { + Dictionary ret = new Dictionary(); + if(m_Scenes.Count <= 0) + return ret; + + List missing = new List(); + Dictionary untried = new Dictionary(); + + // look in cache + UserData userdata = new UserData(); + + UUID uuid = UUID.Zero; + foreach(string id in ids) + { + if(UUID.TryParse(id, out uuid)) + { + lock (m_UserCache) + { + if (m_UserCache.TryGetValue(uuid, out userdata) && + userdata.FirstName != "Unknown" && userdata.FirstName != string.Empty) + { + string name = userdata.FirstName + " " + userdata.LastName; + + if(userdata.HasGridUserTried) + ret[uuid] = name; + else + { + untried[uuid] = name; + missing.Add(id); + } + } + else + missing.Add(id); + } + } + } + + if(missing.Count == 0) + return ret; + + // try user account service + List accounts = m_Scenes[0].UserAccountService.GetUserAccounts( + m_Scenes[0].RegionInfo.ScopeID, missing); + + if(accounts.Count != 0) + { + foreach(UserAccount uac in accounts) + { + if(uac != null) + { + string name = uac.FirstName + " " + uac.LastName; + ret[uac.PrincipalID] = name; + missing.Remove(uac.PrincipalID.ToString()); // slowww + untried.Remove(uac.PrincipalID); + + userdata = new UserData(); + userdata.Id = uac.PrincipalID; + userdata.FirstName = uac.FirstName; + userdata.LastName = uac.LastName; + userdata.HomeURL = string.Empty; + userdata.IsUnknownUser = false; + userdata.HasGridUserTried = true; + lock (m_UserCache) + m_UserCache[uac.PrincipalID] = userdata; + } + } + } + + if (missing.Count == 0 || m_Scenes[0].GridUserService == null) + return ret; + + // try grid user service + + GridUserInfo[] pinfos = m_Scenes[0].GridUserService.GetGridUserInfo(missing.ToArray()); + if(pinfos.Length > 0) + { + foreach(GridUserInfo uInfo in pinfos) + { + if (uInfo != null) + { + string url, first, last, tmp; + + if(uInfo.UserID.Length <= 36) + continue; + + if (Util.ParseUniversalUserIdentifier(uInfo.UserID, out uuid, out url, out first, out last, out tmp)) + { + if (url != string.Empty) + { + try + { + userdata = new UserData(); + userdata.FirstName = first.Replace(" ", ".") + "." + last.Replace(" ", "."); + userdata.LastName = "@" + new Uri(url).Authority; + userdata.Id = uuid; + userdata.HomeURL = url; + userdata.IsUnknownUser = false; + userdata.HasGridUserTried = true; + lock (m_UserCache) + m_UserCache[uuid] = userdata; + + string name = userdata.FirstName + " " + userdata.LastName; + ret[uuid] = name; + missing.Remove(uuid.ToString()); + untried.Remove(uuid); + } + catch + { + } + } + } + } + } + } + + // add the untried in cache that still failed + if(untried.Count > 0) + { + foreach(KeyValuePair kvp in untried) + { + ret[kvp.Key] = kvp.Value; + missing.Remove((kvp.Key).ToString()); + } + } + + // add the UMMthings ( not sure we should) + if(missing.Count > 0) + { + foreach(string id in missing) + { + if(UUID.TryParse(id, out uuid) && uuid != UUID.Zero) + { + if (m_Scenes[0].LibraryService != null && + (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) + ret[uuid] = "Mr OpenSim"; + else + ret[uuid] = "Unknown UserUMMAU43"; + } + } + } + + return ret; + } + public virtual string GetUserHomeURL(UUID userID) { UserData user; @@ -584,7 +729,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement else { userdata = new UserData(); - userdata.HasGridUserTried = false; userdata.Id = uuid; userdata.FirstName = "Unknown"; userdata.LastName = "UserUMMAU42"; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs index 863560b5e2..c48186fdab 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs @@ -203,21 +203,22 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory void OnClientClosed(UUID clientID, Scene scene) { - if (m_InventoryURLs.ContainsKey(clientID)) // if it's in cache + ScenePresence sp = null; + foreach (Scene s in m_Scenes) { - ScenePresence sp = null; - foreach (Scene s in m_Scenes) + s.TryGetScenePresence(clientID, out sp); + if ((sp != null) && !sp.IsChildAgent && (s != scene)) { - s.TryGetScenePresence(clientID, out sp); - if ((sp != null) && !sp.IsChildAgent && (s != scene)) - { - m_log.DebugFormat("[INVENTORY CACHE]: OnClientClosed in {0}, but user {1} still in sim. Keeping inventoryURL in cache", + m_log.DebugFormat("[INVENTORY CACHE]: OnClientClosed in {0}, but user {1} still in sim. Keeping inventoryURL in cache", scene.RegionInfo.RegionName, clientID); return; - } } - DropInventoryServiceURL(clientID); } + + if (m_InventoryURLs.ContainsKey(clientID)) // if it's in cache + DropInventoryServiceURL(clientID); + + m_Cache.RemoveAll(clientID); } /// diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs index 3195e6b872..f7ef2eaa53 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs @@ -38,12 +38,23 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory /// public class InventoryCache { - private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour + private const double CACHE_EXPIRATION_SECONDS = 60.0; // 1 minute private static ExpiringCache m_RootFolders = new ExpiringCache(); private static ExpiringCache> m_FolderTypes = new ExpiringCache>(); private static ExpiringCache m_Inventories = new ExpiringCache(); + + public void RemoveAll(UUID userID) + { + if(m_RootFolders.Contains(userID)) + m_RootFolders.Remove(userID); + if(m_FolderTypes.Contains(userID)) + m_FolderTypes.Remove(userID); + if(m_Inventories.Contains(userID)) + m_Inventories.Remove(userID); + } + public void Cache(UUID userID, InventoryFolderBase root) { m_RootFolders.AddOrUpdate(userID, root, CACHE_EXPIRATION_SECONDS); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs index cf9a7b4ddf..3127199586 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs @@ -153,12 +153,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts public UserAccount GetUserAccount(UUID scopeID, UUID userID) { bool inCache = false; - UserAccount account = m_Cache.Get(userID, out inCache); + UserAccount account; + lock(m_Cache) + account = m_Cache.Get(userID, out inCache); if (inCache) return account; account = UserAccountService.GetUserAccount(scopeID, userID); - m_Cache.Cache(userID, account); + lock(m_Cache) + m_Cache.Cache(userID, account); return account; } @@ -166,13 +169,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) { bool inCache = false; - UserAccount account = m_Cache.Get(firstName + " " + lastName, out inCache); + UserAccount account; + lock(m_Cache) + account = m_Cache.Get(firstName + " " + lastName, out inCache); if (inCache) return account; account = UserAccountService.GetUserAccount(scopeID, firstName, lastName); if (account != null) - m_Cache.Cache(account.PrincipalID, account); + lock(m_Cache) + m_Cache.Cache(account.PrincipalID, account); return account; } @@ -182,6 +188,45 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts return UserAccountService.GetUserAccount(scopeID, Email); } + public List GetUserAccounts(UUID scopeID, List IDs) + { + List ret = new List(); + List missing = new List(); + + // still another cache.. + bool inCache = false; + UUID uuid = UUID.Zero; + UserAccount account; + foreach(string id in IDs) + { + if(UUID.TryParse(id, out uuid)) + { + lock(m_Cache) + account = m_Cache.Get(uuid, out inCache); + if (inCache) + ret.Add(account); + else + missing.Add(id); + } + } + + if(missing.Count == 0) + return ret; + + List ext = UserAccountService.GetUserAccounts(scopeID, missing); + if(ext != null && ext.Count > 0) + { + ret.AddRange(ext); + foreach(UserAccount acc in ext) + { + if(acc != null) + lock(m_Cache) + m_Cache.Cache(acc.PrincipalID, acc); + } + } + return ret; + } + public List GetUserAccountsWhere(UUID scopeID, string query) { return null; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs index afbba30547..eead05d7ae 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs @@ -26,6 +26,8 @@ */ using System; +using System.Collections; +using System.Collections.Generic; using Nini.Config; using log4net; using Mono.Addins; @@ -126,7 +128,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts // flags, title, etc. And country, don't forget country! private void OnNewClient(IClientAPI client) { - m_Cache.Remove(client.Name); + lock(m_Cache) + m_Cache.Remove(client.Name); } #region Overwritten methods from IUserAccountService @@ -134,12 +137,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts public override UserAccount GetUserAccount(UUID scopeID, UUID userID) { bool inCache = false; - UserAccount account = m_Cache.Get(userID, out inCache); + UserAccount account; + lock(m_Cache) + account = m_Cache.Get(userID, out inCache); if (inCache) return account; account = base.GetUserAccount(scopeID, userID); - m_Cache.Cache(userID, account); + lock(m_Cache) + if(account != null) + m_Cache.Cache(userID, account); return account; } @@ -147,17 +154,60 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts public override UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) { bool inCache = false; - UserAccount account = m_Cache.Get(firstName + " " + lastName, out inCache); + UserAccount account; + lock(m_Cache) + account = m_Cache.Get(firstName + " " + lastName, out inCache); if (inCache) return account; account = base.GetUserAccount(scopeID, firstName, lastName); if (account != null) - m_Cache.Cache(account.PrincipalID, account); + lock(m_Cache) + m_Cache.Cache(account.PrincipalID, account); return account; } + public override List GetUserAccounts(UUID scopeID, List IDs) + { + List accs = new List(); + List missing = new List(); + + UUID uuid = UUID.Zero; + UserAccount account; + bool inCache = false; + + foreach(string id in IDs) + { + if(UUID.TryParse(id, out uuid)) + { + lock(m_Cache) + account = m_Cache.Get(uuid, out inCache); + if (inCache) + accs.Add(account); + else + missing.Add(id); + } + } + + if(missing.Count > 0) + { + List ext = base.GetUserAccounts(scopeID, missing); + if(ext != null && ext.Count >0 ) + { + accs.AddRange(ext); + foreach(UserAccount acc in ext) + { + if(acc != null) + lock(m_Cache) + m_Cache.Cache(acc.PrincipalID, acc); + } + } + } + + return accs; + } + public override bool StoreUserAccount(UserAccount data) { // This remote connector refuses to serve this method diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 3ded00c213..56d41a8812 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -572,6 +572,7 @@ namespace OpenSim.Region.CoreModules.World.Estate bool UseEstateSun, bool UseFixedSun, float SunHour, bool UseGlobal, bool EstateFixedSun, float EstateSunHour) { + double lastwaterlevel = Scene.RegionInfo.RegionSettings.WaterHeight; // Water Height Scene.RegionInfo.RegionSettings.WaterHeight = WaterHeight; @@ -584,6 +585,9 @@ namespace OpenSim.Region.CoreModules.World.Estate Scene.RegionInfo.RegionSettings.FixedSun = UseFixedSun; Scene.RegionInfo.RegionSettings.SunPosition = SunHour; + if(Scene.PhysicsEnabled && Scene.PhysicsScene != null && lastwaterlevel != WaterHeight) + Scene.PhysicsScene.SetWaterLevel(WaterHeight); + Scene.TriggerEstateSunUpdate(); //m_log.Debug("[ESTATE]: UFS: " + UseFixedSun.ToString()); @@ -1471,7 +1475,7 @@ namespace OpenSim.Region.CoreModules.World.Estate Scene.RegionInfo.EstateSettings.FixedSun, (float)Scene.RegionInfo.EstateSettings.SunPosition); - sendRegionInfoPacketToAll(); +// sendRegionInfoPacketToAll(); already done by setRegionTerrainSettings } diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index b00f2b0de3..69a34550a9 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -374,9 +374,10 @@ namespace OpenSim.Region.CoreModules.World.Land public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) { - remote_client.SceneAgent.Invulnerable = - !m_scene.RegionInfo.RegionSettings.AllowDamage || - (m_landData.Flags & (uint)ParcelFlags.AllowDamage) == 0; + if(m_scene.RegionInfo.RegionSettings.AllowDamage) + remote_client.SceneAgent.Invulnerable = false; + else + remote_client.SceneAgent.Invulnerable = (m_landData.Flags & (uint)ParcelFlags.AllowDamage) == 0; if (remote_client.SceneAgent.PresenceType == PresenceType.Npc) return; @@ -779,11 +780,10 @@ namespace OpenSim.Region.CoreModules.World.Land { if (over.LandData.LocalID == LandData.LocalID) { - if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) && - m_scene.RegionInfo.RegionSettings.AllowDamage) + if(m_scene.RegionInfo.RegionSettings.AllowDamage) avatar.Invulnerable = false; else - avatar.Invulnerable = true; + avatar.Invulnerable = (over.LandData.Flags & (uint)ParcelFlags.AllowDamage) == 0; SendLandUpdateToClient(snap_selection, avatar.ControllingClient); avatar.currentParcelUUID = LandData.GlobalID; diff --git a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs index b52576984a..3f54ea5bff 100644 --- a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs +++ b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs @@ -52,11 +52,12 @@ namespace OpenSim.Region.Framework.Interfaces string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY); void ChatterboxInvitation(UUID sessionID, string sessionName, - UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog, - uint timeStamp, bool offline, int parentEstateID, Vector3 position, - uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket); - void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat, - bool isModerator, bool textMute, bool isEnterorLeave); + UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog, + uint timeStamp, bool offline, int parentEstateID, Vector3 position, + uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket); + void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, + bool canVoiceChat, bool isModerator, bool textMute, bool isEnterorLeave); + void ChatterBoxForceClose(UUID toAgent, UUID sessionID, string reason); void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID); void GroupMembershipData(UUID receiverAgent, GroupMembershipData[] data); OSD ScriptRunningEvent(UUID objectID, UUID itemID, bool running, bool mono); diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index c913ec260b..5669c43b70 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -108,6 +108,9 @@ namespace OpenSim.Region.Framework.Scenes priority = GetPriorityByFrontBack(client, entity); break; */ + case UpdatePrioritizationSchemes.SimpleAngularDistance: + priority = GetPriorityByAngularDistance(client, entity); // TODO: Reimplement SimpleAngularDistance + break; case UpdatePrioritizationSchemes.BestAvatarResponsiveness: default: priority = GetPriorityByBestAvatarResponsiveness(client, entity); @@ -241,7 +244,7 @@ namespace OpenSim.Region.Framework.Scenes */ if (distance > 10f) { - float tmp = (float)Math.Log((double)distance) * 1.4426950408889634073599246810019f - 3.3219280948873623478703194294894f; + float tmp = (float)Math.Log((double)distance) * 1.442695f - 3.321928f; // for a map identical to original: // now // 1st constant is 1/(log(2)) (natural log) so we get log2(distance) @@ -269,5 +272,67 @@ namespace OpenSim.Region.Framework.Scenes return pqueue; } + private uint GetPriorityByAngularDistance(IClientAPI client, ISceneEntity entity) + { + uint pqueue = 2; // keep compiler happy + + ScenePresence presence = m_scene.GetScenePresence(client.AgentId); + if (presence == null) + return PriorityQueue.NumberOfQueues - 1; + + // All avatars other than our own go into pqueue 1 + if (entity is ScenePresence) + return 1; + + if (entity is SceneObjectPart) + { + // Attachments are high priority, + if (((SceneObjectPart)entity).ParentGroup.IsAttachment) + return 2; + + pqueue = ComputeAngleDistancePriority(presence, entity); + + // Non physical prims are lower priority than physical prims + PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; + if (physActor == null || !physActor.IsPhysical) + pqueue++; + } + + return pqueue; + } + + private uint ComputeAngleDistancePriority(ScenePresence presence, ISceneEntity entity) + { + double distance; + + Vector3 presencePos = presence.AbsolutePosition; + + SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup; + float bradius = group.GetBoundsRadius(); + Vector3 grppos = group.AbsolutePosition + group.getBoundsCenter(); + distance = Vector3.Distance(presencePos, grppos); + distance -= bradius; + distance *= group.getAreaFactor(); + + // And convert the distance to a priority queue, this computation gives queues + // at 10, 20, 40, 80, 160, 320, 640, and 1280m + uint pqueue = PriorityQueue.NumberOfImmediateQueues + 1; // reserve attachments queue + uint queues = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues; + + if (distance > 10f) + { + float tmp = (float)Math.Log(distance) * 1.442695f - 3.321928f; + // for a map identical to original: + // now + // 1st constant is 1/(log(2)) (natural log) so we get log2(distance) + // 2st constant makes it be log2(distance/10) + + pqueue += (uint)tmp; + if (pqueue > queues - 1) + pqueue = queues - 1; + } + + return pqueue; + } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 33418e631d..d5dbcaf7d1 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3866,15 +3866,9 @@ namespace OpenSim.Region.Framework.Scenes foreach (uint localID in localIDs) { SceneObjectPart part = GetSceneObjectPart(localID); - if (part != null) // It is a prim - { - if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid - { - if (part.ParentGroup.RootPart != part) // Child part - continue; - } - } - deleteIDs.Add(localID); + if (part != null && part.ParentGroup != null && + part.ParentGroup.RootPart == part) + deleteIDs.Add(localID); } ForEachClient(c => c.SendKillObject(deleteIDs)); @@ -4458,7 +4452,7 @@ Label_GroupsDone: { m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate", agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); - reason = String.Format("Denied access to private region {0}: You are do not have access to that region.", + reason = String.Format("Denied access to private region {0}: You do not have access to that region.", RegionInfo.RegionName); return false; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index efc1413a12..df6a1cf00f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1586,12 +1586,22 @@ namespace OpenSim.Region.Framework.Scenes return m_boundsCenter; } + private float m_areaFactor; + public float getAreaFactor() + { + // math is done in GetBoundsRadius(); + if(m_boundsRadius == null) + GetBoundsRadius(); + return m_areaFactor; + } + public float GetBoundsRadius() { // this may need more threading work if(m_boundsRadius == null) { float res = 0; + float areaF = 0; SceneObjectPart p; SceneObjectPart[] parts; float partR; @@ -1613,12 +1623,19 @@ namespace OpenSim.Region.Framework.Scenes } if(partR > res) res = partR; + if(p.maxSimpleArea() > areaF) + areaF = p.maxSimpleArea(); } if(parts.Length > 1) { offset /= parts.Length; // basicly geometric center offset = offset * RootPart.RotationOffset; } + + areaF = 10.0f / areaF; // scale it + areaF = Util.Clamp(areaF, 0.001f, 1000f); // clamp it + + m_areaFactor = (float)Math.Sqrt(areaF); m_boundsCenter = offset; m_boundsRadius = res; return res; @@ -2048,41 +2065,37 @@ namespace OpenSim.Region.Framework.Scenes { // We need to keep track of this state in case this group is still queued for backup. IsDeleted = true; - HasGroupChanged = true; DetachFromBackup(); + if(Scene == null) // should not happen unless restart/shutdown ? + return; + SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { SceneObjectPart part = parts[i]; - if (Scene != null) + Scene.ForEachScenePresence(delegate(ScenePresence avatar) { - Scene.ForEachScenePresence(delegate(ScenePresence avatar) - { - if (!avatar.IsChildAgent && avatar.ParentID == LocalId) - avatar.StandUp(); + if (!avatar.IsChildAgent && avatar.ParentID == LocalId) + avatar.StandUp(); - if (!silent) + if (!silent) + { + part.ClearUpdateSchedule(); + if (part == m_rootPart) { - part.ClearUpdateSchedule(); - if (part == m_rootPart) + if (!IsAttachment + || AttachedAvatar == avatar.ControllingClient.AgentId + || !HasPrivateAttachmentPoint) { - if (!IsAttachment - || AttachedAvatar == avatar.ControllingClient.AgentId - || !HasPrivateAttachmentPoint) - { - // Send a kill object immediately - avatar.ControllingClient.SendKillObject(new List { part.LocalId }); - // Also, send a terse update; in case race conditions make the object pop again in the client, - // this update will send another kill object - m_rootPart.SendTerseUpdateToClient(avatar.ControllingClient); - } + // Send a kill object immediately + avatar.ControllingClient.SendKillObject(new List { part.LocalId }); } } - }); - } + } + }); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 0847b0b45a..01a323ee9e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -285,7 +285,23 @@ namespace OpenSim.Region.Framework.Scenes // but reversed logic: bit cleared means free to rotate public byte RotationAxisLocks = 0; - public bool VolumeDetectActive; + // WRONG flag in libOmvPrimFlags + private const uint primFlagVolumeDetect = (uint)PrimFlags.JointLP2P; + + public bool VolumeDetectActive + { + get + { + return (Flags & (PrimFlags)primFlagVolumeDetect) != 0; + } + set + { + if(value) + Flags |= (PrimFlags)primFlagVolumeDetect; + else + Flags &= (PrimFlags)(~primFlagVolumeDetect); + } + } public bool IsWaitingForFirstSpinUpdatePacket; @@ -1188,6 +1204,33 @@ namespace OpenSim.Region.Framework.Scenes } } + public float maxSimpleArea() + { + float a,b; + float sx = m_shape.Scale.X; + float sy = m_shape.Scale.Y; + float sz = m_shape.Scale.Z; + + if( sx > sy) + { + a = sx; + if(sy > sz) + b = sy; + else + b = sz; + } + else + { + a = sy; + if(sx > sz) + b = sx; + else + b = sz; + } + + return a * b; + } + public UpdateRequired UpdateFlag { get; set; } public bool UpdatePhysRequired { get; set; } @@ -2078,12 +2121,6 @@ namespace OpenSim.Region.Framework.Scenes if (localGlobalTF) { -/* - Quaternion grot = GetWorldRotation(); - Quaternion AXgrot = grot; - Vector3 AXimpulsei = impulsei; - Vector3 newimpulse = AXimpulsei * AXgrot; - */ torque *= GetWorldRotation(); } @@ -2222,16 +2259,8 @@ namespace OpenSim.Region.Framework.Scenes if (userExposed) { -/* - if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero) - { - ParentGroup.Scene.AssetService.Get( - dupe.m_shape.SculptTexture.ToString(), dupe, dupe.AssetReceived); - } -*/ bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); dupe.DoPhysicsPropertyUpdate(UsePhysics, true); -// dupe.UpdatePhysicsSubscribedEvents(); // not sure... } if (dupe.PhysActor != null) @@ -2244,23 +2273,6 @@ namespace OpenSim.Region.Framework.Scenes return dupe; } - /// - /// Called back by asynchronous asset fetch. - /// - /// ID of asset received - /// Register - /// -/* - protected void AssetReceived(string id, Object sender, AssetBase asset) - { - if (asset != null) - SculptTextureCallback(asset); -// else -// m_log.WarnFormat( -// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", -// Name, UUID, id); - } -*/ /// /// Do a physics property update for a NINJA joint. /// @@ -3242,39 +3254,6 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.ScriptSetPhysicsStatus(UsePhysics); } - /// - /// Set sculpt and mesh data, and tell the physics engine to process the change. - /// - /// The mesh itself. -/* - public void SculptTextureCallback(AssetBase texture) - { - if (m_shape.SculptEntry) - { - // commented out for sculpt map caching test - null could mean a cached sculpt map has been found - //if (texture != null) - { - if (texture != null) - { -// m_log.DebugFormat( -// "[SCENE OBJECT PART]: Setting sculpt data for {0} on SculptTextureCallback()", Name); - - m_shape.SculptData = texture.Data; - } - - PhysicsActor pa = PhysActor; - - if (pa != null) - { - // Update the physics actor with the new loaded sculpt data and set the taint signal. - pa.Shape = m_shape; - - ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); - } - } - } - } -*/ /// /// Send a full update to the client for the given part /// @@ -4015,103 +3994,6 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter } } - public EntityIntersection TestIntersection(Ray iray, Quaternion parentrot) - { - // In this case we're using a sphere with a radius of the largest dimension of the prim - // TODO: Change to take shape into account - - EntityIntersection result = new EntityIntersection(); - Vector3 vAbsolutePosition = AbsolutePosition; - Vector3 vScale = Scale; - Vector3 rOrigin = iray.Origin; - Vector3 rDirection = iray.Direction; - - //rDirection = rDirection.Normalize(); - // Buidling the first part of the Quadratic equation - Vector3 r2ndDirection = rDirection*rDirection; - float itestPart1 = r2ndDirection.X + r2ndDirection.Y + r2ndDirection.Z; - - // Buidling the second part of the Quadratic equation - Vector3 tmVal2 = rOrigin - vAbsolutePosition; - Vector3 r2Direction = rDirection*2.0f; - Vector3 tmVal3 = r2Direction*tmVal2; - - float itestPart2 = tmVal3.X + tmVal3.Y + tmVal3.Z; - - // Buidling the third part of the Quadratic equation - Vector3 tmVal4 = rOrigin*rOrigin; - Vector3 tmVal5 = vAbsolutePosition*vAbsolutePosition; - - Vector3 tmVal6 = vAbsolutePosition*rOrigin; - - // Set Radius to the largest dimension of the prim - float radius = 0f; - if (vScale.X > radius) - radius = vScale.X; - if (vScale.Y > radius) - radius = vScale.Y; - if (vScale.Z > radius) - radius = vScale.Z; - - // the second part of this is the default prim size - // once we factor in the aabb of the prim we're adding we can - // change this to; - // radius = (radius / 2) - 0.01f; - // - radius = (radius / 2) + (0.5f / 2) - 0.1f; - - //radius = radius; - - float itestPart3 = tmVal4.X + tmVal4.Y + tmVal4.Z + tmVal5.X + tmVal5.Y + tmVal5.Z - - (2.0f*(tmVal6.X + tmVal6.Y + tmVal6.Z + (radius*radius))); - - // Yuk Quadradrics.. Solve first - float rootsqr = (itestPart2*itestPart2) - (4.0f*itestPart1*itestPart3); - if (rootsqr < 0.0f) - { - // No intersection - return result; - } - float root = ((-itestPart2) - (float) Math.Sqrt((double) rootsqr))/(itestPart1*2.0f); - - if (root < 0.0f) - { - // perform second quadratic root solution - root = ((-itestPart2) + (float) Math.Sqrt((double) rootsqr))/(itestPart1*2.0f); - - // is there any intersection? - if (root < 0.0f) - { - // nope, no intersection - return result; - } - } - - // We got an intersection. putting together an EntityIntersection object with the - // intersection information - Vector3 ipoint = - new Vector3(iray.Origin.X + (iray.Direction.X*root), iray.Origin.Y + (iray.Direction.Y*root), - iray.Origin.Z + (iray.Direction.Z*root)); - - result.HitTF = true; - result.ipoint = ipoint; - - // Normal is calculated by the difference and then normalizing the result - Vector3 normalpart = ipoint - vAbsolutePosition; - result.normal = normalpart / normalpart.Length(); - - // It's funny how the Vector3 object has a Distance function, but the Axiom.Math object doesn't. - // I can write a function to do it.. but I like the fact that this one is Static. - - Vector3 distanceConvert1 = new Vector3(iray.Origin.X, iray.Origin.Y, iray.Origin.Z); - Vector3 distanceConvert2 = new Vector3(ipoint.X, ipoint.Y, ipoint.Z); - float distance = (float) Util.GetDistanceTo(distanceConvert1, distanceConvert2); - - result.distance = distance; - - return result; - } - public EntityIntersection TestIntersectionOBB(Ray iray, Quaternion parentrot, bool frontFacesOnly, bool faceCenters) { // In this case we're using a rectangular prism, which has 6 faces and therefore 6 planes @@ -4479,15 +4361,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter public void UpdateExtraParam(ushort type, bool inUse, byte[] data) { m_shape.ReadInUpdateExtraParam(type, inUse, data); -/* - if (type == 0x30) - { - if (m_shape.SculptEntry && m_shape.SculptTexture != UUID.Zero) - { - ParentGroup.Scene.AssetService.Get(m_shape.SculptTexture.ToString(), this, AssetReceived); - } - } -*/ + if (ParentGroup != null) { ParentGroup.HasGroupChanged = true; @@ -4714,9 +4588,11 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter VolumeDetectActive = SetVD; - // volume detector implies phantom - if (VolumeDetectActive) + // volume detector implies phantom we need to decouple this mess + if (SetVD) SetPhantom = true; + else if(wasVD) + SetPhantom = false; if (UsePhysics) AddFlag(PrimFlags.Physics); @@ -4733,7 +4609,6 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter else RemFlag(PrimFlags.TemporaryOnRez); - if (ParentGroup.Scene == null) return; @@ -4763,26 +4638,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter { AddToPhysics(UsePhysics, SetPhantom, building, false); pa = PhysActor; -/* - if (pa != null) - { - if ( -// ((AggregateScriptEvents & scriptEvents.collision) != 0) || -// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || -// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || -// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || -// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || -// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || - ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || - ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || - (CollisionSound != UUID.Zero) - ) - { - pa.OnCollisionUpdate += PhysicsCollision; - pa.SubscribeEvents(1000); - } - } -*/ + if (pa != null) { pa.SetMaterial(Material); @@ -4793,12 +4649,6 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter { DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. -/* moved into DoPhysicsPropertyUpdate - if(VolumeDetectActive) - pa.SetVolumeDetect(1); - else - pa.SetVolumeDetect(0); -*/ if (pa.Building != building) pa.Building = building; @@ -4807,32 +4657,8 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter UpdatePhysicsSubscribedEvents(); } } - if (SetVD) - { - // If the above logic worked (this is urgent candidate to unit tests!) - // we now have a physicsactor. - // Defensive programming calls for a check here. - // Better would be throwing an exception that could be catched by a unit test as the internal - // logic should make sure, this Physactor is always here. - if (pa != null) - { - pa.SetVolumeDetect(1); - AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active - VolumeDetectActive = true; - } - // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); - } - else if (SetVD != wasVD) - { - // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like - // (mumbles, well, at least if you have infinte CPU powers :-)) - if (pa != null) - pa.SetVolumeDetect(0); - RemFlag(PrimFlags.Phantom); - VolumeDetectActive = false; - } - // and last in case we have a new actor and not building + // and last in case we have a new actor and not building if (ParentGroup != null) { @@ -5093,42 +4919,6 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter } } - /// - /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics - /// engine can use it. - /// - /// - /// When the physics engine has finished with it, the sculpt data is discarded to save memory. - /// -/* - public void CheckSculptAndLoad() - { -// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); - - return; - - if (ParentGroup.IsDeleted) - return; - - if ((ParentGroup.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) - return; - - if (Shape.SculptEntry && Shape.SculptTexture != UUID.Zero) - { - // check if a previously decoded sculpt map has been cached - // We don't read the file here - the meshmerizer will do that later. - // TODO: Could we simplify the meshmerizer code by reading and setting the data here? - if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + Shape.SculptTexture.ToString()))) - { - SculptTextureCallback(null); - } - else - { - ParentGroup.Scene.AssetService.Get(Shape.SculptTexture.ToString(), this, AssetReceived); - } - } - } -*/ /// /// Update the texture entry for this part. /// @@ -5259,7 +5049,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter { // subscribe to physics updates. pa.OnCollisionUpdate += PhysicsCollision; - pa.SubscribeEvents(100); // 10 reports per second + pa.SubscribeEvents(50); // 20 reports per second } else { @@ -5304,41 +5094,8 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter { objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; } -/* - PhysicsActor pa = PhysActor; - if (pa != null) - { - if ( -// ((AggregateScriptEvents & scriptEvents.collision) != 0) || -// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || -// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || -// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || -// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || -// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || - ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero) - ) - { - // subscribe to physics updates. - pa.OnCollisionUpdate += PhysicsCollision; - pa.SubscribeEvents(1000); - } - else - { - pa.UnSubscribeEvents(); - pa.OnCollisionUpdate -= PhysicsCollision; - } - } - */ - UpdatePhysicsSubscribedEvents(); - //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) - //{ - // ParentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting; - //} - //else - //{ - // ParentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting; - //} + UpdatePhysicsSubscribedEvents(); LocalFlags = (PrimFlags)objectflagupdate; @@ -5393,6 +5150,9 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter public void SendTerseUpdateToClient(IClientAPI remoteClient) { + if (ParentGroup.IsDeleted) + return; + if (ParentGroup.IsAttachment && (ParentGroup.RootPart != this || ParentGroup.AttachedAvatar != remoteClient.AgentId && ParentGroup.HasPrivateAttachmentPoint)) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index 1737e3c40c..e98e63177f 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -107,7 +107,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests m_so1.ScriptSetVolumeDetect(true); // Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); - Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom)); + // PrimFlags.JointLP2P is incorrect it now means VolumeDetect (as defined by viewers) + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom | PrimFlags.JointLP2P)); m_so1.ScriptSetVolumeDetect(false); @@ -146,7 +147,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests m_so1.ScriptSetPhysicsStatus(true); m_so1.ScriptSetVolumeDetect(true); - Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom | PrimFlags.Physics)); + // PrimFlags.JointLP2P is incorrect it now means VolumeDetect (as defined by viewers) + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom | PrimFlags.Physics | PrimFlags.JointLP2P)); m_so1.ScriptSetVolumeDetect(false); diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 50be3aced7..e21d69fdb0 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1217,6 +1217,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } + public void SendAlertMessage(string message, string info) + { + + } + public void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message, string url) { IRC_SendChannelPrivmsg(objectname,url); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 112a41f549..626937c70d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -862,7 +862,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), UUID.Zero, name) != null) + GroupRecord groupRecord = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), UUID.Zero, name); + + if (groupRecord != null) { remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); return UUID.Zero; @@ -877,26 +879,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (avatar.UserLevel < m_levelGroupCreate) { - remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient permissions to create a group."); + remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have insufficient permissions to create a group."); return UUID.Zero; } } // check funds - // is there is a money module present ? + // is there a money module present ? IMoneyModule money = scene.RequestModuleInterface(); - if (money != null) + if (money != null && money.GroupCreationCharge > 0) { - // do the transaction, that is if the agent has got sufficient funds + // do the transaction, that is if the agent has sufficient funds if (!money.AmountCovered(remoteClient.AgentId, money.GroupCreationCharge)) { - remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient funds to create a group."); + remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have insufficient funds to create a group."); return UUID.Zero; } - money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, MoneyTransactionType.GroupCreate); + money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, MoneyTransactionType.GroupCreate, name); } UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); - remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); + remoteClient.SendCreateGroupReply(groupID, true, "Group created successfully"); // Update the founder with new group information. SendAgentGroupDataUpdate(remoteClient, false); @@ -1092,6 +1094,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Should check to see if OpenEnrollment, or if there's an outstanding invitation m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, UUID.Zero); + // check funds + // is there a money module present ? + GroupRecord groupRecord = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); + IMoneyModule money = remoteClient.Scene.RequestModuleInterface(); + if (money != null && groupRecord.MembershipFee > 0) + { + // do the transaction, that is if the agent has sufficient funds + if (!money.AmountCovered(GetRequestingAgentID(remoteClient), groupRecord.MembershipFee)) { + remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have insufficient funds to join the group."); + return; + } + money.ApplyCharge(GetRequestingAgentID(remoteClient), groupRecord.MembershipFee, MoneyTransactionType.GroupJoin, groupRecord.GroupName); + } + remoteClient.SendJoinGroupReply(groupID, true); SendAgentGroupDataUpdate(remoteClient, true); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 83f08e0e4b..eb64f715a6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -1008,11 +1008,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups respData.Add("error", e.ToString()); return respData; } - } - if ((m_cacheTimeout > 0) && (CacheKey != null)) - { - m_memoryCache.AddOrUpdate(CacheKey, resp, TimeSpan.FromSeconds(m_cacheTimeout)); + if ((m_cacheTimeout > 0) && (CacheKey != null)) + { + m_memoryCache.AddOrUpdate(CacheKey, resp, 10.0); + } } if (resp.Value is Hashtable) diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/CameraOnlyModeModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/CameraOnlyModeModule.cs index 7ae4223899..770b1f288c 100644 --- a/OpenSim/Region/OptionalModules/ViewerSupport/CameraOnlyModeModule.cs +++ b/OpenSim/Region/OptionalModules/ViewerSupport/CameraOnlyModeModule.cs @@ -108,8 +108,7 @@ namespace OpenSim.Region.OptionalModules.ViewerSupport { if (m_Enabled) { - IEntityTransferModule et = m_scene.RequestModuleInterface(); - m_Helper = new SimulatorFeaturesHelper(scene, et); + m_Helper = new SimulatorFeaturesHelper(scene); ISimulatorFeaturesModule featuresModule = m_scene.RequestModuleInterface(); if (featuresModule != null) @@ -124,7 +123,7 @@ namespace OpenSim.Region.OptionalModules.ViewerSupport private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features) { m_log.DebugFormat("[CAMERA-ONLY MODE]: OnSimulatorFeaturesRequest in {0}", m_scene.RegionInfo.RegionName); - if (m_Helper.ShouldSend(agentID) && m_Helper.UserLevel(agentID) <= m_UserLevel) + if (m_Helper.UserLevel(agentID) <= m_UserLevel) { OSDMap extrasMap; if (features.ContainsKey("OpenSimExtras")) diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/SimulatorFeaturesHelper.cs b/OpenSim/Region/OptionalModules/ViewerSupport/SimulatorFeaturesHelper.cs index 266152238c..1ae18dd870 100644 --- a/OpenSim/Region/OptionalModules/ViewerSupport/SimulatorFeaturesHelper.cs +++ b/OpenSim/Region/OptionalModules/ViewerSupport/SimulatorFeaturesHelper.cs @@ -53,86 +53,11 @@ namespace OpenSim.Region.OptionalModules.ViewerSupport { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private IEntityTransferModule m_TransferModule; private Scene m_scene; - private struct RegionSend { - public UUID region; - public bool send; - }; - // Using a static cache so that we don't have to perform the time-consuming tests - // in ShouldSend on Extra SimFeatures that go on the same response but come from - // different modules. - // This cached is indexed on the agentID and maps to a list of regions - private static ExpiringCache> m_Cache = new ExpiringCache>(); - private const double TIMEOUT = 1.0; // time in cache - - public SimulatorFeaturesHelper(Scene scene, IEntityTransferModule et) + public SimulatorFeaturesHelper(Scene scene) { m_scene = scene; - m_TransferModule = et; - } - - public bool ShouldSend(UUID agentID) - { - List rsendlist; - RegionSend rsend; - if (m_Cache.TryGetValue(agentID, out rsendlist)) - { - rsend = rsendlist.Find(r => r.region == m_scene.RegionInfo.RegionID); - if (rsend.region != UUID.Zero) // Found it - { - return rsend.send; - } - } - - // Relatively complex logic for deciding whether to send the extra SimFeature or not. - // This is because the viewer calls this cap to all sims that it knows about, - // including the departing sims and non-neighbors (those that are cached). - rsend.region = m_scene.RegionInfo.RegionID; - rsend.send = false; - IClientAPI client = null; - int counter = 200; - - // Let's wait a little to see if we get a client here - while (!m_scene.TryGetClient(agentID, out client) && counter-- > 0) - Thread.Sleep(50); - - if (client != null) - { - ScenePresence sp = WaitGetScenePresence(agentID); - - if (sp != null) - { - // On the receiving region, the call to this cap may arrive before - // the agent is root. Make sure we only proceed from here when the agent - // has been made root - counter = 200; - while ((sp.IsInTransit || sp.IsChildAgent) && counter-- > 0) - { - Thread.Sleep(50); - } - - // The viewer calls this cap on the departing sims too. Make sure - // that we only proceed after the agent is not in transit anymore. - // The agent must be root and not going anywhere - if (!sp.IsChildAgent && !m_TransferModule.IsInTransit(agentID)) - rsend.send = true; - - } - } - //else - // m_log.DebugFormat("[XXX]: client is null"); - - - if (rsendlist == null) - { - rsendlist = new List(); - m_Cache.AddOrUpdate(agentID, rsendlist, TIMEOUT); - } - rsendlist.Add(rsend); - - return rsend.send; } public int UserLevel(UUID agentID) @@ -144,28 +69,5 @@ namespace OpenSim.Region.OptionalModules.ViewerSupport return level; } - - protected virtual ScenePresence WaitGetScenePresence(UUID agentID) - { - int ntimes = 20; - ScenePresence sp = null; - while ((sp = m_scene.GetScenePresence(agentID)) == null && (ntimes-- > 0)) - Thread.Sleep(1000); - - if (sp == null) - m_log.WarnFormat( - "[XXX]: Did not find presence with id {0} in {1} before timeout", - agentID, m_scene.RegionInfo.RegionName); - else - { - ntimes = 10; - while (sp.IsInTransit && (ntimes-- > 0)) - Thread.Sleep(1000); - } - - return sp; - } - } - } diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/SpecialUIModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/SpecialUIModule.cs index 3fe922df9c..fa8fc66c31 100644 --- a/OpenSim/Region/OptionalModules/ViewerSupport/SpecialUIModule.cs +++ b/OpenSim/Region/OptionalModules/ViewerSupport/SpecialUIModule.cs @@ -102,8 +102,7 @@ namespace OpenSim.Region.OptionalModules.ViewerSupport { if (m_Enabled) { - IEntityTransferModule et = m_scene.RequestModuleInterface(); - m_Helper = new SimulatorFeaturesHelper(scene, et); + m_Helper = new SimulatorFeaturesHelper(scene); ISimulatorFeaturesModule featuresModule = m_scene.RequestModuleInterface(); if (featuresModule != null) @@ -118,7 +117,7 @@ namespace OpenSim.Region.OptionalModules.ViewerSupport private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features) { m_log.DebugFormat("[SPECIAL UI]: OnSimulatorFeaturesRequest in {0}", m_scene.RegionInfo.RegionName); - if (m_Helper.ShouldSend(agentID) && m_Helper.UserLevel(agentID) <= m_UserLevel) + if (m_Helper.UserLevel(agentID) <= m_UserLevel) { OSDMap extrasMap; OSDMap specialUI = new OSDMap(); diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 4275192a33..52e86609b8 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -885,6 +885,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } + public void SendAlertMessage(string message, string info) + { + } + public void SendSystemAlertMessage(string message) { } diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs b/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs index cef7063a2d..c9489d2622 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs @@ -1605,18 +1605,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (m_cureventsubscription < m_eventsubscription) return; - m_cureventsubscription = 0; - int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count; if (!SentEmptyCollisionsEvent || ncolisions > 0) { base.SendCollisionUpdate(CollisionEventsThisFrame); + m_cureventsubscription = 0; if (ncolisions == 0) { SentEmptyCollisionsEvent = true; - _parent_scene.RemoveCollisionEventReporting(this); +// _parent_scene.RemoveCollisionEventReporting(this); } else { diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs index 9f62644f67..6f2cbbe5b2 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs @@ -1000,9 +1000,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { - if (CollisionEventsThisFrame == null) CollisionEventsThisFrame = new CollisionEventUpdate(); + CollisionEventsThisFrame.AddCollider(CollidedWith, contact); _parent_scene.AddCollisionEventReporting(this); } @@ -1033,28 +1033,27 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (CollisionEventsThisFrame == null) return; + int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count; + if (m_cureventsubscription < m_eventsubscription) return; - m_cureventsubscription = 0; - - int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count; - if (!SentEmptyCollisionsEvent || ncolisions > 0) { base.SendCollisionUpdate(CollisionEventsThisFrame); + m_cureventsubscription = 0; if (ncolisions == 0) { SentEmptyCollisionsEvent = true; - _parent_scene.RemoveCollisionEventReporting(this); +// _parent_scene.RemoveCollisionEventReporting(this); } else if(Body == IntPtr.Zero || d.BodyIsEnabled(Body)) { SentEmptyCollisionsEvent = false; CollisionEventsThisFrame.Clear(); } - } + } } public override bool SubscribedEvents() diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs index bcf8e2b594..6e43cf8054 100644 --- a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs +++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs @@ -417,7 +417,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing meshOsd = (OSDMap)osd; else { - m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap"); + m_log.WarnFormat("[Mesh}: unable to cast mesh asset to OSDMap prim: {0}",primName); return false; } } @@ -451,7 +451,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing if (physicsParms == null) { - m_log.Warn("[MESH]: unknown mesh type"); + m_log.WarnFormat("[MESH]: unknown mesh type for {0}",primName); return false; } diff --git a/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs b/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs index b63b59481d..8806c2cbbd 100644 --- a/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs +++ b/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs @@ -228,6 +228,8 @@ namespace OpenSim.Server.Handlers.GridUser int i = 0; foreach (GridUserInfo pinfo in pinfos) { + if(pinfo == null) + continue; Dictionary rinfoDict = pinfo.ToKeyValuePairs(); result["griduser" + i] = rinfoDict; i++; diff --git a/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs index 21eb790643..237ffc7ee3 100644 --- a/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs +++ b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs @@ -103,6 +103,8 @@ namespace OpenSim.Server.Handlers.UserAccounts return GetAccount(request); case "getaccounts": return GetAccounts(request); + case "getmultiaccounts": + return GetMultiAccounts(request); case "setaccount": if (m_AllowSetAccount) return StoreAccount(request); @@ -201,6 +203,52 @@ namespace OpenSim.Server.Handlers.UserAccounts return Util.UTF8NoBomEncoding.GetBytes(xmlString); } + byte[] GetMultiAccounts(Dictionary request) + { + UUID scopeID = UUID.Zero; + if (request.ContainsKey("ScopeID") && !UUID.TryParse(request["ScopeID"].ToString(), out scopeID)) + return FailureResult(); + + if (!request.ContainsKey("IDS")) + { + m_log.DebugFormat("[USER SERVICE HANDLER]: GetMultiAccounts called without required uuids argument"); + return FailureResult(); + } + + if (!(request["IDS"] is List)) + { + m_log.DebugFormat("[USER SERVICE HANDLER]: GetMultiAccounts input argument was of unexpected type {0}", request["IDS"].GetType().ToString()); + return FailureResult(); + } + + List userIDs = (List)request["IDS"]; + + List accounts = m_UserAccountService.GetUserAccounts(scopeID, userIDs); + + Dictionary result = new Dictionary(); + if ((accounts == null) || ((accounts != null) && (accounts.Count == 0))) + { + result["result"] = "null"; + } + else + { + int i = 0; + foreach (UserAccount acc in accounts) + { + if(acc == null) + continue; + Dictionary rinfoDict = acc.ToKeyValuePairs(); + result["account" + i] = rinfoDict; + i++; + } + } + + string xmlString = ServerUtils.BuildXmlResponse(result); + + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); + } + byte[] StoreAccount(Dictionary request) { UUID principalID = UUID.Zero; diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs index 563a1e7dda..6f613c1f5d 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs @@ -201,6 +201,11 @@ namespace OpenSim.Services.Connectors.SimianGrid return null; } + public List GetUserAccounts(UUID scopeID, List IDs) + { + return null; + } + public bool StoreUserAccount(UserAccount data) { // m_log.InfoFormat("[SIMIAN ACCOUNT CONNECTOR]: Storing user account for " + data.Name); diff --git a/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs b/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs index 3de0a20f9e..5bc7a1cf80 100644 --- a/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs +++ b/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs @@ -191,6 +191,98 @@ namespace OpenSim.Services.Connectors return accounts; } + public virtual List GetUserAccounts(UUID scopeID, List IDs) + { + List accs = new List(); + bool multisuported = true; + accs = doGetMultiUserAccounts(scopeID, IDs, out multisuported); + if(multisuported) + return accs; + + // service does not do multi accounts so need to do it one by one + + UUID uuid = UUID.Zero; + foreach(string id in IDs) + { + if(UUID.TryParse(id, out uuid) && uuid != UUID.Zero) + accs.Add(GetUserAccount(scopeID,uuid)); + } + + return accs; + } + + private List doGetMultiUserAccounts(UUID scopeID, List IDs, out bool suported) + { + suported = true; + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "getmultiaccounts"; + + sendData["ScopeID"] = scopeID.ToString(); + sendData["IDS"] = new List(IDs); + + string reply = string.Empty; + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/accounts"; + // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString); + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString, + m_Auth); + if (reply == null || (reply != null && reply == string.Empty)) + { + m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetMultiUserAccounts received null or empty reply"); + return null; + } + } + catch (Exception e) + { + m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting user accounts server at {0}: {1}", uri, e.Message); + } + + List accounts = new List(); + + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData != null) + { + if (replyData.ContainsKey("result")) + { + if(replyData["result"].ToString() == "null") + return accounts; + + if(replyData["result"].ToString() == "Failure") + { + suported = false; + return accounts; + } + } + + Dictionary.ValueCollection accountList = replyData.Values; + //m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count); + foreach (object acc in accountList) + { + if (acc is Dictionary) + { + UserAccount pinfo = new UserAccount((Dictionary)acc); + accounts.Add(pinfo); + } + else + m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetMultiUserAccounts received invalid response type {0}", + acc.GetType()); + } + } + else + m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetMultiUserAccounts received null response"); + + return accounts; + } + + public void InvalidateCache(UUID userID) { } diff --git a/OpenSim/Services/HypergridService/UserAccountCache.cs b/OpenSim/Services/HypergridService/UserAccountCache.cs index 6c3c6551fd..25ffb63548 100644 --- a/OpenSim/Services/HypergridService/UserAccountCache.cs +++ b/OpenSim/Services/HypergridService/UserAccountCache.cs @@ -100,6 +100,11 @@ namespace OpenSim.Services.HypergridService return null; } + public List GetUserAccounts(UUID scopeID, List IDs) + { + return null; + } + public void InvalidateCache(UUID userID) { m_UUIDCache.Remove(userID); diff --git a/OpenSim/Services/Interfaces/IUserAccountService.cs b/OpenSim/Services/Interfaces/IUserAccountService.cs index 18146996a4..c6f3ef35b0 100644 --- a/OpenSim/Services/Interfaces/IUserAccountService.cs +++ b/OpenSim/Services/Interfaces/IUserAccountService.cs @@ -187,6 +187,7 @@ namespace OpenSim.Services.Interfaces /// List GetUserAccounts(UUID scopeID, string query); List GetUserAccountsWhere(UUID scopeID, string where); + List GetUserAccounts(UUID scopeID, List IDs); /// /// Store the data given, wich replaces the stored data, therefore must be complete. diff --git a/OpenSim/Services/Interfaces/IUserManagement.cs b/OpenSim/Services/Interfaces/IUserManagement.cs index 9e560d5f89..225560e00b 100644 --- a/OpenSim/Services/Interfaces/IUserManagement.cs +++ b/OpenSim/Services/Interfaces/IUserManagement.cs @@ -42,6 +42,7 @@ namespace OpenSim.Services.Interfaces string GetUserUUI(UUID uuid); bool GetUserUUI(UUID userID, out string uui); string GetUserServerURL(UUID uuid, string serverType); + Dictionary GetUsersNames(string[] ids); /// /// Get user ID by the given name. diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs index 6010f0c8bd..668fe53730 100644 --- a/OpenSim/Services/UserAccountService/UserAccountService.cs +++ b/OpenSim/Services/UserAccountService/UserAccountService.cs @@ -265,6 +265,19 @@ namespace OpenSim.Services.UserAccountService return MakeUserAccount(d[0]); } + public List GetUserAccounts(UUID scopeID, List IDs) + { + // do it one at a time db access should be fast, so no need to break its api + List accs = new List(); + UUID uuid = UUID.Zero; + foreach(string id in IDs) + { + if (UUID.TryParse(id, out uuid) && uuid != UUID.Zero) + accs.Add(GetUserAccount(scopeID, uuid)); + } + return accs; + } + public void InvalidateCache(UUID userID) { } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 4f8e986771..9b087c9be0 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -861,6 +861,10 @@ namespace OpenSim.Tests.Common { } + public void SendAlertMessage(string message, string info) + { + } + public void SendSystemAlertMessage(string message) { } diff --git a/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs b/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs index 417efce63c..bc30945dab 100644 --- a/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs +++ b/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs @@ -152,6 +152,11 @@ namespace OpenSim.Tests.Common AddEvent(toAgent, "ChatterBoxSessionAgentListUpdates", sessionID, fromAgent, canVoiceChat, isModerator, textMute, isEnterorLeave); } + public void ChatterBoxForceClose (UUID toAgent, UUID sessionID, string reason) + { + AddEvent(toAgent, "ForceCloseChatterBoxSession", sessionID, reason); + } + public void ParcelProperties (OpenMetaverse.Messages.Linden.ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID) { AddEvent(avatarID, "ParcelProperties", parcelPropertiesMessage); diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index df92921a00..6ccea99260 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -725,7 +725,8 @@ Cap_GetObjectCost = "" Cap_GetObjectPhysicsData = "" Cap_GroupProposalBallot = "" - Cap_HomeLocation = "" + Cap_GroupMemberData = "localhost" + Cap_HomeLocation = "localhost" Cap_LandResources = "" Cap_MapLayer = "localhost" Cap_MapLayerGod = "localhost" diff --git a/bin/config-include/osslEnable.ini b/bin/config-include/osslEnable.ini index c87539fe79..4c6be1604c 100644 --- a/bin/config-include/osslEnable.ini +++ b/bin/config-include/osslEnable.ini @@ -213,6 +213,7 @@ ; Some of these were added as early functionality for NPCs. This has been replaced with the NPC functions. Allow_osAvatarPlayAnimation = false Allow_osAvatarStopAnimation = false + Allow_osForceAttachToOtherAvatarFromInventory = false Allow_osForceDetachFromAvatar = false Allow_osForceOtherSit = false ; The notecard functions can cause a lot of load on the region if over used @@ -225,7 +226,6 @@ ; ThreatLevel Severe Allow_osConsoleCommand = false - Allow_osForceAttachToOtherAvatarFromInventory = false Allow_osGrantScriptPermissions = false Allow_osKickAvatar = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osRevokeScriptPermissions = false