From bd57a81e768a4cb5db97bc8e1b7740499912ebbb Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Sat, 23 Feb 2008 04:03:22 +0000 Subject: [PATCH] * Rex merge, region/environment --- OpenSim/Region/Environment/EstateManager.cs | 1298 +++++++++-------- .../Environment/InstantMessageReceiver.cs | 84 +- OpenSim/Region/Environment/ModuleLoader.cs | 613 ++++---- .../Region/Environment/PermissionManager.cs | 1130 +++++++------- OpenSim/Region/Environment/StorageManager.cs | 156 +- 5 files changed, 1749 insertions(+), 1532 deletions(-) diff --git a/OpenSim/Region/Environment/EstateManager.cs b/OpenSim/Region/Environment/EstateManager.cs index 0403e37c2d..4496dc9d6c 100644 --- a/OpenSim/Region/Environment/EstateManager.cs +++ b/OpenSim/Region/Environment/EstateManager.cs @@ -1,624 +1,674 @@ -/* -* Copyright (c) Contributors, http://opensimulator.org/ -* See CONTRIBUTORS.TXT for a full list of copyright holders. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the OpenSim Project nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*/ -using System; -using System.Collections.Generic; -using System.Text; -using libsecondlife; -using libsecondlife.Packets; -using OpenSim.Framework; -using OpenSim.Framework.Console; -using OpenSim.Region.Environment.Scenes; - -namespace OpenSim.Region.Environment -{ - /// - /// Processes requests regarding estates. Refer to EstateSettings.cs in OpenSim.Framework. Types for all of the core settings - /// - public class EstateManager - { - private Scene m_scene; - private RegionInfo m_regInfo; - - public enum EstateAccessCodex : uint - { - AccessOptions = 17, - AllowedGroups = 18, - EstateBans = 20, - EstateManagers = 24 - } - - - public EstateManager(Scene scene, RegionInfo reginfo) - { - m_scene = scene; - m_regInfo = reginfo; - } - - private bool convertParamStringToBool(byte[] field) - { - string s = Helpers.FieldToUTF8String(field); - if (s == "1" || s.ToLower() == "y" || s.ToLower() == "yes" || s.ToLower() == "t" || s.ToLower() == "true") - { - return true; - } - return false; - } - - /// - /// Sets terrain texture heights for each of the four corners of the region - textures are distributed as a linear range between the two heights. - /// - /// Which corner - /// Minimum height that texture range should cover - /// Maximum height that texture range should cover - public void setEstateTextureRange(Int16 corner, float lowValue, float highValue) - { - switch (corner) - { - case 0: - m_regInfo.EstateSettings.terrainStartHeight0 = lowValue; - m_regInfo.EstateSettings.terrainHeightRange0 = highValue; - break; - case 1: - m_regInfo.EstateSettings.terrainStartHeight1 = lowValue; - m_regInfo.EstateSettings.terrainHeightRange1 = highValue; - break; - case 2: - m_regInfo.EstateSettings.terrainStartHeight2 = lowValue; - m_regInfo.EstateSettings.terrainHeightRange2 = highValue; - break; - case 3: - m_regInfo.EstateSettings.terrainStartHeight3 = lowValue; - m_regInfo.EstateSettings.terrainHeightRange3 = highValue; - break; - } - } - - /// - /// Sets the 'detail' terrain texture on each of the bands. - /// - /// Which texture band - /// The UUID of the texture - public void setTerrainTexture(Int16 band, LLUUID textureUUID) - { - switch (band) - { - case 0: - m_regInfo.EstateSettings.terrainDetail0 = textureUUID; - break; - case 1: - m_regInfo.EstateSettings.terrainDetail1 = textureUUID; - break; - case 2: - m_regInfo.EstateSettings.terrainDetail2 = textureUUID; - break; - case 3: - m_regInfo.EstateSettings.terrainDetail3 = textureUUID; - break; - } - } - - /// - /// Sets common region settings - /// - /// Water height of the waterplane (may not nessecarily be one value) - /// Maximum amount terrain can be raised from previous baking - /// Minimum amount terrain can be lowered from previous baking - /// Use a fixed time of day on the sun? - /// The offset hour of the day - public void setRegionSettings(float WaterHeight, float TerrainRaiseLimit, float TerrainLowerLimit, - bool UseFixedSun, float SunHour) - { - // Water Height - m_regInfo.EstateSettings.waterHeight = WaterHeight; - m_scene.Terrain.watermap.Fill(WaterHeight); - - // Terraforming limits - m_regInfo.EstateSettings.terrainRaiseLimit = TerrainRaiseLimit; - m_regInfo.EstateSettings.terrainLowerLimit = TerrainLowerLimit; - m_scene.Terrain.maxRaise = TerrainRaiseLimit; - m_scene.Terrain.minLower = TerrainLowerLimit; - - // Time of day / fixed sun - m_regInfo.EstateSettings.useFixedSun = UseFixedSun; - m_regInfo.EstateSettings.sunHour = SunHour; - } - - #region Packet Handlers - - public void handleEstateOwnerMessage(EstateOwnerMessagePacket packet, IClientAPI remote_client) - { - switch (Helpers.FieldToUTF8String(packet.MethodData.Method)) - { - case "getinfo": - - //MainLog.Instance.Verbose("ESTATE","CLIENT--->" + packet.ToString()); - sendRegionInfoPacketToAll(); - if (m_scene.PermissionsMngr.GenericEstatePermission(remote_client.AgentId)) - { - sendDetailedEstateData(remote_client, packet); - } - break; - case "setregioninfo": - if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) - estateSetRegionInfoHandler(packet); - break; - case "texturebase": - if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) - estateTextureBaseHandler(packet); - break; - case "texturedetail": - if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) - estateTextureDetailHandler(packet); - break; - case "textureheights": - if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) - estateTextureHeightsHandler(packet); - break; - case "texturecommit": - sendRegionHandshakeToAll(); - break; - case "setregionterrain": - if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) - estateSetRegionTerrainHandler(packet); - break; - case "restart": - if (m_scene.PermissionsMngr.CanRestartSim(remote_client.AgentId)) - { - estateRestartSim(packet); - } - break; - case "estatechangecovenantid": - if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) - { - EstateChangeCovenant(packet); - } - break; - case "estateaccessdelta": // Estate access delta manages the banlist and allow list too. - if (m_scene.PermissionsMngr.GenericEstatePermission(remote_client.AgentId)) - { - estateAccessDelta(remote_client, packet); - } - break; - case "simulatormessage": - if (m_scene.PermissionsMngr.GenericEstatePermission(remote_client.AgentId)) - { - SendSimulatorBlueBoxMessage(remote_client, packet); - } - break; - case "instantmessage": - if (m_scene.PermissionsMngr.GenericEstatePermission(remote_client.AgentId)) - { - SendEstateBlueBoxMessage(remote_client, packet); - } - break; - default: - MainLog.Instance.Error("EstateOwnerMessage: Unknown method requested\n" + packet.ToString()); - break; - } - } - - private void SendSimulatorBlueBoxMessage(IClientAPI remote_client, EstateOwnerMessagePacket packet) - { - LLUUID invoice = packet.MethodData.Invoice; - LLUUID SenderID = new LLUUID(Helpers.FieldToUTF8String(packet.ParamList[2].Parameter)); - string SenderName = Helpers.FieldToUTF8String(packet.ParamList[3].Parameter); - string Message = Helpers.FieldToUTF8String(packet.ParamList[4].Parameter); - m_scene.SendRegionMessageFromEstateTools(SenderID, packet.AgentData.SessionID, SenderName, Message); - - } - private void SendEstateBlueBoxMessage(IClientAPI remote_client, EstateOwnerMessagePacket packet) - { - LLUUID invoice = packet.MethodData.Invoice; - LLUUID SenderID = packet.AgentData.AgentID; - string SenderName = Helpers.FieldToUTF8String(packet.ParamList[0].Parameter); - string Message = Helpers.FieldToUTF8String(packet.ParamList[1].Parameter); - m_scene.SendEstateMessageFromEstateTools(SenderID, packet.AgentData.SessionID, SenderName, Message); - - } - private void sendDetailedEstateData(IClientAPI remote_client, EstateOwnerMessagePacket packet) - { - - LLUUID invoice = packet.MethodData.Invoice; - packet.AgentData.TransactionID = LLUUID.Random(); - packet.MethodData.Method = Helpers.StringToField("estateupdateinfo"); - EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[9]; - - for (int i = 0; i < 9; i++) - { - returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); - } - - //Sending Estate Settings - returnblock[0].Parameter = Helpers.StringToField(m_scene.RegionInfo.MasterAvatarFirstName + m_scene.RegionInfo.MasterAvatarLastName); - returnblock[1].Parameter = Helpers.StringToField(m_scene.RegionInfo.MasterAvatarAssignedUUID.ToString()); - returnblock[2].Parameter = Helpers.StringToField(m_scene.RegionInfo.EstateSettings.estateID.ToString()); - - // TODO: Resolve Magic numbers here - returnblock[3].Parameter = Helpers.StringToField("269516800"); - returnblock[4].Parameter = Helpers.StringToField("0"); - returnblock[5].Parameter = Helpers.StringToField("1"); - returnblock[6].Parameter = Helpers.StringToField(m_scene.RegionInfo.RegionID.ToString()); - returnblock[7].Parameter = Helpers.StringToField("1160895077"); - returnblock[8].Parameter = Helpers.StringToField("1"); - - packet.ParamList = returnblock; - //MainLog.Instance.Verbose("ESTATE", "SIM--->" + packet.ToString()); - remote_client.OutPacket(packet, ThrottleOutPacketType.Task); - - sendEstateManagerList(remote_client, packet); - - } - - private void sendEstateManagerList(IClientAPI remote_client, EstateOwnerMessagePacket packet) - { - LLUUID invoice = packet.MethodData.Invoice; - - //Sending Estate Managers - packet = new EstateOwnerMessagePacket(); - packet.AgentData.TransactionID = LLUUID.Random(); - packet.AgentData.AgentID = remote_client.AgentId; - packet.AgentData.SessionID = remote_client.SessionId; - packet.MethodData.Invoice = invoice; - packet.MethodData.Method = Helpers.StringToField("setaccess"); - - LLUUID[] EstateManagers = m_scene.RegionInfo.EstateSettings.estateManagers; - - EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + EstateManagers.Length]; - - for (int i = 0; i < (6 + EstateManagers.Length); i++) - { - returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); - } - int j = 0; - returnblock[j].Parameter = Helpers.StringToField(m_scene.RegionInfo.EstateSettings.estateID.ToString()); j++; - returnblock[j].Parameter = Helpers.StringToField(((int)EstateAccessCodex.EstateManagers).ToString()); j++; - returnblock[j].Parameter = Helpers.StringToField("0"); j++; - returnblock[j].Parameter = Helpers.StringToField("0"); j++; - returnblock[j].Parameter = Helpers.StringToField("0"); j++; - returnblock[j].Parameter = Helpers.StringToField(EstateManagers.Length.ToString()); j++; - for (int i = 0; i < EstateManagers.Length; i++) - { - returnblock[j].Parameter = EstateManagers[i].GetBytes(); j++; - } - packet.ParamList = returnblock; - //MainLog.Instance.Verbose("ESTATE", "SIM--->" + packet.ToString()); - remote_client.OutPacket(packet, ThrottleOutPacketType.Task); - } - - private void estateAccessDelta(IClientAPI remote_client, EstateOwnerMessagePacket packet) - { - // EstateAccessDelta handles Estate Managers, Sim Access, Sim Banlist, allowed Groups.. etc. - int estateAccessType = Convert.ToInt16(Helpers.FieldToUTF8String(packet.ParamList[1].Parameter)); - - switch (estateAccessType) - { - case 256: - - // This needs to be updated for SuperEstateOwnerUser.. a non existing user in the estatesettings.xml - // So make sure you really trust your region owners. because they can add other estate manaagers to your other estates - if (packet.AgentData.AgentID == m_scene.RegionInfo.MasterAvatarAssignedUUID || m_scene.PermissionsMngr.BypassPermissions) - { - m_scene.RegionInfo.EstateSettings.AddEstateManager(new LLUUID(Helpers.FieldToUTF8String(packet.ParamList[2].Parameter))); - sendEstateManagerList(remote_client, packet); - } - else - { - remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); - } - - break; - case 512: - // This needs to be updated for SuperEstateOwnerUser.. a non existing user in the estatesettings.xml - // So make sure you really trust your region owners. because they can add other estate manaagers to your other estates - if (packet.AgentData.AgentID == m_scene.RegionInfo.MasterAvatarAssignedUUID || m_scene.PermissionsMngr.BypassPermissions) - { - m_scene.RegionInfo.EstateSettings.RemoveEstateManager(new LLUUID(Helpers.FieldToUTF8String(packet.ParamList[2].Parameter))); - sendEstateManagerList(remote_client, packet); - } - else - { - remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); - } - break; - - default: - - MainLog.Instance.Error("EstateOwnerMessage: Unknown EstateAccessType requested in estateAccessDelta\n" + packet.ToString()); - break; - } - //MainLog.Instance.Error("EstateOwnerMessage: estateAccessDelta\n" + packet.ToString()); - - - } - private void estateSetRegionInfoHandler(EstateOwnerMessagePacket packet) - { - if (packet.ParamList.Length != 9) - { - MainLog.Instance.Error("EstateOwnerMessage: SetRegionInfo method has a ParamList of invalid length"); - } - else - { - m_regInfo.EstateSettings.regionFlags = Simulator.RegionFlags.None; - - if (convertParamStringToBool(packet.ParamList[0].Parameter)) - { - m_regInfo.EstateSettings.regionFlags = m_regInfo.EstateSettings.regionFlags | - Simulator.RegionFlags.BlockTerraform; - } - - if (convertParamStringToBool(packet.ParamList[1].Parameter)) - { - m_regInfo.EstateSettings.regionFlags = m_regInfo.EstateSettings.regionFlags | - Simulator.RegionFlags.NoFly; - } - - if (convertParamStringToBool(packet.ParamList[2].Parameter)) - { - m_regInfo.EstateSettings.regionFlags = m_regInfo.EstateSettings.regionFlags | - Simulator.RegionFlags.AllowDamage; - } - - if (convertParamStringToBool(packet.ParamList[3].Parameter) == false) - { - m_regInfo.EstateSettings.regionFlags = m_regInfo.EstateSettings.regionFlags | - Simulator.RegionFlags.BlockLandResell; - } - - - int tempMaxAgents = - Convert.ToInt16(Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[4].Parameter))); - m_regInfo.EstateSettings.maxAgents = (byte) tempMaxAgents; - - float tempObjectBonusFactor = - (float) Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[5].Parameter)); - m_regInfo.EstateSettings.objectBonusFactor = tempObjectBonusFactor; - - int tempMatureLevel = Convert.ToInt16(Helpers.FieldToUTF8String(packet.ParamList[6].Parameter)); - m_regInfo.EstateSettings.simAccess = (Simulator.SimAccess) tempMatureLevel; - - - if (convertParamStringToBool(packet.ParamList[7].Parameter)) - { - m_regInfo.EstateSettings.regionFlags = m_regInfo.EstateSettings.regionFlags | - Simulator.RegionFlags.RestrictPushObject; - } - - if (convertParamStringToBool(packet.ParamList[8].Parameter)) - { - m_regInfo.EstateSettings.regionFlags = m_regInfo.EstateSettings.regionFlags | - Simulator.RegionFlags.AllowParcelChanges; - } - - sendRegionInfoPacketToAll(); - } - } - - private void estateSetRegionTerrainHandler(EstateOwnerMessagePacket packet) - { - if (packet.ParamList.Length != 9) - { - MainLog.Instance.Error("EstateOwnerMessage: SetRegionTerrain method has a ParamList of invalid length"); - } - else - { - float WaterHeight = (float) Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[0].Parameter)); - float TerrainRaiseLimit = - (float) Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[1].Parameter)); - float TerrainLowerLimit = - (float) Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[2].Parameter)); - bool UseFixedSun = convertParamStringToBool(packet.ParamList[4].Parameter); - float SunHour = (float) Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[5].Parameter)); - - setRegionSettings(WaterHeight, TerrainRaiseLimit, TerrainLowerLimit, UseFixedSun, SunHour); - - sendRegionInfoPacketToAll(); - } - } - - private void estateTextureHeightsHandler(EstateOwnerMessagePacket packet) - { - foreach (EstateOwnerMessagePacket.ParamListBlock block in packet.ParamList) - { - string s = Helpers.FieldToUTF8String(block.Parameter); - string[] splitField = s.Split(' '); - if (splitField.Length == 3) - { - Int16 corner = Convert.ToInt16(splitField[0]); - float lowValue = (float) Convert.ToDouble(splitField[1].Replace('.', ',')); - float highValue = (float) Convert.ToDouble(splitField[2].Replace('.', ',')); - - setEstateTextureRange(corner, lowValue, highValue); - } - } - } - - private void estateTextureDetailHandler(EstateOwnerMessagePacket packet) - { - foreach (EstateOwnerMessagePacket.ParamListBlock block in packet.ParamList) - { - string s = Helpers.FieldToUTF8String(block.Parameter); - string[] splitField = s.Split(' '); - if (splitField.Length == 2) - { - Int16 corner = Convert.ToInt16(splitField[0]); - LLUUID textureUUID = new LLUUID(splitField[1]); - - setTerrainTexture(corner, textureUUID); - } - } - } - - private void estateTextureBaseHandler(EstateOwnerMessagePacket packet) - { - foreach (EstateOwnerMessagePacket.ParamListBlock block in packet.ParamList) - { - string s = Helpers.FieldToUTF8String(block.Parameter); - string[] splitField = s.Split(' '); - if (splitField.Length == 2) - { - LLUUID tempUUID = new LLUUID(splitField[1]); - switch (Convert.ToInt16(splitField[0])) - { - case 0: - m_regInfo.EstateSettings.terrainBase0 = tempUUID; - break; - case 1: - m_regInfo.EstateSettings.terrainBase1 = tempUUID; - break; - case 2: - m_regInfo.EstateSettings.terrainBase2 = tempUUID; - break; - case 3: - m_regInfo.EstateSettings.terrainBase3 = tempUUID; - break; - } - } - } - } - - private void estateRestartSim(EstateOwnerMessagePacket packet) - { - // There's only 1 block in the estateResetSim.. and that's the number of seconds till restart. - foreach (EstateOwnerMessagePacket.ParamListBlock block in packet.ParamList) - { - float timeSeconds = 0; - Helpers.TryParse(Helpers.FieldToUTF8String(block.Parameter), out timeSeconds); - timeSeconds = (int)timeSeconds; - m_scene.Restart(timeSeconds); - - } - } - - private void EstateChangeCovenant(EstateOwnerMessagePacket packet) - { - foreach (EstateOwnerMessagePacket.ParamListBlock block in packet.ParamList) - { - LLUUID newCovenantID = new LLUUID(Helpers.FieldToUTF8String(block.Parameter)); - m_regInfo.CovenantID = newCovenantID; - m_scene.RegionInfo.SaveEstatecovenantUUID(newCovenantID); - } - } - - public void HandleRegionInfoRequest(IClientAPI client, LLUUID sessionID) - { - RegionInfoPacket rinfopack = new RegionInfoPacket(); - RegionInfoPacket.RegionInfoBlock rinfoblk = new RegionInfoPacket.RegionInfoBlock(); - - rinfoblk.BillableFactor = 0; - rinfoblk.EstateID = 02; - rinfoblk.MaxAgents = 100; - rinfoblk.ObjectBonusFactor = 1.0f; - rinfoblk.ParentEstateID = 0; - rinfoblk.PricePerMeter = 0; - rinfoblk.RedirectGridX = 0; - rinfoblk.RedirectGridY = 0; - rinfoblk.RegionFlags = (uint) m_regInfo.EstateSettings.regionFlags; - rinfoblk.SimAccess = (byte) m_regInfo.EstateSettings.simAccess; - rinfoblk.SunHour = m_regInfo.EstateSettings.sunHour; - rinfoblk.TerrainLowerLimit = 20; - rinfoblk.TerrainRaiseLimit = 20; - rinfoblk.UseEstateSun = true; - rinfoblk.WaterHeight = m_regInfo.EstateSettings.waterHeight; - rinfoblk.SimName = Helpers.StringToField(m_regInfo.RegionName); - - rinfopack.RegionInfo = rinfoblk; - - client.OutPacket(rinfopack, ThrottleOutPacketType.Task); - } - - public void HandleEstateCovenantRequest(IClientAPI client, LLUUID sessionID) - { - EstateCovenantReplyPacket einfopack = new EstateCovenantReplyPacket(); - EstateCovenantReplyPacket.DataBlock edata = new EstateCovenantReplyPacket.DataBlock(); - edata.CovenantID = m_regInfo.CovenantID; - edata.CovenantTimestamp = 0; - edata.EstateOwnerID = m_regInfo.MasterAvatarAssignedUUID; - edata.EstateName = - Helpers.StringToField(m_regInfo.MasterAvatarFirstName + " " + m_regInfo.MasterAvatarLastName); - einfopack.Data = edata; - client.OutPacket(einfopack, ThrottleOutPacketType.Task); - } - - #endregion - - #region Outgoing Packets - - public void sendRegionInfoPacketToAll() - { - List avatars = m_scene.GetAvatars(); - - for (int i = 0; i < avatars.Count; i++) - { - sendRegionInfoPacket(avatars[i].ControllingClient); - } - } - - public void sendRegionHandshakeToAll() - { - m_scene.Broadcast( - sendRegionHandshake - ); - } - - public void sendRegionInfoPacket(IClientAPI remote_client) - { - Encoding _enc = Encoding.ASCII; - - AgentCircuitData circuitData = remote_client.RequestClientInfo(); - - RegionInfoPacket regionInfoPacket = new RegionInfoPacket(); - regionInfoPacket.AgentData.AgentID = circuitData.AgentID; - regionInfoPacket.AgentData.SessionID = circuitData.SessionID; - regionInfoPacket.RegionInfo.BillableFactor = m_regInfo.EstateSettings.billableFactor; - regionInfoPacket.RegionInfo.EstateID = m_regInfo.EstateSettings.estateID; - regionInfoPacket.RegionInfo.MaxAgents = m_regInfo.EstateSettings.maxAgents; - regionInfoPacket.RegionInfo.ObjectBonusFactor = m_regInfo.EstateSettings.objectBonusFactor; - regionInfoPacket.RegionInfo.ParentEstateID = m_regInfo.EstateSettings.parentEstateID; - regionInfoPacket.RegionInfo.PricePerMeter = m_regInfo.EstateSettings.pricePerMeter; - regionInfoPacket.RegionInfo.RedirectGridX = m_regInfo.EstateSettings.redirectGridX; - regionInfoPacket.RegionInfo.RedirectGridY = m_regInfo.EstateSettings.redirectGridY; - regionInfoPacket.RegionInfo.RegionFlags = (uint) m_regInfo.EstateSettings.regionFlags; - regionInfoPacket.RegionInfo.SimAccess = (byte) m_regInfo.EstateSettings.simAccess; - regionInfoPacket.RegionInfo.SimName = _enc.GetBytes(m_regInfo.RegionName); - regionInfoPacket.RegionInfo.SunHour = m_regInfo.EstateSettings.sunHour; - regionInfoPacket.RegionInfo.TerrainLowerLimit = m_regInfo.EstateSettings.terrainLowerLimit; - regionInfoPacket.RegionInfo.TerrainRaiseLimit = m_regInfo.EstateSettings.terrainRaiseLimit; - regionInfoPacket.RegionInfo.UseEstateSun = !m_regInfo.EstateSettings.useFixedSun; - regionInfoPacket.RegionInfo.WaterHeight = m_regInfo.EstateSettings.waterHeight; - - remote_client.OutPacket(regionInfoPacket, ThrottleOutPacketType.Task); - } - - public void sendRegionHandshake(IClientAPI remoteClient) - { - remoteClient.SendRegionHandshake(m_regInfo); - } - - #endregion - } -} \ No newline at end of file +/* +* Copyright (c) Contributors, http://opensimulator.org/ +* See CONTRIBUTORS.TXT for a full list of copyright holders. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the OpenSim Project nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ +using System; +using System.Collections.Generic; +using System.Text; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Region.Environment.Scenes; + +namespace OpenSim.Region.Environment +{ + /// + /// Processes requests regarding estates. Refer to EstateSettings.cs in OpenSim.Framework. Types for all of the core settings + /// + public class EstateManager + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene; + private RegionInfo m_regInfo; + + public enum EstateAccessCodex : uint + { + AccessOptions = 17, + AllowedGroups = 18, + EstateBans = 20, + EstateManagers = 24 + } + + + public EstateManager(Scene scene, RegionInfo reginfo) + { + m_scene = scene; + m_regInfo = reginfo; + } + + private bool convertParamStringToBool(byte[] field) + { + string s = Helpers.FieldToUTF8String(field); + if (s == "1" || s.ToLower() == "y" || s.ToLower() == "yes" || s.ToLower() == "t" || s.ToLower() == "true") + { + return true; + } + return false; + } + + /// + /// Sets terrain texture heights for each of the four corners of the region - textures are distributed as a linear range between the two heights. + /// + /// Which corner + /// Minimum height that texture range should cover + /// Maximum height that texture range should cover + public void setEstateTextureRange(Int16 corner, float lowValue, float highValue) + { + switch (corner) + { + case 0: + m_regInfo.EstateSettings.terrainStartHeight0 = lowValue; + m_regInfo.EstateSettings.terrainHeightRange0 = highValue; + break; + case 1: + m_regInfo.EstateSettings.terrainStartHeight1 = lowValue; + m_regInfo.EstateSettings.terrainHeightRange1 = highValue; + break; + case 2: + m_regInfo.EstateSettings.terrainStartHeight2 = lowValue; + m_regInfo.EstateSettings.terrainHeightRange2 = highValue; + break; + case 3: + m_regInfo.EstateSettings.terrainStartHeight3 = lowValue; + m_regInfo.EstateSettings.terrainHeightRange3 = highValue; + break; + } + } + + /// + /// Sets the 'detail' terrain texture on each of the bands. + /// + /// Which texture band + /// The UUID of the texture + public void setTerrainTexture(Int16 band, LLUUID textureUUID) + { + switch (band) + { + case 0: + m_regInfo.EstateSettings.terrainDetail0 = textureUUID; + break; + case 1: + m_regInfo.EstateSettings.terrainDetail1 = textureUUID; + break; + case 2: + m_regInfo.EstateSettings.terrainDetail2 = textureUUID; + break; + case 3: + m_regInfo.EstateSettings.terrainDetail3 = textureUUID; + break; + } + } + + /// + /// Sets common region settings + /// + /// Water height of the waterplane (may not nessecarily be one value) + /// Maximum amount terrain can be raised from previous baking + /// Minimum amount terrain can be lowered from previous baking + /// Use a fixed time of day on the sun? + /// The offset hour of the day + public void setRegionSettings(float WaterHeight, float TerrainRaiseLimit, float TerrainLowerLimit, + bool UseFixedSun, float SunHour) + { + // Water Height + m_regInfo.EstateSettings.waterHeight = WaterHeight; + m_scene.Terrain.watermap.Fill(WaterHeight); + + // Terraforming limits + m_regInfo.EstateSettings.terrainRaiseLimit = TerrainRaiseLimit; + m_regInfo.EstateSettings.terrainLowerLimit = TerrainLowerLimit; + m_scene.Terrain.maxRaise = TerrainRaiseLimit; + m_scene.Terrain.minLower = TerrainLowerLimit; + + // Time of day / fixed sun + m_regInfo.EstateSettings.useFixedSun = UseFixedSun; + m_regInfo.EstateSettings.sunHour = SunHour; + } + + #region Packet Handlers + + public void handleEstateOwnerMessage(EstateOwnerMessagePacket packet, IClientAPI remote_client) + { + switch (Helpers.FieldToUTF8String(packet.MethodData.Method)) + { + case "getinfo": + + //m_log.Info("[ESTATE]: CLIENT--->" + packet.ToString()); + sendRegionInfoPacketToAll(); + if (m_scene.PermissionsMngr.GenericEstatePermission(remote_client.AgentId)) + { + sendDetailedEstateData(remote_client, packet); + } + break; + case "setregioninfo": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) + estateSetRegionInfoHandler(packet); + break; + case "texturebase": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) + estateTextureBaseHandler(packet); + break; + case "texturedetail": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) + estateTextureDetailHandler(packet); + break; + case "textureheights": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) + estateTextureHeightsHandler(packet); + break; + case "texturecommit": + sendRegionHandshakeToAll(); + break; + case "setregionterrain": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) + estateSetRegionTerrainHandler(packet); + break; + case "restart": + if (m_scene.PermissionsMngr.CanRestartSim(remote_client.AgentId)) + { + estateRestartSim(packet); + } + break; + case "estatechangecovenantid": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) + { + EstateChangeCovenant(packet); + } + break; + case "estateaccessdelta": // Estate access delta manages the banlist and allow list too. + if (m_scene.PermissionsMngr.GenericEstatePermission(remote_client.AgentId)) + { + estateAccessDelta(remote_client, packet); + } + break; + case "simulatormessage": + if (m_scene.PermissionsMngr.GenericEstatePermission(remote_client.AgentId)) + { + SendSimulatorBlueBoxMessage(remote_client, packet); + } + break; + case "instantmessage": + if (m_scene.PermissionsMngr.GenericEstatePermission(remote_client.AgentId)) + { + SendEstateBlueBoxMessage(remote_client, packet); + } + break; + case "setregiondebug": + if (m_scene.PermissionsMngr.GenericEstatePermission(remote_client.AgentId)) + { + SetRegionDebug(remote_client, packet); + } + break; + default: + m_log.Error("EstateOwnerMessage: Unknown method requested\n" + packet.ToString()); + break; + } + } + + private void SetRegionDebug(IClientAPI remote_client, EstateOwnerMessagePacket packet) + { + LLUUID invoice = packet.MethodData.Invoice; + LLUUID SenderID = packet.AgentData.AgentID; + bool scripted = convertParamStringToBool(packet.ParamList[0].Parameter); + bool collisionEvents = convertParamStringToBool(packet.ParamList[1].Parameter); + bool physics = convertParamStringToBool(packet.ParamList[2].Parameter); + + if (physics) + { + m_scene.RegionInfo.EstateSettings.regionFlags |= Simulator.RegionFlags.SkipPhysics; + } + else + { + m_scene.RegionInfo.EstateSettings.regionFlags &= ~Simulator.RegionFlags.SkipPhysics; + } + + if (scripted) + { + m_scene.RegionInfo.EstateSettings.regionFlags |= Simulator.RegionFlags.SkipScripts; + } + else + { + m_scene.RegionInfo.EstateSettings.regionFlags &= ~Simulator.RegionFlags.SkipScripts; + } + + + m_scene.SetSceneCoreDebug(scripted, collisionEvents, physics); + } + + private void SendSimulatorBlueBoxMessage(IClientAPI remote_client, EstateOwnerMessagePacket packet) + { + LLUUID invoice = packet.MethodData.Invoice; + LLUUID SenderID = new LLUUID(Helpers.FieldToUTF8String(packet.ParamList[2].Parameter)); + string SenderName = Helpers.FieldToUTF8String(packet.ParamList[3].Parameter); + string Message = Helpers.FieldToUTF8String(packet.ParamList[4].Parameter); + m_scene.SendRegionMessageFromEstateTools(SenderID, packet.AgentData.SessionID, SenderName, Message); + + } + private void SendEstateBlueBoxMessage(IClientAPI remote_client, EstateOwnerMessagePacket packet) + { + LLUUID invoice = packet.MethodData.Invoice; + LLUUID SenderID = packet.AgentData.AgentID; + string SenderName = Helpers.FieldToUTF8String(packet.ParamList[0].Parameter); + string Message = Helpers.FieldToUTF8String(packet.ParamList[1].Parameter); + m_scene.SendEstateMessageFromEstateTools(SenderID, packet.AgentData.SessionID, SenderName, Message); + + } + private void sendDetailedEstateData(IClientAPI remote_client, EstateOwnerMessagePacket packet) + { + + LLUUID invoice = packet.MethodData.Invoice; + packet.AgentData.TransactionID = LLUUID.Random(); + packet.MethodData.Method = Helpers.StringToField("estateupdateinfo"); + EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[9]; + + for (int i = 0; i < 9; i++) + { + returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); + } + + //Sending Estate Settings + returnblock[0].Parameter = Helpers.StringToField(m_scene.RegionInfo.MasterAvatarFirstName + m_scene.RegionInfo.MasterAvatarLastName); + returnblock[1].Parameter = Helpers.StringToField(m_scene.RegionInfo.MasterAvatarAssignedUUID.ToString()); + returnblock[2].Parameter = Helpers.StringToField(m_scene.RegionInfo.EstateSettings.estateID.ToString()); + + // TODO: Resolve Magic numbers here + returnblock[3].Parameter = Helpers.StringToField("269516800"); + returnblock[4].Parameter = Helpers.StringToField("0"); + returnblock[5].Parameter = Helpers.StringToField("1"); + returnblock[6].Parameter = Helpers.StringToField(m_scene.RegionInfo.RegionID.ToString()); + returnblock[7].Parameter = Helpers.StringToField("1160895077"); + returnblock[8].Parameter = Helpers.StringToField("1"); + + packet.ParamList = returnblock; + //m_log.Info("[ESTATE]: SIM--->" + packet.ToString()); + remote_client.OutPacket(packet, ThrottleOutPacketType.Task); + + sendEstateManagerList(remote_client, packet); + + } + + private void sendEstateManagerList(IClientAPI remote_client, EstateOwnerMessagePacket packet) + { + LLUUID invoice = packet.MethodData.Invoice; + + //Sending Estate Managers + packet = new EstateOwnerMessagePacket(); + packet.AgentData.TransactionID = LLUUID.Random(); + packet.AgentData.AgentID = remote_client.AgentId; + packet.AgentData.SessionID = remote_client.SessionId; + packet.MethodData.Invoice = invoice; + packet.MethodData.Method = Helpers.StringToField("setaccess"); + + LLUUID[] EstateManagers = m_scene.RegionInfo.EstateSettings.estateManagers; + + EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + EstateManagers.Length]; + + for (int i = 0; i < (6 + EstateManagers.Length); i++) + { + returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); + } + int j = 0; + returnblock[j].Parameter = Helpers.StringToField(m_scene.RegionInfo.EstateSettings.estateID.ToString()); j++; + returnblock[j].Parameter = Helpers.StringToField(((int)EstateAccessCodex.EstateManagers).ToString()); j++; + returnblock[j].Parameter = Helpers.StringToField("0"); j++; + returnblock[j].Parameter = Helpers.StringToField("0"); j++; + returnblock[j].Parameter = Helpers.StringToField("0"); j++; + returnblock[j].Parameter = Helpers.StringToField(EstateManagers.Length.ToString()); j++; + for (int i = 0; i < EstateManagers.Length; i++) + { + returnblock[j].Parameter = EstateManagers[i].GetBytes(); j++; + } + packet.ParamList = returnblock; + //m_log.Info("[ESTATE]: SIM--->" + packet.ToString()); + remote_client.OutPacket(packet, ThrottleOutPacketType.Task); + } + + private void estateAccessDelta(IClientAPI remote_client, EstateOwnerMessagePacket packet) + { + // EstateAccessDelta handles Estate Managers, Sim Access, Sim Banlist, allowed Groups.. etc. + int estateAccessType = Convert.ToInt16(Helpers.FieldToUTF8String(packet.ParamList[1].Parameter)); + + switch (estateAccessType) + { + case 256: + + // This needs to be updated for SuperEstateOwnerUser.. a non existing user in the estatesettings.xml + // So make sure you really trust your region owners. because they can add other estate manaagers to your other estates + if (packet.AgentData.AgentID == m_scene.RegionInfo.MasterAvatarAssignedUUID || m_scene.PermissionsMngr.BypassPermissions) + { + m_scene.RegionInfo.EstateSettings.AddEstateManager(new LLUUID(Helpers.FieldToUTF8String(packet.ParamList[2].Parameter))); + sendEstateManagerList(remote_client, packet); + } + else + { + remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); + } + + break; + case 512: + // This needs to be updated for SuperEstateOwnerUser.. a non existing user in the estatesettings.xml + // So make sure you really trust your region owners. because they can add other estate manaagers to your other estates + if (packet.AgentData.AgentID == m_scene.RegionInfo.MasterAvatarAssignedUUID || m_scene.PermissionsMngr.BypassPermissions) + { + m_scene.RegionInfo.EstateSettings.RemoveEstateManager(new LLUUID(Helpers.FieldToUTF8String(packet.ParamList[2].Parameter))); + sendEstateManagerList(remote_client, packet); + } + else + { + remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); + } + break; + + default: + + m_log.Error("EstateOwnerMessage: Unknown EstateAccessType requested in estateAccessDelta\n" + packet.ToString()); + break; + } + //m_log.Error("EstateOwnerMessage: estateAccessDelta\n" + packet.ToString()); + + + } + private void estateSetRegionInfoHandler(EstateOwnerMessagePacket packet) + { + if (packet.ParamList.Length != 9) + { + m_log.Error("EstateOwnerMessage: SetRegionInfo method has a ParamList of invalid length"); + } + else + { + m_regInfo.EstateSettings.regionFlags = Simulator.RegionFlags.None; + + if (convertParamStringToBool(packet.ParamList[0].Parameter)) + { + m_regInfo.EstateSettings.regionFlags = m_regInfo.EstateSettings.regionFlags | + Simulator.RegionFlags.BlockTerraform; + } + + if (convertParamStringToBool(packet.ParamList[1].Parameter)) + { + m_regInfo.EstateSettings.regionFlags = m_regInfo.EstateSettings.regionFlags | + Simulator.RegionFlags.NoFly; + } + + if (convertParamStringToBool(packet.ParamList[2].Parameter)) + { + m_regInfo.EstateSettings.regionFlags = m_regInfo.EstateSettings.regionFlags | + Simulator.RegionFlags.AllowDamage; + } + + if (convertParamStringToBool(packet.ParamList[3].Parameter) == false) + { + m_regInfo.EstateSettings.regionFlags = m_regInfo.EstateSettings.regionFlags | + Simulator.RegionFlags.BlockLandResell; + } + + + int tempMaxAgents = + Convert.ToInt16(Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[4].Parameter))); + m_regInfo.EstateSettings.maxAgents = (byte) tempMaxAgents; + + float tempObjectBonusFactor = + (float) Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[5].Parameter)); + m_regInfo.EstateSettings.objectBonusFactor = tempObjectBonusFactor; + + int tempMatureLevel = Convert.ToInt16(Helpers.FieldToUTF8String(packet.ParamList[6].Parameter)); + m_regInfo.EstateSettings.simAccess = (Simulator.SimAccess) tempMatureLevel; + + + if (convertParamStringToBool(packet.ParamList[7].Parameter)) + { + m_regInfo.EstateSettings.regionFlags = m_regInfo.EstateSettings.regionFlags | + Simulator.RegionFlags.RestrictPushObject; + } + + if (convertParamStringToBool(packet.ParamList[8].Parameter)) + { + m_regInfo.EstateSettings.regionFlags = m_regInfo.EstateSettings.regionFlags | + Simulator.RegionFlags.AllowParcelChanges; + } + + sendRegionInfoPacketToAll(); + } + } + + private void estateSetRegionTerrainHandler(EstateOwnerMessagePacket packet) + { + if (packet.ParamList.Length != 9) + { + m_log.Error("EstateOwnerMessage: SetRegionTerrain method has a ParamList of invalid length"); + } + else + { + try + { + string tmp; + tmp = Helpers.FieldToUTF8String(packet.ParamList[0].Parameter); + if (!tmp.Contains(".")) tmp += ".00"; + float WaterHeight = (float)Convert.ToDecimal(tmp); + tmp = Helpers.FieldToUTF8String(packet.ParamList[1].Parameter); + if (!tmp.Contains(".")) tmp += ".00"; + float TerrainRaiseLimit = (float)Convert.ToDecimal(tmp); + tmp = Helpers.FieldToUTF8String(packet.ParamList[2].Parameter); + if (!tmp.Contains(".")) tmp += ".00"; + float TerrainLowerLimit = (float)Convert.ToDecimal(tmp); + bool UseFixedSun = convertParamStringToBool(packet.ParamList[4].Parameter); + float SunHour = (float)Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[5].Parameter)); + + setRegionSettings(WaterHeight, TerrainRaiseLimit, TerrainLowerLimit, UseFixedSun, SunHour); + + sendRegionInfoPacketToAll(); + } + catch (Exception ex) + { + m_log.Error("EstateManager: Exception while setting terrain settings: \n" + packet.ToString() + "\n" + ex.ToString()); + } + } + } + + private void estateTextureHeightsHandler(EstateOwnerMessagePacket packet) + { + foreach (EstateOwnerMessagePacket.ParamListBlock block in packet.ParamList) + { + string s = Helpers.FieldToUTF8String(block.Parameter); + string[] splitField = s.Split(' '); + if (splitField.Length == 3) + { + Int16 corner = Convert.ToInt16(splitField[0]); + float lowValue = (float) Convert.ToDouble(splitField[1].Replace('.', ',')); + float highValue = (float) Convert.ToDouble(splitField[2].Replace('.', ',')); + + setEstateTextureRange(corner, lowValue, highValue); + } + } + } + + private void estateTextureDetailHandler(EstateOwnerMessagePacket packet) + { + foreach (EstateOwnerMessagePacket.ParamListBlock block in packet.ParamList) + { + string s = Helpers.FieldToUTF8String(block.Parameter); + string[] splitField = s.Split(' '); + if (splitField.Length == 2) + { + Int16 corner = Convert.ToInt16(splitField[0]); + LLUUID textureUUID = new LLUUID(splitField[1]); + + setTerrainTexture(corner, textureUUID); + } + } + } + + private void estateTextureBaseHandler(EstateOwnerMessagePacket packet) + { + foreach (EstateOwnerMessagePacket.ParamListBlock block in packet.ParamList) + { + string s = Helpers.FieldToUTF8String(block.Parameter); + string[] splitField = s.Split(' '); + if (splitField.Length == 2) + { + LLUUID tempUUID = new LLUUID(splitField[1]); + switch (Convert.ToInt16(splitField[0])) + { + case 0: + m_regInfo.EstateSettings.terrainBase0 = tempUUID; + break; + case 1: + m_regInfo.EstateSettings.terrainBase1 = tempUUID; + break; + case 2: + m_regInfo.EstateSettings.terrainBase2 = tempUUID; + break; + case 3: + m_regInfo.EstateSettings.terrainBase3 = tempUUID; + break; + } + } + } + } + + private void estateRestartSim(EstateOwnerMessagePacket packet) + { + // There's only 1 block in the estateResetSim.. and that's the number of seconds till restart. + foreach (EstateOwnerMessagePacket.ParamListBlock block in packet.ParamList) + { + float timeSeconds = 0; + Helpers.TryParse(Helpers.FieldToUTF8String(block.Parameter), out timeSeconds); + timeSeconds = (int)timeSeconds; + m_scene.Restart(timeSeconds); + + } + } + + private void EstateChangeCovenant(EstateOwnerMessagePacket packet) + { + foreach (EstateOwnerMessagePacket.ParamListBlock block in packet.ParamList) + { + LLUUID newCovenantID = new LLUUID(Helpers.FieldToUTF8String(block.Parameter)); + m_regInfo.CovenantID = newCovenantID; + m_scene.RegionInfo.SaveEstatecovenantUUID(newCovenantID); + } + } + + public void HandleRegionInfoRequest(IClientAPI client, LLUUID sessionID) + { + RegionInfoPacket rinfopack = new RegionInfoPacket(); + RegionInfoPacket.RegionInfoBlock rinfoblk = new RegionInfoPacket.RegionInfoBlock(); + + rinfoblk.BillableFactor = 0; + rinfoblk.EstateID = 02; + rinfoblk.MaxAgents = 100; + rinfoblk.ObjectBonusFactor = 1.0f; + rinfoblk.ParentEstateID = 0; + rinfoblk.PricePerMeter = 0; + rinfoblk.RedirectGridX = 0; + rinfoblk.RedirectGridY = 0; + rinfoblk.RegionFlags = (uint) m_regInfo.EstateSettings.regionFlags; + rinfoblk.SimAccess = (byte) m_regInfo.EstateSettings.simAccess; + rinfoblk.SunHour = m_regInfo.EstateSettings.sunHour; + rinfoblk.TerrainLowerLimit = 20; + rinfoblk.TerrainRaiseLimit = 20; + rinfoblk.UseEstateSun = true; + rinfoblk.WaterHeight = m_regInfo.EstateSettings.waterHeight; + rinfoblk.SimName = Helpers.StringToField(m_regInfo.RegionName); + + rinfopack.RegionInfo = rinfoblk; + + client.OutPacket(rinfopack, ThrottleOutPacketType.Task); + } + + public void HandleEstateCovenantRequest(IClientAPI client, LLUUID sessionID) + { + EstateCovenantReplyPacket einfopack = new EstateCovenantReplyPacket(); + EstateCovenantReplyPacket.DataBlock edata = new EstateCovenantReplyPacket.DataBlock(); + edata.CovenantID = m_regInfo.CovenantID; + edata.CovenantTimestamp = 0; + edata.EstateOwnerID = m_regInfo.MasterAvatarAssignedUUID; + edata.EstateName = + Helpers.StringToField(m_regInfo.MasterAvatarFirstName + " " + m_regInfo.MasterAvatarLastName); + einfopack.Data = edata; + client.OutPacket(einfopack, ThrottleOutPacketType.Task); + } + + #endregion + + #region Outgoing Packets + + public void sendRegionInfoPacketToAll() + { + List avatars = m_scene.GetAvatars(); + + for (int i = 0; i < avatars.Count; i++) + { + sendRegionInfoPacket(avatars[i].ControllingClient); + } + } + + public void sendRegionHandshakeToAll() + { + m_scene.Broadcast( + sendRegionHandshake + ); + } + + public void sendRegionInfoPacket(IClientAPI remote_client) + { + Encoding _enc = Encoding.ASCII; + + AgentCircuitData circuitData = remote_client.RequestClientInfo(); + + RegionInfoPacket regionInfoPacket = new RegionInfoPacket(); + regionInfoPacket.AgentData.AgentID = circuitData.AgentID; + regionInfoPacket.AgentData.SessionID = circuitData.SessionID; + regionInfoPacket.RegionInfo.BillableFactor = m_regInfo.EstateSettings.billableFactor; + regionInfoPacket.RegionInfo.EstateID = m_regInfo.EstateSettings.estateID; + regionInfoPacket.RegionInfo.MaxAgents = m_regInfo.EstateSettings.maxAgents; + regionInfoPacket.RegionInfo.ObjectBonusFactor = m_regInfo.EstateSettings.objectBonusFactor; + regionInfoPacket.RegionInfo.ParentEstateID = m_regInfo.EstateSettings.parentEstateID; + regionInfoPacket.RegionInfo.PricePerMeter = m_regInfo.EstateSettings.pricePerMeter; + regionInfoPacket.RegionInfo.RedirectGridX = m_regInfo.EstateSettings.redirectGridX; + regionInfoPacket.RegionInfo.RedirectGridY = m_regInfo.EstateSettings.redirectGridY; + regionInfoPacket.RegionInfo.RegionFlags = (uint) m_regInfo.EstateSettings.regionFlags; + regionInfoPacket.RegionInfo.SimAccess = (byte) m_regInfo.EstateSettings.simAccess; + regionInfoPacket.RegionInfo.SimName = _enc.GetBytes(m_regInfo.RegionName); + regionInfoPacket.RegionInfo.SunHour = m_regInfo.EstateSettings.sunHour; + regionInfoPacket.RegionInfo.TerrainLowerLimit = m_regInfo.EstateSettings.terrainLowerLimit; + regionInfoPacket.RegionInfo.TerrainRaiseLimit = m_regInfo.EstateSettings.terrainRaiseLimit; + regionInfoPacket.RegionInfo.UseEstateSun = !m_regInfo.EstateSettings.useFixedSun; + regionInfoPacket.RegionInfo.WaterHeight = m_regInfo.EstateSettings.waterHeight; + + remote_client.OutPacket(regionInfoPacket, ThrottleOutPacketType.Task); + } + + public void sendRegionHandshake(IClientAPI remoteClient) + { + remoteClient.SendRegionHandshake(m_regInfo); + } + + #endregion + } +} diff --git a/OpenSim/Region/Environment/InstantMessageReceiver.cs b/OpenSim/Region/Environment/InstantMessageReceiver.cs index 829a68a49b..5bf6779736 100644 --- a/OpenSim/Region/Environment/InstantMessageReceiver.cs +++ b/OpenSim/Region/Environment/InstantMessageReceiver.cs @@ -1,28 +1,56 @@ -using System; - -namespace OpenSim.Region.Environment -{ - /// - /// Bit Vector for Which Modules to send an instant message to from the Scene or an Associated Module - /// - - // This prevents the Modules from sending Instant messages to other modules through the scene - // and then receiving the same messages - - // This is mostly here because on LLSL and the SecondLife Client, IMs,Groups and friends are linked - // inseparably - - [Flags] - public enum InstantMessageReceiver : uint - { - /// None of them.. here for posterity and amusement - None = 0, - /// The IM Module - IMModule = 0x00000001, - /// The Friends Module - FriendsModule = 0x00000002, - /// The Groups Module - GroupsModule = 0x00000004 - - } -} +/* +* Copyright (c) Contributors, http://opensimulator.org/ +* See CONTRIBUTORS.TXT for a full list of copyright holders. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the OpenSim Project nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ + +using System; + +namespace OpenSim.Region.Environment +{ + /// + /// Bit Vector for Which Modules to send an instant message to from the Scene or an Associated Module + /// + + // This prevents the Modules from sending Instant messages to other modules through the scene + // and then receiving the same messages + + // This is mostly here because on LLSL and the SecondLife Client, IMs,Groups and friends are linked + // inseparably + + [Flags] + public enum InstantMessageReceiver : uint + { + /// None of them.. here for posterity and amusement + None = 0, + /// The IM Module + IMModule = 0x00000001, + /// The Friends Module + FriendsModule = 0x00000002, + /// The Groups Module + GroupsModule = 0x00000004 + + } +} diff --git a/OpenSim/Region/Environment/ModuleLoader.cs b/OpenSim/Region/Environment/ModuleLoader.cs index 35f4eb8b48..2037da9781 100644 --- a/OpenSim/Region/Environment/ModuleLoader.cs +++ b/OpenSim/Region/Environment/ModuleLoader.cs @@ -1,297 +1,316 @@ -/* -* Copyright (c) Contributors, http://opensimulator.org/ -* See CONTRIBUTORS.TXT for a full list of copyright holders. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the OpenSim Project nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*/ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Nini.Config; -using OpenSim.Framework.Console; -using OpenSim.Region.Environment.Interfaces; -using OpenSim.Region.Environment.Modules; -using OpenSim.Region.Environment.Scenes; - -namespace OpenSim.Region.Environment -{ - public class ModuleLoader - { - public Dictionary LoadedAssemblys = new Dictionary(); - - private readonly List m_loadedModules = new List(); - private Dictionary m_loadedSharedModules = new Dictionary(); - private readonly LogBase m_log; - private readonly IConfigSource m_config; - - public ModuleLoader(LogBase log, IConfigSource config) - { - m_log = log; - m_config = config; - } - - public IRegionModule[] GetLoadedSharedModules - { - get - { - IRegionModule[] regionModules = new IRegionModule[m_loadedSharedModules.Count]; - m_loadedSharedModules.Values.CopyTo(regionModules, 0); - return regionModules; - } - } - - public void PickupModules(Scene scene, string moduleDir) - { - DirectoryInfo dir = new DirectoryInfo(moduleDir); - - foreach (FileInfo fileInfo in dir.GetFiles("*.dll")) - { - LoadRegionModules(fileInfo.FullName, scene); - } - } - - public void LoadDefaultSharedModules() - { - DynamicTextureModule dynamicModule = new DynamicTextureModule(); - if (m_loadedSharedModules.ContainsKey(dynamicModule.Name)) - { - m_log.Error("MODULES", "Module name \"{0}\" already exists in module list. Module type {1} not added!", dynamicModule.Name, "DynamicTextureModule"); - } - else - { - m_loadedSharedModules.Add(dynamicModule.Name, dynamicModule); - } - - ChatModule chat = new ChatModule(); - if (m_loadedSharedModules.ContainsKey(chat.Name)) - { - m_log.Error("MODULES", "Module name \"{0}\" already exists in module list. Module type {1} not added!", chat.Name, "ChatModule"); - } - else - { - m_loadedSharedModules.Add(chat.Name, chat); - } - - InstantMessageModule imMod = new InstantMessageModule(); - if (m_loadedSharedModules.ContainsKey(imMod.Name)) - { - m_log.Error("MODULES", "Module name \"{0}\" already exists in module list. Module type {1} not added!", imMod.Name, "InstantMessageModule"); - } - else - { - m_loadedSharedModules.Add(imMod.Name, imMod); - } - - LoadImageURLModule loadMod = new LoadImageURLModule(); - if (m_loadedSharedModules.ContainsKey(loadMod.Name)) - { - m_log.Error("MODULES", "Module name \"{0}\" already exists in module list. Module type {1} not added!", loadMod.Name, "LoadImageURLModule"); - } - else - { - m_loadedSharedModules.Add(loadMod.Name, loadMod); - } - - AvatarFactoryModule avatarFactory = new AvatarFactoryModule(); - if (m_loadedSharedModules.ContainsKey(avatarFactory.Name)) - { - m_log.Error("MODULES", "Module name \"{0}\" already exists in module list. Module type {1} not added!", avatarFactory.Name, "AvarFactoryModule"); - } - else - { - m_loadedSharedModules.Add(avatarFactory.Name, avatarFactory); - } - - XMLRPCModule xmlRpcMod = new XMLRPCModule(); - if (m_loadedSharedModules.ContainsKey(xmlRpcMod.Name)) - { - m_log.Error("MODULES", "Module name \"{0}\" already exists in module list. Module type {1} not added!", xmlRpcMod.Name, "XMLRPCModule"); - } - else - { - m_loadedSharedModules.Add(xmlRpcMod.Name, xmlRpcMod); - } - //TextureDownloadModule textureModule = new TextureDownloadModule(); - //LoadedSharedModules.Add(textureModule.Name, textureModule); - } - - public void InitialiseSharedModules(Scene scene) - { - foreach (IRegionModule module in m_loadedSharedModules.Values) - { - module.Initialise(scene, m_config); - scene.AddModule(module.Name, module); //should be doing this? - } - } - - public void InitializeModule(IRegionModule module, Scene scene) - { - module.Initialise(scene, m_config); - scene.AddModule(module.Name, module); - m_loadedModules.Add(module); - } - - /// - /// Loads/initialises a Module instance that can be used by multiple Regions - /// - /// - /// - public void LoadSharedModule(string dllName, string moduleName) - { - IRegionModule module = LoadModule(dllName, moduleName); - - if (module != null) - LoadSharedModule(module); - } - - /// - /// Loads/initialises a Module instance that can be used by multiple Regions - /// - /// - public void LoadSharedModule(IRegionModule module) - { - if (!m_loadedSharedModules.ContainsKey(module.Name)) - { - m_loadedSharedModules.Add(module.Name, module); - } - } - - public void LoadRegionModules(string dllName, Scene scene) - { - IRegionModule[] modules = LoadModules(dllName); - - if (modules.Length > 0) - { - m_log.Verbose("MODULES", "Found Module Library [{0}]", dllName); - foreach (IRegionModule module in modules) - { - if (!module.IsSharedModule) - { - m_log.Verbose("MODULES", " [{0}]: Initializing.", module.Name); - InitializeModule(module, scene); - } - else - { - m_log.Verbose("MODULES", " [{0}]: Loading Shared Module.", module.Name); - LoadSharedModule(module); - } - } - } - } - - public void LoadRegionModule(string dllName, string moduleName, Scene scene) - { - IRegionModule module = LoadModule(dllName, moduleName); - if (module != null) - { - InitializeModule(module, scene); - } - } - - /// - /// Loads a external Module (if not already loaded) and creates a new instance of it. - /// - /// - /// - public IRegionModule LoadModule(string dllName, string moduleName) - { - IRegionModule[] modules = LoadModules(dllName); - - foreach (IRegionModule module in modules) - { - if ((module != null) && (module.Name == moduleName)) - { - return module; - } - } - - return null; - } - - public IRegionModule[] LoadModules(string dllName) - { - List modules = new List(); - - Assembly pluginAssembly; - if (!LoadedAssemblys.TryGetValue(dllName, out pluginAssembly)) - { - try - { - pluginAssembly = Assembly.LoadFrom(dllName); - LoadedAssemblys.Add(dllName, pluginAssembly); - } - catch (BadImageFormatException) - { - //m_log.Verbose("MODULES", "The file [{0}] is not a module assembly.", e.FileName); - } - } - - if (pluginAssembly != null) - { - try - { - foreach (Type pluginType in pluginAssembly.GetTypes()) - { - if (pluginType.IsPublic) - { - if (!pluginType.IsAbstract) - { - if (pluginType.GetInterface("IRegionModule") != null) - { - modules.Add((IRegionModule)Activator.CreateInstance(pluginType)); - } - } - } - } - } - catch (ReflectionTypeLoadException) - { - m_log.Verbose("MODULES", "Could not load types for [{0}].", pluginAssembly.FullName); - } - } - - return modules.ToArray(); - } - - public void PostInitialise() - { - foreach (IRegionModule module in m_loadedSharedModules.Values) - { - module.PostInitialise(); - } - - foreach (IRegionModule module in m_loadedModules) - { - module.PostInitialise(); - } - } - - public void ClearCache() - { - LoadedAssemblys.Clear(); - } - } -} \ No newline at end of file +/* +* Copyright (c) Contributors, http://opensimulator.org/ +* See CONTRIBUTORS.TXT for a full list of copyright holders. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the OpenSim Project nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework.Console; +using OpenSim.Region.Environment.Interfaces; +using OpenSim.Region.Environment.Modules; +using OpenSim.Region.Environment.Scenes; + +namespace OpenSim.Region.Environment +{ + public class ModuleLoader + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + public Dictionary LoadedAssemblys = new Dictionary(); + + private readonly List m_loadedModules = new List(); + private readonly Dictionary m_loadedSharedModules = new Dictionary(); + private readonly IConfigSource m_config; + + public ModuleLoader(IConfigSource config) + { + m_config = config; + } + + public IRegionModule[] GetLoadedSharedModules + { + get + { + IRegionModule[] regionModules = new IRegionModule[m_loadedSharedModules.Count]; + m_loadedSharedModules.Values.CopyTo(regionModules, 0); + return regionModules; + } + } + + public void PickupModules(Scene scene, string moduleDir) + { + DirectoryInfo dir = new DirectoryInfo(moduleDir); + + foreach (FileInfo fileInfo in dir.GetFiles("*.dll")) + { + LoadRegionModules(fileInfo.FullName, scene); + } + } + + public void LoadDefaultSharedModules() + { + DynamicTextureModule dynamicModule = new DynamicTextureModule(); + if (m_loadedSharedModules.ContainsKey(dynamicModule.Name)) + { + m_log.ErrorFormat("[MODULES]: Module name \"{0}\" already exists in module list. Module type {1} not added!", dynamicModule.Name, "DynamicTextureModule"); + } + else + { + m_loadedSharedModules.Add(dynamicModule.Name, dynamicModule); + } + + ChatModule chat = new ChatModule(); + if (m_loadedSharedModules.ContainsKey(chat.Name)) + { + m_log.ErrorFormat("[MODULES]: Module name \"{0}\" already exists in module list. Module type {1} not added!", chat.Name, "ChatModule"); + } + else + { + m_loadedSharedModules.Add(chat.Name, chat); + } + + InstantMessageModule imMod = new InstantMessageModule(); + if (m_loadedSharedModules.ContainsKey(imMod.Name)) + { + m_log.ErrorFormat("[MODULES]: Module name \"{0}\" already exists in module list. Module type {1} not added!", imMod.Name, "InstantMessageModule"); + } + else + { + m_loadedSharedModules.Add(imMod.Name, imMod); + } + + LoadImageURLModule loadMod = new LoadImageURLModule(); + if (m_loadedSharedModules.ContainsKey(loadMod.Name)) + { + m_log.ErrorFormat("[MODULES]: Module name \"{0}\" already exists in module list. Module type {1} not added!", loadMod.Name, "LoadImageURLModule"); + } + else + { + m_loadedSharedModules.Add(loadMod.Name, loadMod); + } + + AvatarFactoryModule avatarFactory = new AvatarFactoryModule(); + if (m_loadedSharedModules.ContainsKey(avatarFactory.Name)) + { + m_log.ErrorFormat("[MODULES]: Module name \"{0}\" already exists in module list. Module type {1} not added!", avatarFactory.Name, "AvarFactoryModule"); + } + else + { + m_loadedSharedModules.Add(avatarFactory.Name, avatarFactory); + } + + XMLRPCModule xmlRpcMod = new XMLRPCModule(); + if (m_loadedSharedModules.ContainsKey(xmlRpcMod.Name)) + { + m_log.ErrorFormat("[MODULES]: Module name \"{0}\" already exists in module list. Module type {1} not added!", xmlRpcMod.Name, "XMLRPCModule"); + } + else + { + m_loadedSharedModules.Add(xmlRpcMod.Name, xmlRpcMod); + } + //TextureDownloadModule textureModule = new TextureDownloadModule(); + + //LoadedSharedModules.Add(textureModule.Name, textureModule); + + AgentAssetTransactionModule transactionsModule = new AgentAssetTransactionModule(); + if (m_loadedSharedModules.ContainsKey(transactionsModule.Name)) + { + m_log.ErrorFormat("[MODULES]: Module name \"{0}\" already exists in module list. Module type {1} not added!", xmlRpcMod.Name, "XMLRPCModule"); + } + else + { + m_loadedSharedModules.Add(transactionsModule.Name, transactionsModule); + } + + } + + public void InitialiseSharedModules(Scene scene) + { + foreach (IRegionModule module in m_loadedSharedModules.Values) + { + module.Initialise(scene, m_config); + scene.AddModule(module.Name, module); //should be doing this? + } + } + + public void InitializeModule(IRegionModule module, Scene scene) + { + module.Initialise(scene, m_config); + scene.AddModule(module.Name, module); + m_loadedModules.Add(module); + } + + /// + /// Loads/initialises a Module instance that can be used by multiple Regions + /// + /// + /// + public void LoadSharedModule(string dllName, string moduleName) + { + IRegionModule module = LoadModule(dllName, moduleName); + + if (module != null) + LoadSharedModule(module); + } + + /// + /// Loads/initialises a Module instance that can be used by multiple Regions + /// + /// + public void LoadSharedModule(IRegionModule module) + { + if (!m_loadedSharedModules.ContainsKey(module.Name)) + { + m_loadedSharedModules.Add(module.Name, module); + } + } + + public void LoadRegionModules(string dllName, Scene scene) + { + IRegionModule[] modules = LoadModules(dllName); + + if (modules.Length > 0) + { + m_log.InfoFormat("[MODULES]: Found Module Library [{0}]", dllName); + foreach (IRegionModule module in modules) + { + if (!module.IsSharedModule) + { + m_log.InfoFormat("[MODULES]: [{0}]: Initializing.", module.Name); + InitializeModule(module, scene); + } + else + { + m_log.InfoFormat("[MODULES]: [{0}]: Loading Shared Module.", module.Name); + LoadSharedModule(module); + } + } + } + } + + public void LoadRegionModule(string dllName, string moduleName, Scene scene) + { + IRegionModule module = LoadModule(dllName, moduleName); + if (module != null) + { + InitializeModule(module, scene); + } + } + + /// + /// Loads a external Module (if not already loaded) and creates a new instance of it. + /// + /// + /// + public IRegionModule LoadModule(string dllName, string moduleName) + { + IRegionModule[] modules = LoadModules(dllName); + + foreach (IRegionModule module in modules) + { + if ((module != null) && (module.Name == moduleName)) + { + return module; + } + } + + return null; + } + + public IRegionModule[] LoadModules(string dllName) + { + List modules = new List(); + + Assembly pluginAssembly; + if (!LoadedAssemblys.TryGetValue(dllName, out pluginAssembly)) + { + try + { + pluginAssembly = Assembly.LoadFrom(dllName); + LoadedAssemblys.Add(dllName, pluginAssembly); + } + catch (BadImageFormatException) + { + //m_log.InfoFormat("[MODULES]: The file [{0}] is not a module assembly.", e.FileName); + } + } + + if (pluginAssembly != null) + { + try + { + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (pluginType.IsPublic) + { + if (!pluginType.IsAbstract) + { + if (pluginType.GetInterface("IRegionModule") != null) + { + modules.Add((IRegionModule)Activator.CreateInstance(pluginType)); + } + } + } + } + } + catch (ReflectionTypeLoadException) + { + m_log.InfoFormat("[MODULES]: Could not load types for [{0}].", pluginAssembly.FullName); + } + } + + return modules.ToArray(); + } + + public void PostInitialise() + { + foreach (IRegionModule module in m_loadedSharedModules.Values) + { + module.PostInitialise(); + } + + foreach (IRegionModule module in m_loadedModules) + { + module.PostInitialise(); + } + } + + public void ClearCache() + { + LoadedAssemblys.Clear(); + } + + public void UnloadModule(IRegionModule rm) + { + rm.Close(); + + m_loadedModules.Remove(rm); + } + } +} diff --git a/OpenSim/Region/Environment/PermissionManager.cs b/OpenSim/Region/Environment/PermissionManager.cs index 74e397b94a..9bcbfd1151 100644 --- a/OpenSim/Region/Environment/PermissionManager.cs +++ b/OpenSim/Region/Environment/PermissionManager.cs @@ -1,506 +1,624 @@ -/* -* Copyright (c) Contributors, http://opensimulator.org/ -* See CONTRIBUTORS.TXT for a full list of copyright holders. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the OpenSim Project nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*/ - -using libsecondlife; -using OpenSim.Region.Environment.LandManagement; -using OpenSim.Region.Environment.Scenes; - -namespace OpenSim.Region.Environment -{ - public class PermissionManager - { - protected Scene m_scene; - - // These are here for testing. They will be taken out - private uint PERM_ALL = (uint) 2147483647; - private uint PERM_COPY = (uint) 32768; - private uint PERM_MODIFY = (uint) 16384; - private uint PERM_MOVE = (uint) 524288; - private uint PERM_TRANS = (uint) 8192; - // Bypasses the permissions engine (always returns OK) - // disable in any production environment - // TODO: Change this to false when permissions are a desired default - // TODO: Move to configuration option. - private bool m_bypassPermissions = true; - - public bool BypassPermissions - { - get { return m_bypassPermissions; } - set { m_bypassPermissions = value; } - } - - public PermissionManager() - { - } - - public PermissionManager(Scene scene) - { - m_scene = scene; - } - - public void Initialise(Scene scene) - { - m_scene = scene; - } - - protected virtual void SendPermissionError(LLUUID user, string reason) - { - m_scene.EventManager.TriggerPermissionError(user, reason); - } - - protected virtual bool IsAdministrator(LLUUID user) - { - if (m_bypassPermissions) - { - return true; - } - - return m_scene.RegionInfo.MasterAvatarAssignedUUID == user; - } - - public virtual bool IsEstateManager(LLUUID user) - { - if (m_bypassPermissions) - { - return true; - } - - LLUUID[] estatemanagers = m_scene.RegionInfo.EstateSettings.estateManagers; - for (int i = 0; i < estatemanagers.Length; i++) - { - if (estatemanagers[i] == user) - return true; - } - - return false; - } - - protected virtual bool IsGridUser(LLUUID user) - { - return true; - } - - protected virtual bool IsGuest(LLUUID user) - { - return false; - } - - public virtual bool CanRezObject(LLUUID user, LLVector3 position) - { - bool permission = false; - - string reason = "Insufficient permission"; - - Land land = m_scene.LandManager.getLandObject(position.X, position.Y); - if (land == null) return false; - - if ((land.landData.landFlags & ((int) Parcel.ParcelFlags.CreateObjects)) == - (int) Parcel.ParcelFlags.CreateObjects) - permission = true; - - //TODO: check for group rights - - if (IsAdministrator(user)) - { - permission = true; - } - else - { - reason = "Not an administrator"; - } - - if (GenericParcelPermission(user, position)) - { - permission = true; - } - else - { - reason = "Not the parcel owner"; - } - - if (!permission) - SendPermissionError(user, reason); - - return permission; - } - - #region Object Permissions - - public virtual uint GenerateClientFlags(LLUUID user, LLUUID objID) - { - if (!m_scene.Entities.ContainsKey(objID)) - { - return 0; - } - - // If it's not an object, we cant edit it. - if (!(m_scene.Entities[objID] is SceneObjectGroup)) - { - return 0; - } - - SceneObjectGroup task = (SceneObjectGroup) m_scene.Entities[objID]; - LLUUID taskOwner = null; - // Added this because at this point in time it wouldn't be wise for - // the administrator object permissions to take effect. - LLUUID objectOwner = task.OwnerID; - - //return task.RootPart.ObjectFlags;task.RootPart.ObjectFlags | - - uint OwnerMask = task.RootPart.ObjectFlags | task.RootPart.OwnerMask; - uint GroupMask = task.RootPart.ObjectFlags | task.RootPart.GroupMask; - uint EveryoneMask = task.RootPart.ObjectFlags | task.RootPart.EveryoneMask; - - if (m_bypassPermissions) - return OwnerMask; - else //rex - { - EveryoneMask &= ~(uint)LLObject.ObjectFlags.ObjectModify; - } - - // Object owners should be able to edit their own content - if (user == objectOwner) - return OwnerMask; - - // Users should be able to edit what is over their land. - Land parcel = m_scene.LandManager.getLandObject(task.AbsolutePosition.X, task.AbsolutePosition.Y); - if (parcel != null && parcel.landData.ownerID == user) - return OwnerMask; - - // Estate users should be able to edit anything in the sim - if (IsEstateManager(user)) - return OwnerMask; - - // Admin objects should not be editable by the above - if (IsAdministrator(taskOwner)) - return EveryoneMask; - - // Admin should be able to edit anything in the sim (including admin objects) - if (IsAdministrator(user)) - return OwnerMask; - - if (((EveryoneMask & PERM_MOVE) != 0) || ((EveryoneMask & PERM_COPY) != 0)) - { - if ((EveryoneMask & PERM_MOVE) != 0) - OwnerMask &= ~PERM_MOVE; - - if ((EveryoneMask & PERM_COPY) != 0) - OwnerMask &= ~PERM_COPY; - - OwnerMask &= ~PERM_MODIFY; - OwnerMask &= ~PERM_TRANS; - - return OwnerMask; - } - return EveryoneMask; - } - - protected virtual bool GenericObjectPermission(LLUUID user, LLUUID objId) - { - // Default: deny - bool permission = false; - - if (!m_scene.Entities.ContainsKey(objId)) - { - return false; - } - - // If it's not an object, we cant edit it. - if (!(m_scene.Entities[objId] is SceneObjectGroup)) - { - return false; - } - - SceneObjectGroup task = (SceneObjectGroup) m_scene.Entities[objId]; - LLUUID taskOwner = null; - // Added this because at this point in time it wouldn't be wise for - // the administrator object permissions to take effect. - LLUUID objectOwner = task.OwnerID; - - // Object owners should be able to edit their own content - if (user == objectOwner) - permission = true; - - // Users should be able to edit what is over their land. - Land parcel = m_scene.LandManager.getLandObject(task.AbsolutePosition.X, task.AbsolutePosition.Y); - if (parcel != null && parcel.landData.ownerID == user) - permission = true; - - // Estate users should be able to edit anything in the sim - if (IsEstateManager(user)) - permission = true; - - // Admin objects should not be editable by the above - if (IsAdministrator(taskOwner)) - permission = false; - - // Admin should be able to edit anything in the sim (including admin objects) - if (IsAdministrator(user)) - permission = true; - - return permission; - } - - /// - /// Permissions check - can user delete an object? - /// - /// User attempting the delete - /// Target object - /// Has permission? - public virtual bool CanDeRezObject(LLUUID user, LLUUID obj) - { - return GenericObjectPermission(user, obj); - } - - public virtual bool CanEditObject(LLUUID user, LLUUID obj) - { - return GenericObjectPermission(user, obj); - } - - public virtual bool CanEditObjectPosition(LLUUID user, LLUUID obj) - { - bool permission = GenericObjectPermission(user, obj); - if (!permission) - { - if (!m_scene.Entities.ContainsKey(obj)) - { - return false; - } - - // If it's not an object, we cant edit it. - if (!(m_scene.Entities[obj] is SceneObjectGroup)) - { - return false; - } - - SceneObjectGroup task = (SceneObjectGroup) m_scene.Entities[obj]; - LLUUID taskOwner = null; - // Added this because at this point in time it wouldn't be wise for - // the administrator object permissions to take effect. - LLUUID objectOwner = task.OwnerID; - if ((task.RootPart.EveryoneMask & PERM_MOVE) != 0) - permission = true; - } - return permission; - } - - public virtual bool CanCopyObject(LLUUID user, LLUUID obj) - { - bool permission = GenericObjectPermission(user, obj); - if (!permission) - { - if (!m_scene.Entities.ContainsKey(obj)) - { - return false; - } - - // If it's not an object, we cant edit it. - if (!(m_scene.Entities[obj] is SceneObjectGroup)) - { - return false; - } - - SceneObjectGroup task = (SceneObjectGroup) m_scene.Entities[obj]; - LLUUID taskOwner = null; - // Added this because at this point in time it wouldn't be wise for - // the administrator object permissions to take effect. - LLUUID objectOwner = task.OwnerID; - if ((task.RootPart.EveryoneMask & PERM_COPY) != 0) - permission = true; - } - return permission; - } - - public virtual bool CanReturnObject(LLUUID user, LLUUID obj) - { - return GenericObjectPermission(user, obj); - } - - #endregion - - #region Communication Permissions - - public virtual bool GenericCommunicationPermission(LLUUID user, LLUUID target) - { - bool permission = false; - string reason = "Only registered users may communicate with another account."; - - if (IsGridUser(user)) - permission = true; - - if (!IsGridUser(user)) - { - permission = false; - reason = "The person that you are messaging is not a registered user."; - } - if (IsAdministrator(user)) - permission = true; - - if (IsEstateManager(user)) - permission = true; - - if (!permission) - SendPermissionError(user, reason); - - return permission; - } - - public virtual bool CanInstantMessage(LLUUID user, LLUUID target) - { - return GenericCommunicationPermission(user, target); - } - - public virtual bool CanInventoryTransfer(LLUUID user, LLUUID target) - { - return GenericCommunicationPermission(user, target); - } - - #endregion - - public virtual bool CanEditScript(LLUUID user, LLUUID script) - { - return IsAdministrator(user); - } - - public virtual bool CanRunScript(LLUUID user, LLUUID script) - { - return IsAdministrator(user); - } - - public virtual bool CanTerraform(LLUUID user, LLVector3 position) - { - bool permission = false; - - // Estate override - if (GenericEstatePermission(user)) - permission = true; - - float X = position.X; - float Y = position.Y; - - if (X > 255) - X = 255; - if (Y > 255) - Y = 255; - if (X < 0) - X = 0; - if (Y < 0) - Y = 0; - - // Land owner can terraform too - Land parcel = m_scene.LandManager.getLandObject(X, Y); - if (parcel != null && GenericParcelPermission(user, parcel)) - permission = true; - - if (!permission) - SendPermissionError(user, "Not authorized to terraform at this location."); - - return permission; - } - - #region Estate Permissions - - public virtual bool GenericEstatePermission(LLUUID user) - { - // Default: deny - bool permission = false; - - // Estate admins should be able to use estate tools - if (IsEstateManager(user)) - permission = true; - - // Administrators always have permission - if (IsAdministrator(user)) - permission = true; - - return permission; - } - - public virtual bool CanEditEstateTerrain(LLUUID user) - { - return GenericEstatePermission(user); - } - - public virtual bool CanRestartSim(LLUUID user) - { - // Since this is potentially going on a grid... - - return GenericEstatePermission(user); - //return m_scene.RegionInfo.MasterAvatarAssignedUUID == user; - } - - #endregion - - #region Parcel Permissions - - protected virtual bool GenericParcelPermission(LLUUID user, Land parcel) - { - bool permission = false; - - if (parcel.landData.ownerID == user) - permission = true; - - if (parcel.landData.isGroupOwned) - { - // TODO: Need to do some extra checks here. Requires group code. - } - - if (IsEstateManager(user)) - permission = true; - - if (IsAdministrator(user)) - permission = true; - - return permission; - } - - protected virtual bool GenericParcelPermission(LLUUID user, LLVector3 pos) - { - Land parcel = m_scene.LandManager.getLandObject(pos.X, pos.Y); - if (parcel == null) return false; - return GenericParcelPermission(user, parcel); - } - - public virtual bool CanEditParcel(LLUUID user, Land parcel) - { - return GenericParcelPermission(user, parcel); - } - - public virtual bool CanSellParcel(LLUUID user, Land parcel) - { - return GenericParcelPermission(user, parcel); - } - - public virtual bool CanAbandonParcel(LLUUID user, Land parcel) - { - return GenericParcelPermission(user, parcel); - } - - #endregion - } -} \ No newline at end of file +/* +* Copyright (c) Contributors, http://opensimulator.org/ +* See CONTRIBUTORS.TXT for a full list of copyright holders. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the OpenSim Project nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ + +using libsecondlife; +using OpenSim.Region.Environment.LandManagement; +using OpenSim.Region.Environment.Scenes; + +namespace OpenSim.Region.Environment +{ + public class PermissionManager + { + protected Scene m_scene; + + // These are here for testing. They will be taken out + private uint PERM_ALL = (uint)2147483647; + private uint PERM_COPY = (uint)32768; + private uint PERM_MODIFY = (uint)16384; + private uint PERM_MOVE = (uint)524288; + private uint PERM_TRANS = (uint)8192; + private uint PERM_LOCKED = (uint)540672; + // Bypasses the permissions engine (always returns OK) + // disable in any production environment + // TODO: Change this to false when permissions are a desired default + // TODO: Move to configuration option. + private bool m_bypassPermissions = true; + + public bool BypassPermissions + { + get { return m_bypassPermissions; } + set { m_bypassPermissions = value; } + } + + public PermissionManager() + { + } + + public PermissionManager(Scene scene) + { + m_scene = scene; + } + + public void Initialise(Scene scene) + { + m_scene = scene; + } + + protected virtual void SendPermissionError(LLUUID user, string reason) + { + m_scene.EventManager.TriggerPermissionError(user, reason); + } + + protected virtual bool IsAdministrator(LLUUID user) + { + if (m_bypassPermissions) + { + return true; + } + + // If there is no master avatar, return false + if (m_scene.RegionInfo.MasterAvatarAssignedUUID != null) + { + return m_scene.RegionInfo.MasterAvatarAssignedUUID == user; + } + + return false; + } + + public virtual bool IsEstateManager(LLUUID user) + { + if (m_bypassPermissions) + { + return true; + } + if (user != null) + { + LLUUID[] estatemanagers = m_scene.RegionInfo.EstateSettings.estateManagers; + for (int i = 0; i < estatemanagers.Length; i++) + { + if (estatemanagers[i] == user) + return true; + } + } + // The below is commented out because logically it happens anyway. It's left in for readability + //else + //{ + //return false; + //} + + return false; + } + + protected virtual bool IsGridUser(LLUUID user) + { + return true; + } + + protected virtual bool IsGuest(LLUUID user) + { + return false; + } + + public virtual bool CanRezObject(LLUUID user, LLVector3 position) + { + bool permission = false; + + string reason = "Insufficient permission"; + + Land land = m_scene.LandManager.getLandObject(position.X, position.Y); + if (land == null) return false; + + if ((land.landData.landFlags & ((int)Parcel.ParcelFlags.CreateObjects)) == + (int)Parcel.ParcelFlags.CreateObjects) + permission = true; + + //TODO: check for group rights + + if (IsAdministrator(user)) + { + permission = true; + } + else + { + reason = "Not an administrator"; + } + + if (GenericParcelPermission(user, position)) + { + permission = true; + } + else + { + reason = "Not the parcel owner"; + } + + if (!permission) + SendPermissionError(user, reason); + + return permission; + } + + #region Object Permissions + + public virtual uint GenerateClientFlags(LLUUID user, LLUUID objID) + { + + // Here's the way this works, + // ObjectFlags and Permission flags are two different enumerations + // ObjectFlags, however, tells the client to change what it will allow the user to do. + // So, that means that all of the permissions type ObjectFlags are /temporary/ and only + // supposed to be set when customizing the objectflags for the client. + + // These temporary objectflags get computed and added in this function based on the + // Permission mask that's appropriate! + // Outside of this method, they should never be added to objectflags! + // -teravus + + if (!m_scene.Entities.ContainsKey(objID)) + { + return 0; + } + + // If it's not an object, we cant edit it. + if (!(m_scene.Entities[objID] is SceneObjectGroup)) + { + return 0; + } + + SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[objID]; + LLUUID objectOwner = task.OwnerID; + + uint objflags = task.RootPart.ObjectFlags; + + + // Remove any of the objectFlags that are temporary. These will get added back if appropriate + // in the next bit of code + + objflags &= (uint) + ~(LLObject.ObjectFlags.ObjectCopy | // Tells client you can copy the object + LLObject.ObjectFlags.ObjectModify | // tells client you can modify the object + LLObject.ObjectFlags.ObjectMove | // tells client that you can move the object (only, no mod) + LLObject.ObjectFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it + LLObject.ObjectFlags.ObjectYouOwner | // Tells client that you're the owner of the object + LLObject.ObjectFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set + ); + + // Creating the three ObjectFlags options for this method to choose from. + // Customize the OwnerMask + uint objectOwnerMask = ApplyObjectModifyMasks(task.RootPart.OwnerMask, objflags); + objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectYouOwner; + + // Customize the GroupMask + uint objectGroupMask = ApplyObjectModifyMasks(task.RootPart.GroupMask, objflags); + + // Customize the EveryoneMask + uint objectEveryoneMask = ApplyObjectModifyMasks(task.RootPart.EveryoneMask, objflags); + + + // Hack to allow collaboration until Groups and Group Permissions are implemented + if ((objectEveryoneMask & (uint)LLObject.ObjectFlags.ObjectMove) != 0) + objectEveryoneMask |= (uint)LLObject.ObjectFlags.ObjectModify; + + if (m_bypassPermissions) + return objectOwnerMask; + else //rex + { + EveryoneMask &= ~(uint)LLObject.ObjectFlags.ObjectModify; + } + + // Object owners should be able to edit their own content + if (user == objectOwner) + { + return objectOwnerMask; + } + + // Users should be able to edit what is over their land. + Land parcel = m_scene.LandManager.getLandObject(task.AbsolutePosition.X, task.AbsolutePosition.Y); + if (parcel != null && parcel.landData.ownerID == user) + return objectOwnerMask; + + // Admin objects should not be editable by the above + if (IsAdministrator(objectOwner)) + return objectEveryoneMask; + + // Estate users should be able to edit anything in the sim + if (IsEstateManager(user)) + return objectOwnerMask; + + + + // Admin should be able to edit anything in the sim (including admin objects) + if (IsAdministrator(user)) + return objectOwnerMask; + + + return objectEveryoneMask; + } + + + + private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask) + { + // We are adding the temporary objectflags to the object's objectflags based on the + // permission flag given. These change the F flags on the client. + + if ((setPermissionMask & (uint)PermissionMask.Copy) != 0) + { + objectFlagsMask |= (uint)LLObject.ObjectFlags.ObjectCopy; + } + + if ((setPermissionMask & (uint)PermissionMask.Move) != 0) + { + objectFlagsMask |= (uint)LLObject.ObjectFlags.ObjectMove; + } + + if ((setPermissionMask & (uint)PermissionMask.Modify) != 0) + { + objectFlagsMask |= (uint)LLObject.ObjectFlags.ObjectModify; + } + + if ((setPermissionMask & (uint)PermissionMask.Transfer) != 0) + { + objectFlagsMask |= (uint)LLObject.ObjectFlags.ObjectTransfer; + } + + return objectFlagsMask; + } + + protected virtual bool GenericObjectPermission(LLUUID currentUser, LLUUID objId) + { + // Default: deny + bool permission = false; + bool locked = false; + + if (!m_scene.Entities.ContainsKey(objId)) + { + return false; + } + + // If it's not an object, we cant edit it. + if ((!(m_scene.Entities[objId] is SceneObjectGroup))) + { + return false; + } + + + SceneObjectGroup group = (SceneObjectGroup)m_scene.Entities[objId]; + + LLUUID objectOwner = group.OwnerID; + locked = ((group.RootPart.OwnerMask & PERM_LOCKED) == 0); + + // People shouldn't be able to do anything with locked objects, except the Administrator + // The 'set permissions' runs through a different permission check, so when an object owner + // sets an object locked, the only thing that they can do is unlock it. + // + // Nobody but the object owner can set permissions on an object + // + + if (locked && (!IsAdministrator(currentUser))) + { + return false; + } + + // Object owners should be able to edit their own content + if (currentUser == objectOwner) + { + permission = true; + } + + // Users should be able to edit what is over their land. + Land parcel = m_scene.LandManager.getLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y); + if ((parcel != null) && (parcel.landData.ownerID == currentUser)) + { + permission = true; + } + + // Estate users should be able to edit anything in the sim + if (IsEstateManager(currentUser)) + { + permission = true; + } + + // Admin objects should not be editable by the above + if (IsAdministrator(objectOwner)) + { + permission = false; + } + + // Admin should be able to edit anything in the sim (including admin objects) + if (IsAdministrator(currentUser)) + { + permission = true; + } + + return permission; + } + + /// + /// Permissions check - can user delete an object? + /// + /// User attempting the delete + /// Target object + /// Has permission? + public virtual bool CanDeRezObject(LLUUID user, LLUUID obj) + { + return GenericObjectPermission(user, obj); + } + + public virtual bool CanEditObject(LLUUID user, LLUUID obj) + { + return GenericObjectPermission(user, obj); + } + + public virtual bool CanEditObjectPosition(LLUUID user, LLUUID obj) + { + bool permission = GenericObjectPermission(user, obj); + if (!permission) + { + if (!m_scene.Entities.ContainsKey(obj)) + { + return false; + } + + // The client + // may request to edit linked parts, and therefore, it needs + // to also check for SceneObjectPart + + // If it's not an object, we cant edit it. + if ((!(m_scene.Entities[obj] is SceneObjectGroup))) + { + return false; + } + + + SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[obj]; + + + LLUUID taskOwner = null; + // Added this because at this point in time it wouldn't be wise for + // the administrator object permissions to take effect. + LLUUID objectOwner = task.OwnerID; + + // Anyone can move + if ((task.RootPart.EveryoneMask & PERM_MOVE) != 0) + permission = true; + + // Locked + if ((task.RootPart.OwnerMask & PERM_LOCKED) != 0) + permission = false; + + } + return permission; + } + + public virtual bool CanCopyObject(LLUUID user, LLUUID obj) + { + bool permission = GenericObjectPermission(user, obj); + if (!permission) + { + if (!m_scene.Entities.ContainsKey(obj)) + { + return false; + } + + // If it's not an object, we cant edit it. + if (!(m_scene.Entities[obj] is SceneObjectGroup)) + { + return false; + } + + SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[obj]; + LLUUID taskOwner = null; + // Added this because at this point in time it wouldn't be wise for + // the administrator object permissions to take effect. + LLUUID objectOwner = task.OwnerID; + if ((task.RootPart.EveryoneMask & PERM_COPY) != 0) + permission = true; + } + return permission; + } + + public virtual bool CanReturnObject(LLUUID user, LLUUID obj) + { + return GenericObjectPermission(user, obj); + } + + #endregion + + #region Communication Permissions + + public virtual bool GenericCommunicationPermission(LLUUID user, LLUUID target) + { + bool permission = false; + string reason = "Only registered users may communicate with another account."; + + if (IsGridUser(user)) + permission = true; + + if (!IsGridUser(user)) + { + permission = false; + reason = "The person that you are messaging is not a registered user."; + } + if (IsAdministrator(user)) + permission = true; + + if (IsEstateManager(user)) + permission = true; + + if (!permission) + SendPermissionError(user, reason); + + return permission; + } + + public virtual bool CanInstantMessage(LLUUID user, LLUUID target) + { + return GenericCommunicationPermission(user, target); + } + + public virtual bool CanInventoryTransfer(LLUUID user, LLUUID target) + { + return GenericCommunicationPermission(user, target); + } + + #endregion + + public virtual bool CanEditScript(LLUUID user, LLUUID script) + { + return IsAdministrator(user); + } + + public virtual bool CanRunScript(LLUUID user, LLUUID script) + { + return IsAdministrator(user); + } + + public virtual bool CanRunConsoleCommand(LLUUID user) + { + return IsAdministrator(user); + } + + public virtual bool CanTerraform(LLUUID user, LLVector3 position) + { + bool permission = false; + + // Estate override + if (GenericEstatePermission(user)) + permission = true; + + float X = position.X; + float Y = position.Y; + + if (X > 255) + X = 255; + if (Y > 255) + Y = 255; + if (X < 0) + X = 0; + if (Y < 0) + Y = 0; + + // Land owner can terraform too + Land parcel = m_scene.LandManager.getLandObject(X, Y); + if (parcel != null && GenericParcelPermission(user, parcel)) + permission = true; + + if (!permission) + SendPermissionError(user, "Not authorized to terraform at this location."); + + return permission; + } + + #region Estate Permissions + + public virtual bool GenericEstatePermission(LLUUID user) + { + // Default: deny + bool permission = false; + + // Estate admins should be able to use estate tools + if (IsEstateManager(user)) + permission = true; + + // Administrators always have permission + if (IsAdministrator(user)) + permission = true; + + return permission; + } + + public virtual bool CanEditEstateTerrain(LLUUID user) + { + return GenericEstatePermission(user); + } + + public virtual bool CanRestartSim(LLUUID user) + { + // Since this is potentially going on a grid... + + return GenericEstatePermission(user); + //return m_scene.RegionInfo.MasterAvatarAssignedUUID == user; + } + + #endregion + + #region Parcel Permissions + + protected virtual bool GenericParcelPermission(LLUUID user, Land parcel) + { + bool permission = false; + + if (parcel.landData.ownerID == user) + { + permission = true; + } + + if (parcel.landData.isGroupOwned) + { + // TODO: Need to do some extra checks here. Requires group code. + } + + if (IsEstateManager(user)) + { + permission = true; + } + + if (IsAdministrator(user)) + { + permission = true; + } + + return permission; + } + + protected virtual bool GenericParcelPermission(LLUUID user, LLVector3 pos) + { + Land parcel = m_scene.LandManager.getLandObject(pos.X, pos.Y); + if (parcel == null) return false; + return GenericParcelPermission(user, parcel); + } + + public virtual bool CanEditParcel(LLUUID user, Land parcel) + { + return GenericParcelPermission(user, parcel); + } + + public virtual bool CanSellParcel(LLUUID user, Land parcel) + { + return GenericParcelPermission(user, parcel); + } + + public virtual bool CanAbandonParcel(LLUUID user, Land parcel) + { + return GenericParcelPermission(user, parcel); + } + + #endregion + } +} diff --git a/OpenSim/Region/Environment/StorageManager.cs b/OpenSim/Region/Environment/StorageManager.cs index b8ed1ecf55..a98a1e1565 100644 --- a/OpenSim/Region/Environment/StorageManager.cs +++ b/OpenSim/Region/Environment/StorageManager.cs @@ -1,77 +1,79 @@ -/* -* Copyright (c) Contributors, http://opensimulator.org/ -* See CONTRIBUTORS.TXT for a full list of copyright holders. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the OpenSim Project nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*/ - -using System; -using System.Reflection; -using OpenSim.Framework.Console; -using OpenSim.Region.Environment.Interfaces; - -namespace OpenSim.Region.Environment -{ - public class StorageManager - { - private IRegionDataStore m_dataStore; - - public IRegionDataStore DataStore - { - get { return m_dataStore; } - } - - public StorageManager(IRegionDataStore storage) - { - m_dataStore = storage; - } - - public StorageManager(string dllName, string connectionstring) - { - MainLog.Instance.Verbose("DATASTORE", "Attempting to load " + dllName); - Assembly pluginAssembly = Assembly.LoadFrom(dllName); - - foreach (Type pluginType in pluginAssembly.GetTypes()) - { - if (pluginType.IsPublic) - { - Type typeInterface = pluginType.GetInterface("IRegionDataStore", true); - - if (typeInterface != null) - { - IRegionDataStore plug = - (IRegionDataStore) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); - plug.Initialise(connectionstring, false); - - m_dataStore = plug; - - MainLog.Instance.Verbose("DATASTORE", "Added IRegionDataStore Interface"); - } - } - } - - //TODO: Add checking and warning to make sure it initialised. - } - } -} \ No newline at end of file +/* +* Copyright (c) Contributors, http://opensimulator.org/ +* See CONTRIBUTORS.TXT for a full list of copyright holders. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the OpenSim Project nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ + +using System; +using System.Reflection; +using OpenSim.Framework.Console; +using OpenSim.Region.Environment.Interfaces; + +namespace OpenSim.Region.Environment +{ + public class StorageManager + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private IRegionDataStore m_dataStore; + + public IRegionDataStore DataStore + { + get { return m_dataStore; } + } + + public StorageManager(IRegionDataStore storage) + { + m_dataStore = storage; + } + + public StorageManager(string dllName, string connectionstring, bool persistPrimInventories) + { + m_log.Info("[DATASTORE]: Attempting to load " + dllName); + Assembly pluginAssembly = Assembly.LoadFrom(dllName); + + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (pluginType.IsPublic) + { + Type typeInterface = pluginType.GetInterface("IRegionDataStore", true); + + if (typeInterface != null) + { + IRegionDataStore plug = + (IRegionDataStore) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + plug.Initialise(connectionstring, persistPrimInventories); + + m_dataStore = plug; + + m_log.Info("[DATASTORE]: Added IRegionDataStore Interface"); + } + } + } + + //TODO: Add checking and warning to make sure it initialised. + } + } +}