diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 325816da7d..b22003cffa 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -413,8 +413,21 @@ namespace OpenSim.ApplicationPlugins.RemoteController ITerrainModule terrainModule = region.RequestModuleInterface(); if (null == terrainModule) throw new Exception("terrain module not available"); - terrainModule.LoadFromFile(file); - + if (Uri.IsWellFormedUriString(file, UriKind.Absolute)) + { + m_log.Info("[RADMIN]: Terrain path is URL"); + Uri result; + if (Uri.TryCreate(file, UriKind.RelativeOrAbsolute, out result)) + { + // the url is valid + string fileType = file.Substring(file.LastIndexOf('/') + 1); + terrainModule.LoadFromStream(fileType, result); + } + } + else + { + terrainModule.LoadFromFile(file); + } responseData["success"] = false; response.Value = responseData; diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index e47d2a5f5a..e2a5406aff 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -479,7 +479,9 @@ namespace OpenSim.Data.MySQL } else { - m_log.Warn("[REGION DB]: Database contains an orphan child prim " + prim.UUID + " pointing to missing parent " + prim.ParentUUID); + m_log.WarnFormat( + "[REGION DB]: Database contains an orphan child prim {0} {1} at {2} in region {3} pointing to missing parent {4}. This prim will not be loaded.", + prim.Name, prim.UUID, prim.AbsolutePosition, regionID, prim.ParentUUID); } } } diff --git a/OpenSim/Data/SQLite/SQLiteUserData.cs b/OpenSim/Data/SQLite/SQLiteUserData.cs index b9f3515b1a..caddcf8538 100644 --- a/OpenSim/Data/SQLite/SQLiteUserData.cs +++ b/OpenSim/Data/SQLite/SQLiteUserData.cs @@ -819,7 +819,10 @@ namespace OpenSim.Data.SQLite SQLiteUtil.createCol(users, "homeLookAtZ", typeof (Double)); SQLiteUtil.createCol(users, "created", typeof (Int32)); SQLiteUtil.createCol(users, "lastLogin", typeof (Int32)); + + //TODO: Please delete this column. It's now a brick SQLiteUtil.createCol(users, "rootInventoryFolderID", typeof (String)); + SQLiteUtil.createCol(users, "userInventoryURI", typeof (String)); SQLiteUtil.createCol(users, "userAssetURI", typeof (String)); SQLiteUtil.createCol(users, "profileCanDoMask", typeof (Int32)); @@ -980,7 +983,6 @@ namespace OpenSim.Data.SQLite user.Created = Convert.ToInt32(row["created"]); user.LastLogin = Convert.ToInt32(row["lastLogin"]); - user.RootInventoryFolderID = new UUID((String) row["rootInventoryFolderID"]); user.UserInventoryURI = (String) row["userInventoryURI"]; user.UserAssetURI = (String) row["userAssetURI"]; user.CanDoMask = Convert.ToUInt32(row["profileCanDoMask"]); @@ -1026,7 +1028,8 @@ namespace OpenSim.Data.SQLite row["created"] = user.Created; row["lastLogin"] = user.LastLogin; - row["rootInventoryFolderID"] = user.RootInventoryFolderID.ToString(); + //TODO: Get rid of rootInventoryFolderID in a safe way. + row["rootInventoryFolderID"] = UUID.Zero.ToString(); row["userInventoryURI"] = user.UserInventoryURI; row["userAssetURI"] = user.UserAssetURI; row["profileCanDoMask"] = user.CanDoMask; diff --git a/OpenSim/Data/Tests/BasicUserTest.cs b/OpenSim/Data/Tests/BasicUserTest.cs index 1f472a54ec..d3b6041490 100644 --- a/OpenSim/Data/Tests/BasicUserTest.cs +++ b/OpenSim/Data/Tests/BasicUserTest.cs @@ -170,8 +170,8 @@ namespace OpenSim.Data.Tests { UserProfileData u0 = NewUser(zero,fname0,lname0); UserProfileData u4 = NewUser(user4,fname2,lname2); - db.AddNewUserProfile(u0); - db.AddNewUserProfile(u4); + db.AddNewUserProfile(u0); //UserID 0 should fail to save. + db.AddNewUserProfile(u4); //The first name and last name are already in use (from T010), so this should fail too Assert.That(db.GetUserByUUID(zero),Is.Null); Assert.That(db.GetUserByUUID(user4),Is.Null); } @@ -267,8 +267,6 @@ namespace OpenSim.Data.Tests Assert.That(homelookat,Is.EqualTo(u1a.HomeLookAt), "Assert.That(homelookat,Is.EqualTo(u1a.HomeLookAt))"); Assert.That(created,Is.EqualTo(u1a.Created), "Assert.That(created,Is.EqualTo(u1a.Created))"); Assert.That(lastlogin,Is.EqualTo(u1a.LastLogin), "Assert.That(lastlogin,Is.EqualTo(u1a.LastLogin))"); - // RootInventoryFolderID is not tested because it is saved in SQLite, - // but not in MySQL Assert.That(userinvuri,Is.EqualTo(u1a.UserInventoryURI), "Assert.That(userinvuri,Is.EqualTo(u1a.UserInventoryURI))"); Assert.That(userasseturi,Is.EqualTo(u1a.UserAssetURI), "Assert.That(userasseturi,Is.EqualTo(u1a.UserAssetURI))"); Assert.That(candomask,Is.EqualTo(u1a.CanDoMask), "Assert.That(candomask,Is.EqualTo(u1a.CanDoMask))"); @@ -367,8 +365,6 @@ namespace OpenSim.Data.Tests Assert.That(homelookat,Is.EqualTo(u1a.HomeLookAt), "Assert.That(homelookat,Is.EqualTo(u1a.HomeLookAt))"); Assert.That(created,Is.EqualTo(u1a.Created), "Assert.That(created,Is.EqualTo(u1a.Created))"); Assert.That(lastlogin,Is.EqualTo(u1a.LastLogin), "Assert.That(lastlogin,Is.EqualTo(u1a.LastLogin))"); - // RootInventoryFolderID is not tested because it is saved in SQLite, - // but not in MySQL Assert.That(userasseturi,Is.EqualTo(u1a.UserAssetURI), "Assert.That(userasseturi,Is.EqualTo(u1a.UserAssetURI))"); Assert.That(candomask,Is.EqualTo(u1a.CanDoMask), "Assert.That(candomask,Is.EqualTo(u1a.CanDoMask))"); Assert.That(wantdomask,Is.EqualTo(u1a.WantDoMask), "Assert.That(wantdomask,Is.EqualTo(u1a.WantDoMask))"); @@ -395,7 +391,6 @@ namespace OpenSim.Data.Tests Assert.That(u1a, Constraints.PropertyCompareConstraint(u) .IgnoreProperty(x=>x.HomeRegionX) .IgnoreProperty(x=>x.HomeRegionY) - .IgnoreProperty(x=>x.RootInventoryFolderID) ); } diff --git a/OpenSim/Framework/Communications/Services/LoginService.cs b/OpenSim/Framework/Communications/Services/LoginService.cs index b6522992b7..57ca704e73 100644 --- a/OpenSim/Framework/Communications/Services/LoginService.cs +++ b/OpenSim/Framework/Communications/Services/LoginService.cs @@ -244,7 +244,6 @@ namespace OpenSim.Framework.Communications.Services InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString(); ArrayList InventoryRoot = new ArrayList(); InventoryRoot.Add(InventoryRootHash); - userProfile.RootInventoryFolderID = inventData.RootFolderID; logResponse.InventoryRoot = InventoryRoot; logResponse.InventorySkeleton = AgentInventoryArray; @@ -501,7 +500,6 @@ namespace OpenSim.Framework.Communications.Services InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString(); ArrayList InventoryRoot = new ArrayList(); InventoryRoot.Add(InventoryRootHash); - userProfile.RootInventoryFolderID = inventData.RootFolderID; // Inventory Library Section diff --git a/OpenSim/Framework/Communications/UserManagerBase.cs b/OpenSim/Framework/Communications/UserManagerBase.cs index bf4f331e61..4f0af0664d 100644 --- a/OpenSim/Framework/Communications/UserManagerBase.cs +++ b/OpenSim/Framework/Communications/UserManagerBase.cs @@ -697,9 +697,6 @@ namespace OpenSim.Framework.Communications // local service (standalone) m_log.Debug("[USERSTORAGE]: using IInventoryService to create user's inventory"); m_InventoryService.CreateUserInventory(userProf.ID); - InventoryFolderBase rootfolder = m_InventoryService.GetRootFolder(userProf.ID); - if (rootfolder != null) - userProf.RootInventoryFolderID = rootfolder.ID; } else if (m_commsManager.InterServiceInventoryService != null) { diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index bec5ed31bb..75cdeb4466 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -724,12 +724,20 @@ namespace OpenSim.Framework.Servers.HttpServer } catch(Exception e) { + string errorMessage + = String.Format( + "Requested method [{0}] from {1} threw exception: {2} {3}", + methodName, request.RemoteIPEndPoint.Address, e.Message, e.StackTrace); + + m_log.ErrorFormat("[BASE HTTP SERVER]: {0}", errorMessage); + // if the registered XmlRpc method threw an exception, we pass a fault-code along xmlRpcResponse = new XmlRpcResponse(); + // Code probably set in accordance with http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php - xmlRpcResponse.SetFault(-32603, String.Format("Requested method [{0}] threw exception: {1}", - methodName, e.Message)); + xmlRpcResponse.SetFault(-32603, errorMessage); } + // if the method wasn't found, we can't determine KeepAlive state anyway, so lets do it only here response.KeepAlive = m_rpcHandlersKeepAlive[methodName]; } diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs index c53160fb1d..bcfb0a4025 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs @@ -188,7 +188,15 @@ namespace OpenSim.Framework.Servers.HttpServer try { IPAddress addr = IPAddress.Parse(req.Headers["remote_addr"]); - int port = Int32.Parse(req.Headers["remote_port"]); + // sometimes req.Headers["remote_port"] returns a comma separated list, so use + // the first one in the list and log it + string[] strPorts = req.Headers["remote_port"].Split(new char[] { ',' }); + if (strPorts.Length > 1) + { + _log.ErrorFormat("[OSHttpRequest]: format exception on addr/port {0}:{1}, ignoring", + req.Headers["remote_addr"], req.Headers["remote_port"]); + } + int port = Int32.Parse(strPorts[0]); _remoteIPEndPoint = new IPEndPoint(addr, port); } catch (FormatException) diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs index efe5f0cb47..4b9a509e6b 100644 --- a/OpenSim/Framework/TaskInventoryDictionary.cs +++ b/OpenSim/Framework/TaskInventoryDictionary.cs @@ -109,7 +109,10 @@ namespace OpenSim.Framework } else { - m_itemLock.ExitReadLock(); + if (m_itemLock.RecursiveReadCount>0) + { + m_itemLock.ExitReadLock(); + } } } @@ -144,7 +147,10 @@ namespace OpenSim.Framework } else { - m_itemLock.ExitWriteLock(); + if (m_itemLock.RecursiveWriteCount > 0) + { + m_itemLock.ExitWriteLock(); + } } } diff --git a/OpenSim/Framework/UserProfileData.cs b/OpenSim/Framework/UserProfileData.cs index 413f152e4e..9bac739589 100644 --- a/OpenSim/Framework/UserProfileData.cs +++ b/OpenSim/Framework/UserProfileData.cs @@ -119,8 +119,6 @@ namespace OpenSim.Framework /// private string m_profileUrl; - private UUID m_rootInventoryFolderId; - /// /// The second component of a users account name /// @@ -312,12 +310,6 @@ namespace OpenSim.Framework set { m_lastLogin = value; } } - public UUID RootInventoryFolderID - { - get { return m_rootInventoryFolderId; } - set { m_rootInventoryFolderId = value; } - } - public string UserInventoryURI { get { return m_userInventoryUri; } diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 7b90239d12..b5e2872f33 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1389,30 +1389,30 @@ namespace OpenSim.Framework return null; } - #endregion FireAndForget Threading Pattern - /// - /// Environment.TickCount is an int but it counts all 32 bits so it goes positive - /// and negative every 24.9 days. This trims down TickCount so it doesn't wrap - /// for the callers. - /// This trims it to a 12 day interval so don't let your frame time get too long. - /// - /// - public static Int32 EnvironmentTickCount() - { - return Environment.TickCount & EnvironmentTickCountMask; - } - const Int32 EnvironmentTickCountMask = 0x3fffffff; - - /// - /// Environment.TickCount is an int but it counts all 32 bits so it goes positive - /// and negative every 24.9 days. Subtracts the passed value (previously fetched by - /// 'EnvironmentTickCount()') and accounts for any wrapping. - /// - /// subtraction of passed prevValue from current Environment.TickCount - public static Int32 EnvironmentTickCountSubtract(Int32 prevValue) - { - Int32 diff = EnvironmentTickCount() - prevValue; - return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); + #endregion FireAndForget Threading Pattern + /// + /// Environment.TickCount is an int but it counts all 32 bits so it goes positive + /// and negative every 24.9 days. This trims down TickCount so it doesn't wrap + /// for the callers. + /// This trims it to a 12 day interval so don't let your frame time get too long. + /// + /// + public static Int32 EnvironmentTickCount() + { + return Environment.TickCount & EnvironmentTickCountMask; + } + const Int32 EnvironmentTickCountMask = 0x3fffffff; + + /// + /// Environment.TickCount is an int but it counts all 32 bits so it goes positive + /// and negative every 24.9 days. Subtracts the passed value (previously fetched by + /// 'EnvironmentTickCount()') and accounts for any wrapping. + /// + /// subtraction of passed prevValue from current Environment.TickCount + public static Int32 EnvironmentTickCountSubtract(Int32 prevValue) + { + Int32 diff = EnvironmentTickCount() - prevValue; + return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); } } } diff --git a/OpenSim/Grid/UserServer.Modules/MessageServersConnector.cs b/OpenSim/Grid/UserServer.Modules/MessageServersConnector.cs index f24cef6e0e..3384952be1 100644 --- a/OpenSim/Grid/UserServer.Modules/MessageServersConnector.cs +++ b/OpenSim/Grid/UserServer.Modules/MessageServersConnector.cs @@ -201,6 +201,7 @@ namespace OpenSim.Grid.UserServer.Modules } return response; } + public XmlRpcResponse XmlRPCUserMovedtoRegion(XmlRpcRequest request, IPEndPoint remoteClient) { XmlRpcResponse response = new XmlRpcResponse(); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 6cbf1a6f66..2b5e632781 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -352,6 +352,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP private IHyperAssetService m_hyperAssets; private const bool m_checkPackets = true; + private Timer m_propertiesPacketTimer; + private List m_propertiesBlocks = new List(); + #endregion Class Members #region Properties @@ -433,6 +436,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_udpClient.OnQueueEmpty += HandleQueueEmpty; m_udpClient.OnPacketStats += PopulateStats; + m_propertiesPacketTimer = new Timer(100); + m_propertiesPacketTimer.Elapsed += ProcessObjectPropertiesPacket; + RegisterLocalPacketHandlers(); } @@ -3562,42 +3568,88 @@ namespace OpenSim.Region.ClientStack.LindenUDP string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, uint BaseMask, byte saleType, int salePrice) { - ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); + //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); // TODO: don't create new blocks if recycling an old packet - proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[1]; - proper.ObjectData[0] = new ObjectPropertiesPacket.ObjectDataBlock(); - proper.ObjectData[0].ItemID = ItemID; - proper.ObjectData[0].CreationDate = CreationDate; - proper.ObjectData[0].CreatorID = CreatorUUID; - proper.ObjectData[0].FolderID = FolderUUID; - proper.ObjectData[0].FromTaskID = FromTaskUUID; - proper.ObjectData[0].GroupID = GroupUUID; - proper.ObjectData[0].InventorySerial = InventorySerial; + ObjectPropertiesPacket.ObjectDataBlock block = + new ObjectPropertiesPacket.ObjectDataBlock(); - proper.ObjectData[0].LastOwnerID = LastOwnerUUID; + block.ItemID = ItemID; + block.CreationDate = CreationDate; + block.CreatorID = CreatorUUID; + block.FolderID = FolderUUID; + block.FromTaskID = FromTaskUUID; + block.GroupID = GroupUUID; + block.InventorySerial = InventorySerial; + + block.LastOwnerID = LastOwnerUUID; // proper.ObjectData[0].LastOwnerID = UUID.Zero; - proper.ObjectData[0].ObjectID = ObjectUUID; + block.ObjectID = ObjectUUID; if (OwnerUUID == GroupUUID) - proper.ObjectData[0].OwnerID = UUID.Zero; + block.OwnerID = UUID.Zero; else - proper.ObjectData[0].OwnerID = OwnerUUID; - proper.ObjectData[0].TouchName = Util.StringToBytes256(TouchTitle); - proper.ObjectData[0].TextureID = TextureID; - proper.ObjectData[0].SitName = Util.StringToBytes256(SitTitle); - proper.ObjectData[0].Name = Util.StringToBytes256(ItemName); - proper.ObjectData[0].Description = Util.StringToBytes256(ItemDescription); - proper.ObjectData[0].OwnerMask = OwnerMask; - proper.ObjectData[0].NextOwnerMask = NextOwnerMask; - proper.ObjectData[0].GroupMask = GroupMask; - proper.ObjectData[0].EveryoneMask = EveryoneMask; - proper.ObjectData[0].BaseMask = BaseMask; + block.OwnerID = OwnerUUID; + block.TouchName = Util.StringToBytes256(TouchTitle); + block.TextureID = TextureID; + block.SitName = Util.StringToBytes256(SitTitle); + block.Name = Util.StringToBytes256(ItemName); + block.Description = Util.StringToBytes256(ItemDescription); + block.OwnerMask = OwnerMask; + block.NextOwnerMask = NextOwnerMask; + block.GroupMask = GroupMask; + block.EveryoneMask = EveryoneMask; + block.BaseMask = BaseMask; // proper.ObjectData[0].AggregatePerms = 53; // proper.ObjectData[0].AggregatePermTextures = 0; // proper.ObjectData[0].AggregatePermTexturesOwner = 0; - proper.ObjectData[0].SaleType = saleType; - proper.ObjectData[0].SalePrice = salePrice; + block.SaleType = saleType; + block.SalePrice = salePrice; + + lock (m_propertiesPacketTimer) + { + m_propertiesBlocks.Add(block); + + int length = 0; + foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks) + { + length += b.Length; + } + if (length > 1100) // FIXME: use real MTU + { + ProcessObjectPropertiesPacket(null, null); + m_propertiesPacketTimer.Stop(); + return; + } + + m_propertiesPacketTimer.Stop(); + m_propertiesPacketTimer.Start(); + } + + //proper.Header.Zerocoded = true; + //OutPacket(proper, ThrottleOutPacketType.Task); + } + + private void ProcessObjectPropertiesPacket(Object sender, ElapsedEventArgs e) + { + ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); + + lock (m_propertiesPacketTimer) + { + m_propertiesPacketTimer.Stop(); + + proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count]; + + int index = 0; + + foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks) + { + proper.ObjectData[index++] = b; + } + + m_propertiesBlocks.Clear(); + } + proper.Header.Zerocoded = true; OutPacket(proper, ThrottleOutPacketType.Task); } @@ -5504,6 +5556,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (avSetStartLocationRequestPacket.AgentData.AgentID == AgentId && avSetStartLocationRequestPacket.AgentData.SessionID == SessionId) { + // Linden Client limitation.. + if (avSetStartLocationRequestPacket.StartLocationData.LocationPos.X == 255.5f + || avSetStartLocationRequestPacket.StartLocationData.LocationPos.Y == 255.5f) + { + ScenePresence avatar = null; + if (((Scene)m_scene).TryGetAvatar(AgentId, out avatar)) + { + if (avSetStartLocationRequestPacket.StartLocationData.LocationPos.X == 255.5f) + { + avSetStartLocationRequestPacket.StartLocationData.LocationPos.X = avatar.AbsolutePosition.X; + } + if (avSetStartLocationRequestPacket.StartLocationData.LocationPos.Y == 255.5f) + { + avSetStartLocationRequestPacket.StartLocationData.LocationPos.Y = avatar.AbsolutePosition.Y; + } + } + + } TeleportLocationRequest handlerSetStartLocationRequest = OnSetStartLocationRequest; if (handlerSetStartLocationRequest != null) { diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 1e5f15a3b2..55d9c9cd47 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -430,7 +430,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Send the packet m_udpServer.SendPacketFinal(nextPacket); m_nextPackets[i] = null; - packetSent = true; + packetSent = true; this.PacketsSent++; } } diff --git a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs index 62500a2d7f..c727cec860 100644 --- a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs +++ b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs @@ -527,7 +527,6 @@ namespace OpenSim.Region.CoreModules.InterGrid userProfile.Partner = UUID.Zero; userProfile.PasswordHash = "$1$"; userProfile.PasswordSalt = ""; - userProfile.RootInventoryFolderID = UUID.Zero; userProfile.SurName = agentData.lastname; userProfile.UserAssetURI = homeScene.CommsManager.NetworkServersInfo.AssetURL; userProfile.UserFlags = 0; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs index fca2df2766..68499f3d20 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs @@ -70,7 +70,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization IConfig authorizationConfig = source.Configs["AuthorizationService"]; if (authorizationConfig == null) { - m_log.Error("[REMOTE AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini"); + m_log.Info("[REMOTE AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini"); return; } diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index e3a395eef5..b1dcb1489a 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -471,20 +471,45 @@ namespace OpenSim.Region.CoreModules.World.Estate if (terr != null) { m_log.Warn("[CLIENT]: Got Request to Send Terrain in region " + m_scene.RegionInfo.RegionName); - if (File.Exists(Util.dataDir() + "/terrain.raw")) - { - File.Delete(Util.dataDir() + "/terrain.raw"); - } + try { - FileStream input = new FileStream(Util.dataDir() + "/terrain.raw", FileMode.CreateNew); + + string localfilename = "terrain.raw"; + + if (terrainData.Length == 851968) + { + localfilename = Path.Combine(Util.dataDir(),"terrain.raw"); // It's a .LLRAW + } + + if (terrainData.Length == 196662) // 24-bit 256x256 Bitmap + localfilename = Path.Combine(Util.dataDir(), "terrain.bmp"); + + if (terrainData.Length == 256 * 256 * 4) // It's a .R32 + localfilename = Path.Combine(Util.dataDir(), "terrain.r32"); + + if (terrainData.Length == 256 * 256 * 8) // It's a .R64 + localfilename = Path.Combine(Util.dataDir(), "terrain.r64"); + + if (File.Exists(localfilename)) + { + File.Delete(localfilename); + } + + FileStream input = new FileStream(localfilename, FileMode.CreateNew); input.Write(terrainData, 0, terrainData.Length); input.Close(); + + FileInfo x = new FileInfo(localfilename); + + terr.LoadFromFile(localfilename); + remoteClient.SendAlertMessage("Your terrain was loaded as a ." + x.Extension + " file. It may take a few moments to appear."); + } catch (IOException e) { m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); - remoteClient.SendAlertMessage("There was an IO Exception loading your terrain. Please check free space"); + remoteClient.SendAlertMessage("There was an IO Exception loading your terrain. Please check free space."); return; } @@ -502,29 +527,16 @@ namespace OpenSim.Region.CoreModules.World.Estate return; } - - - - - try - { - terr.LoadFromFile(Util.dataDir() + "/terrain.raw"); - remoteClient.SendAlertMessage("Your terrain was loaded. Give it a minute or two to apply"); - } catch (Exception e) { m_log.ErrorFormat("[TERRAIN]: Error loading a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); remoteClient.SendAlertMessage("There was a general error loading your terrain. Please fix the terrain file and try again"); } - } else { remoteClient.SendAlertMessage("Unable to apply terrain. Cannot get an instance of the terrain module"); } - - - } private void handleUploadTerrain(IClientAPI remote_client, string clientFileName) diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index ba271fd362..a40828b080 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Reflection; +using System.Net; using log4net; using Nini.Config; using OpenMetaverse; @@ -258,6 +259,16 @@ namespace OpenSim.Region.CoreModules.World.Terrain } } + /// + /// Loads a terrain file from the specified URI + /// + /// The name of the terrain to load + /// The URI to the terrain height map + public void LoadFromStream(string filename, Uri pathToTerrainHeightmap) + { + LoadFromStream(filename, URIFetch(pathToTerrainHeightmap)); + } + /// /// Loads a terrain file from a stream and installs it in the scene. /// @@ -267,7 +278,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain { foreach (KeyValuePair loader in m_loaders) { - if (@filename.EndsWith(loader.Key)) + if (filename.EndsWith(loader.Key)) { lock (m_scene) { @@ -295,6 +306,25 @@ namespace OpenSim.Region.CoreModules.World.Terrain throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename)); } + private static Stream URIFetch(Uri uri) + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); + + // request.Credentials = credentials; + + request.ContentLength = 0; + request.KeepAlive = false; + + WebResponse response = request.GetResponse(); + Stream file = response.GetResponseStream(); + + if (response.ContentLength == 0) + throw new Exception(String.Format("{0} returned an empty file", uri.ToString())); + + // return new BufferedStream(file, (int) response.ContentLength); + return new BufferedStream(file, 1000000); + } + /// /// Modify Land /// diff --git a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs index 2dcba0c999..7caac55e9e 100644 --- a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// void LoadFromStream(string filename, Stream stream); - + void LoadFromStream(string filename, System.Uri pathToTerrainHeightmap); /// /// Save a terrain to a stream. /// diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index b031f61c4d..50624a13bb 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -448,5 +448,11 @@ namespace OpenSim.Region.Framework.Scenes.Animation SendAnimPack(animIDs, sequenceNums, objectIDs); } + + public void Close() + { + m_animations = null; + m_scenePresence = null; + } } } diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs index 099fcce559..c246e32be9 100644 --- a/OpenSim/Region/Framework/Scenes/EntityManager.cs +++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs @@ -40,7 +40,7 @@ namespace OpenSim.Region.Framework.Scenes private readonly Dictionary m_eb_uuid = new Dictionary(); private readonly Dictionary m_eb_localID = new Dictionary(); //private readonly Dictionary m_pres_uuid = new Dictionary(); - private readonly Object m_lock = new Object(); + private System.Threading.ReaderWriterLockSlim m_lock = new System.Threading.ReaderWriterLockSlim(); [Obsolete("Use Add() instead.")] public void Add(UUID id, EntityBase eb) @@ -50,7 +50,8 @@ namespace OpenSim.Region.Framework.Scenes public void Add(EntityBase entity) { - lock (m_lock) + m_lock.EnterWriteLock(); + try { try { @@ -62,11 +63,16 @@ namespace OpenSim.Region.Framework.Scenes m_log.ErrorFormat("Add Entity failed: {0}", e.Message); } } + finally + { + m_lock.ExitWriteLock(); + } } public void InsertOrReplace(EntityBase entity) { - lock (m_lock) + m_lock.EnterWriteLock(); + try { try { @@ -78,15 +84,24 @@ namespace OpenSim.Region.Framework.Scenes m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message); } } + finally + { + m_lock.ExitWriteLock(); + } } public void Clear() { - lock (m_lock) + m_lock.EnterWriteLock(); + try { m_eb_uuid.Clear(); m_eb_localID.Clear(); } + finally + { + m_lock.ExitWriteLock(); + } } public int Count @@ -123,7 +138,8 @@ namespace OpenSim.Region.Framework.Scenes public bool Remove(uint localID) { - lock (m_lock) + m_lock.EnterWriteLock(); + try { try { @@ -141,11 +157,16 @@ namespace OpenSim.Region.Framework.Scenes return false; } } + finally + { + m_lock.ExitWriteLock(); + } } public bool Remove(UUID id) { - lock (m_lock) + m_lock.EnterWriteLock(); + try { try { @@ -163,13 +184,18 @@ namespace OpenSim.Region.Framework.Scenes return false; } } + finally + { + m_lock.ExitWriteLock(); + } } public List GetAllByType() { List tmp = new List(); - lock (m_lock) + m_lock.EnterReadLock(); + try { try { @@ -187,23 +213,33 @@ namespace OpenSim.Region.Framework.Scenes tmp = null; } } + finally + { + m_lock.ExitReadLock(); + } return tmp; } public List GetEntities() { - lock (m_lock) + m_lock.EnterReadLock(); + try { return new List(m_eb_uuid.Values); } + finally + { + m_lock.ExitReadLock(); + } } public EntityBase this[UUID id] { get { - lock (m_lock) + m_lock.EnterReadLock(); + try { EntityBase entity; if (m_eb_uuid.TryGetValue(id, out entity)) @@ -211,6 +247,10 @@ namespace OpenSim.Region.Framework.Scenes else return null; } + finally + { + m_lock.ExitReadLock(); + } } set { @@ -222,7 +262,8 @@ namespace OpenSim.Region.Framework.Scenes { get { - lock (m_lock) + m_lock.EnterReadLock(); + try { EntityBase entity; if (m_eb_localID.TryGetValue(localID, out entity)) @@ -230,6 +271,10 @@ namespace OpenSim.Region.Framework.Scenes else return null; } + finally + { + m_lock.ExitReadLock(); + } } set { @@ -239,18 +284,28 @@ namespace OpenSim.Region.Framework.Scenes public bool TryGetValue(UUID key, out EntityBase obj) { - lock (m_lock) + m_lock.EnterReadLock(); + try { return m_eb_uuid.TryGetValue(key, out obj); } + finally + { + m_lock.ExitReadLock(); + } } public bool TryGetValue(uint key, out EntityBase obj) { - lock (m_lock) + m_lock.EnterReadLock(); + try { return m_eb_localID.TryGetValue(key, out obj); } + finally + { + m_lock.ExitReadLock(); + } } /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 83208e9747..7ca779a7ea 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1726,10 +1726,19 @@ namespace OpenSim.Region.Framework.Scenes if (folderID == UUID.Zero && folder == null) { - // Catch all. Use lost & found - // + if (action == DeRezAction.Delete) + { + // Deletes go to trash by default + // + folder = InventoryService.GetFolderForType(userID, AssetType.TrashFolder); + } + else + { + // Catch all. Use lost & found + // - folder = InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); + folder = InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); + } } if (folder == null) // None of the above @@ -2388,6 +2397,12 @@ namespace OpenSim.Region.Framework.Scenes InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = InventoryService.GetItem(item); presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); + + if (m_AvatarFactory != null) + { + m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); + } + } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f70af27a35..8d91d65191 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3048,6 +3048,7 @@ namespace OpenSim.Region.Framework.Scenes // TODO: The next line can be removed, as soon as only homeRegionID based UserServers are around. // TODO: The HomeRegion property can be removed then, too UserProfile.HomeRegion = RegionInfo.RegionHandle; + UserProfile.HomeLocation = position; UserProfile.HomeLookAt = lookAt; CommsManager.UserService.UpdateUserProfile(UserProfile); diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 2fdb48dd89..f74fd5d93f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -26,6 +26,7 @@ */ using System; +using System.Threading; using System.Collections.Generic; using System.Reflection; using OpenMetaverse; @@ -96,6 +97,8 @@ namespace OpenSim.Region.Framework.Scenes protected internal Dictionary SceneObjectGroupsByFullID = new Dictionary(); private readonly Object m_dictionary_lock = new Object(); + private Object m_updateLock = new Object(); + #endregion protected internal SceneGraph(Scene parent, RegionInfo regInfo) @@ -369,6 +372,9 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void UpdateObjectGroups() { + if (!Monitor.TryEnter(m_updateLock)) + return; + List updates; // Some updates add more updates to the updateList. @@ -395,6 +401,7 @@ namespace OpenSim.Region.Framework.Scenes "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e); } } + Monitor.Exit(m_updateLock); } protected internal void AddPhysicalPrim(int number) @@ -1555,55 +1562,65 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void LinkObjects(IClientAPI client, uint parentPrimId, List childPrimIds) { - SceneObjectGroup parentGroup = GetGroupByPrim(parentPrimId); - - List childGroups = new List(); - if (parentGroup != null) + Monitor.Enter(m_updateLock); + try { - // We do this in reverse to get the link order of the prims correct - for (int i = childPrimIds.Count - 1; i >= 0; i--) + SceneObjectGroup parentGroup = GetGroupByPrim(parentPrimId); + + List childGroups = new List(); + if (parentGroup != null) { - SceneObjectGroup child = GetGroupByPrim(childPrimIds[i]); - if (child != null) + // We do this in reverse to get the link order of the prims correct + for (int i = childPrimIds.Count - 1; i >= 0; i--) { - // Make sure no child prim is set for sale - // So that, on delink, no prims are unwittingly - // left for sale and sold off - child.RootPart.ObjectSaleType = 0; - child.RootPart.SalePrice = 10; - childGroups.Add(child); + SceneObjectGroup child = GetGroupByPrim(childPrimIds[i]); + if (child != null) + { + // Make sure no child prim is set for sale + // So that, on delink, no prims are unwittingly + // left for sale and sold off + child.RootPart.ObjectSaleType = 0; + child.RootPart.SalePrice = 10; + childGroups.Add(child); + } } } - } - else - { - return; // parent is null so not in this region - } - - foreach (SceneObjectGroup child in childGroups) - { - parentGroup.LinkToGroup(child); - - // this is here so physics gets updated! - // Don't remove! Bad juju! Stay away! or fix physics! - child.AbsolutePosition = child.AbsolutePosition; - } - - // We need to explicitly resend the newly link prim's object properties since no other actions - // occur on link to invoke this elsewhere (such as object selection) - parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); - parentGroup.TriggerScriptChangedEvent(Changed.LINK); - - if (client != null) - { - parentGroup.GetProperties(client); - } - else - { - foreach (ScenePresence p in GetScenePresences()) + else { - parentGroup.GetProperties(p.ControllingClient); + return; // parent is null so not in this region } + + foreach (SceneObjectGroup child in childGroups) + { + parentGroup.LinkToGroup(child); + + // this is here so physics gets updated! + // Don't remove! Bad juju! Stay away! or fix physics! + child.AbsolutePosition = child.AbsolutePosition; + } + + // We need to explicitly resend the newly link prim's object properties since no other actions + // occur on link to invoke this elsewhere (such as object selection) + parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); + parentGroup.TriggerScriptChangedEvent(Changed.LINK); + parentGroup.HasGroupChanged = true; + parentGroup.ScheduleGroupForFullUpdate(); + +// if (client != null) +// { +// parentGroup.GetProperties(client); +// } +// else +// { +// foreach (ScenePresence p in GetScenePresences()) +// { +// parentGroup.GetProperties(p.ControllingClient); +// } +// } + } + finally + { + Monitor.Exit(m_updateLock); } } @@ -1618,109 +1635,120 @@ namespace OpenSim.Region.Framework.Scenes protected internal void DelinkObjects(List primIds, bool sendEvents) { - List childParts = new List(); - List rootParts = new List(); - List affectedGroups = new List(); - // Look them all up in one go, since that is comparatively expensive - // - foreach (uint primID in primIds) + Monitor.Enter(m_updateLock); + try { - SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID); - if (part != null) - { - if (part.LinkNum < 2) // Root or single - rootParts.Add(part); - else - childParts.Add(part); - - SceneObjectGroup group = part.ParentGroup; - if (!affectedGroups.Contains(group)) - affectedGroups.Add(group); - } - else - { - m_log.ErrorFormat("Viewer requested unlink of nonexistent part {0}", primID); - } - } - - foreach (SceneObjectPart child in childParts) - { - // Unlink all child parts from their groups + List childParts = new List(); + List rootParts = new List(); + List affectedGroups = new List(); + // Look them all up in one go, since that is comparatively expensive // - child.ParentGroup.DelinkFromGroup(child, sendEvents); - } - - foreach (SceneObjectPart root in rootParts) - { - // In most cases, this will run only one time, and the prim - // will be a solo prim - // However, editing linked parts and unlinking may be different - // - SceneObjectGroup group = root.ParentGroup; - List newSet = new List(group.Children.Values); - int numChildren = group.Children.Count; - - // If there are prims left in a link set, but the root is - // slated for unlink, we need to do this - // - if (numChildren != 1) + foreach (uint primID in primIds) { - // Unlink the remaining set - // - bool sendEventsToRemainder = true; - if (numChildren > 1) - sendEventsToRemainder = false; - - foreach (SceneObjectPart p in newSet) + SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID); + if (part != null) { - if (p != group.RootPart) - group.DelinkFromGroup(p, sendEventsToRemainder); + if (part.ParentGroup.Children.Count != 1) // Skip single + { + if (part.LinkNum < 2) // Root + rootParts.Add(part); + else + childParts.Add(part); + + SceneObjectGroup group = part.ParentGroup; + if (!affectedGroups.Contains(group)) + affectedGroups.Add(group); + } } - - // If there is more than one prim remaining, we - // need to re-link - // - if (numChildren > 2) + else { - // Remove old root - // - if (newSet.Contains(root)) - newSet.Remove(root); + m_log.ErrorFormat("Viewer requested unlink of nonexistent part {0}", primID); + } + } - // Preserve link ordering + foreach (SceneObjectPart child in childParts) + { + // Unlink all child parts from their groups + // + child.ParentGroup.DelinkFromGroup(child, sendEvents); + } + + foreach (SceneObjectPart root in rootParts) + { + // In most cases, this will run only one time, and the prim + // will be a solo prim + // However, editing linked parts and unlinking may be different + // + SceneObjectGroup group = root.ParentGroup; + List newSet = new List(group.Children.Values); + int numChildren = group.Children.Count; + + // If there are prims left in a link set, but the root is + // slated for unlink, we need to do this + // + if (numChildren != 1) + { + // Unlink the remaining set // - newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b) + bool sendEventsToRemainder = true; + if (numChildren > 1) + sendEventsToRemainder = false; + + foreach (SceneObjectPart p in newSet) { - return a.LinkNum.CompareTo(b.LinkNum); - }); - - // Determine new root - // - SceneObjectPart newRoot = newSet[0]; - newSet.RemoveAt(0); - - List linkIDs = new List(); - - foreach (SceneObjectPart newChild in newSet) - { - newChild.UpdateFlag = 0; - linkIDs.Add(newChild.LocalId); + if (p != group.RootPart) + group.DelinkFromGroup(p, sendEventsToRemainder); } - LinkObjects(null, newRoot.LocalId, linkIDs); - if (!affectedGroups.Contains(newRoot.ParentGroup)) - affectedGroups.Add(newRoot.ParentGroup); + // If there is more than one prim remaining, we + // need to re-link + // + if (numChildren > 2) + { + // Remove old root + // + if (newSet.Contains(root)) + newSet.Remove(root); + + // Preserve link ordering + // + newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b) + { + return a.LinkNum.CompareTo(b.LinkNum); + }); + + // Determine new root + // + SceneObjectPart newRoot = newSet[0]; + newSet.RemoveAt(0); + + List linkIDs = new List(); + + foreach (SceneObjectPart newChild in newSet) + { + newChild.UpdateFlag = 0; + linkIDs.Add(newChild.LocalId); + } + + LinkObjects(null, newRoot.LocalId, linkIDs); + if (!affectedGroups.Contains(newRoot.ParentGroup)) + affectedGroups.Add(newRoot.ParentGroup); + } } } - } - // Finally, trigger events in the roots - // - foreach (SceneObjectGroup g in affectedGroups) + // Finally, trigger events in the roots + // + foreach (SceneObjectGroup g in affectedGroups) + { + g.TriggerScriptChangedEvent(Changed.LINK); + g.HasGroupChanged = true; // Persist + g.ScheduleGroupForFullUpdate(); + } + } + finally { - g.TriggerScriptChangedEvent(Changed.LINK); - g.HasGroupChanged = true; // Persist - g.ScheduleGroupForFullUpdate(); + Monitor.Exit(m_updateLock); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 42481ffc92..eacd21977d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -126,7 +126,10 @@ namespace OpenSim.Region.Framework.Scenes } else { - m_partsLock.ExitReadLock(); + if (m_partsLock.RecursiveReadCount > 0) + { + m_partsLock.ExitReadLock(); + } } } public void lockPartsForWrite(bool locked) @@ -155,7 +158,10 @@ namespace OpenSim.Region.Framework.Scenes } else { - m_partsLock.ExitWriteLock(); + if (m_partsLock.RecursiveWriteCount > 0) + { + m_partsLock.ExitWriteLock(); + } } } @@ -2292,14 +2298,14 @@ namespace OpenSim.Region.Framework.Scenes public void LinkToGroup(SceneObjectGroup objectGroup) { // Make sure we have sent any pending unlinks or stuff. - if (objectGroup.RootPart.UpdateFlag > 0) - { - m_log.WarnFormat( - "[SCENE OBJECT GROUP]: Forcing send of linkset {0}, {1} to {2}, {3} as its still waiting.", - objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); + //if (objectGroup.RootPart.UpdateFlag > 0) + //{ + // m_log.WarnFormat( + // "[SCENE OBJECT GROUP]: Forcing send of linkset {0}, {1} to {2}, {3} as its still waiting.", + // objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); - objectGroup.RootPart.SendScheduledUpdates(); - } + // objectGroup.RootPart.SendScheduledUpdates(); + //} // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}", @@ -2389,8 +2395,8 @@ namespace OpenSim.Region.Framework.Scenes // unmoved prims! ResetChildPrimPhysicsPositions(); - HasGroupChanged = true; - ScheduleGroupForFullUpdate(); + //HasGroupChanged = true; + //ScheduleGroupForFullUpdate(); } /// @@ -2483,8 +2489,8 @@ namespace OpenSim.Region.Framework.Scenes linkPart.Rezzed = RootPart.Rezzed; - HasGroupChanged = true; - ScheduleGroupForFullUpdate(); + //HasGroupChanged = true; + //ScheduleGroupForFullUpdate(); } /// @@ -2776,8 +2782,13 @@ namespace OpenSim.Region.Framework.Scenes { if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0) { - UsePhysics = false; // Reset physics - break; + if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || + part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || + part.Scale.Z > m_scene.RegionInfo.PhysPrimMax) + { + UsePhysics = false; // Reset physics + break; + } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index eca8588c51..b57d91218b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -269,8 +269,9 @@ namespace OpenSim.Region.Framework.Scenes { m_log.ErrorFormat( "[PRIM INVENTORY]: " + - "Couldn't start script {0}, {1} since asset ID {2} could not be found", - item.Name, item.ItemID, item.AssetID); + "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", + item.Name, item.ItemID, m_part.AbsolutePosition, + m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); } else { @@ -317,9 +318,20 @@ namespace OpenSim.Region.Framework.Scenes m_items.LockItemsForRead(true); if (m_items.ContainsKey(itemId)) { - TaskInventoryItem item = m_items[itemId]; - m_items.LockItemsForRead(false); - CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); + if (m_items.ContainsKey(itemId)) + { + m_items.LockItemsForRead(false); + CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); + } + else + { + m_items.LockItemsForRead(false); + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", + itemId, m_part.Name, m_part.UUID, + m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); + } } else { @@ -347,8 +359,9 @@ namespace OpenSim.Region.Framework.Scenes { m_log.ErrorFormat( "[PRIM INVENTORY]: " + - "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2}", - itemId, m_part.Name, m_part.UUID); + "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", + itemId, m_part.Name, m_part.UUID, + m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); } } @@ -542,8 +555,9 @@ namespace OpenSim.Region.Framework.Scenes { m_log.ErrorFormat( "[PRIM INVENTORY]: " + - "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory", - item.ItemID, m_part.Name, m_part.UUID); + "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", + item.ItemID, m_part.Name, m_part.UUID, + m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); } m_items.LockItemsForWrite(false); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 681291464a..f6bcb593cb 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -790,37 +790,13 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendPrimUpdates() { - m_perfMonMS = EnvironmentTickCount(); + m_perfMonMS = Util.EnvironmentTickCount(); m_sceneViewer.SendPrimUpdates(); - m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); } - /// - /// Environment.TickCount is an int but it counts all 32 bits so it goes positive - /// and negative every 24.9 days. This trims down TickCount so it doesn't wrap - /// for the callers. - /// This trims it to a 12 day interval so don't let your frame time get too long. - /// - /// - const Int32 EnvironmentTickCountMask = 0x3fffffff; - private static Int32 EnvironmentTickCount() { - return Environment.TickCount & EnvironmentTickCountMask; - } - - /// - /// Environment.TickCount is an int but it counts all 32 bits so it goes positive - /// and negative every 24.9 days. Subtracts the passed value (previously fetched by - /// 'EnvironmentTickCount()') and accounts for any wrapping. - /// - /// subtraction of passed prevValue from current Environment.TickCount - private static Int32 EnvironmentTickCountSubtract(Int32 prevValue) { - Int32 diff = EnvironmentTickCount() - prevValue; - return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); - } - - #region Status Methods /// @@ -1166,7 +1142,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance) + public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) { const float POSITION_TOLERANCE = 0.02f; const float VELOCITY_TOLERANCE = 0.02f; @@ -1209,7 +1185,7 @@ namespace OpenSim.Region.Framework.Scenes // return; //} - m_perfMonMS = EnvironmentTickCount(); + m_perfMonMS = Util.EnvironmentTickCount(); ++m_movementUpdateCount; if (m_movementUpdateCount < 1) @@ -1539,7 +1515,7 @@ namespace OpenSim.Region.Framework.Scenes m_scene.EventManager.TriggerOnClientMovement(this); - m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); } public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) @@ -1764,11 +1740,14 @@ namespace OpenSim.Region.Framework.Scenes UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); -// bool SitTargetisSet = -// (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f && -// avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f)); - - bool SitTargetisSet = ((Vector3.Zero != avSitOffSet) || (Quaternion.Identity != avSitOrientation)); + bool SitTargetisSet = + (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && + ( + avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion + || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point + || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion + ) + )); //Console.WriteLine("SendSitResponse offset=" + offset + " UnOccup=" + SitTargetUnOccupied + // " TargSet=" + SitTargetisSet); @@ -1850,7 +1829,7 @@ namespace OpenSim.Region.Framework.Scenes StandUp(); } m_nextSitAnimation = "SIT"; - + //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); SceneObjectPart part = FindNextAvailableSitTarget(targetID); @@ -1862,12 +1841,23 @@ namespace OpenSim.Region.Framework.Scenes } m_requestedSitTargetID = part.LocalId; //m_requestedSitOffset = offset; + //offset.X += part.Scale.X;// *offset.X; + //offset.Y += part.Scale.Y;// * offset.Y; + //offset.Z += part.Scale.Z;// * offset.Z; + //m_requestedSitOffset = offset; + m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); } else { m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); } + + if (m_scene.PhysicsScene.SupportsRayCast()) + { + //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback()); + } + SendSitResponse(remoteClient, targetID, offset); } @@ -1982,7 +1972,7 @@ namespace OpenSim.Region.Framework.Scenes SendFullUpdateToAllClients(); } - public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance) + public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal) { if(hitYN) { @@ -2057,7 +2047,7 @@ namespace OpenSim.Region.Framework.Scenes return; } - m_perfMonMS = EnvironmentTickCount(); + m_perfMonMS = Util.EnvironmentTickCount(); Rotation = rotation; Vector3 direc = vec * rotation; @@ -2099,7 +2089,7 @@ namespace OpenSim.Region.Framework.Scenes // TODO: Add the force instead of only setting it to support multiple forces per frame? m_forceToApply = direc; m_isNudging = Nudging; - m_scene.StatsReporter.AddAgentTime(EnvironmentTickCount() - m_perfMonMS); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); } #endregion @@ -2168,7 +2158,7 @@ namespace OpenSim.Region.Framework.Scenes // server. if (remoteClient.IsActive) { - m_perfMonMS = EnvironmentTickCount(); + m_perfMonMS = Util.EnvironmentTickCount(); PhysicsActor actor = m_physicsActor; Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero; @@ -2181,7 +2171,7 @@ namespace OpenSim.Region.Framework.Scenes remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient))); - m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); m_scene.StatsReporter.AddAgentUpdates(1); } } @@ -2191,11 +2181,11 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendTerseUpdateToAllClients() { - m_perfMonMS = EnvironmentTickCount(); + m_perfMonMS = Util.EnvironmentTickCount(); m_scene.ForEachClient(SendTerseUpdateToClient); - m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); } public void SendCoarseLocations() @@ -2215,7 +2205,7 @@ namespace OpenSim.Region.Framework.Scenes public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p) { - m_perfMonMS = EnvironmentTickCount(); + m_perfMonMS = Util.EnvironmentTickCount(); List CoarseLocations = new List(); List AvatarUUIDs = new List(); @@ -2251,7 +2241,7 @@ namespace OpenSim.Region.Framework.Scenes m_controllingClient.SendCoarseLocationUpdate(AvatarUUIDs, CoarseLocations); - m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); } public void CoarseLocationChange() @@ -2288,7 +2278,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendInitialFullUpdateToAllClients() { - m_perfMonMS = EnvironmentTickCount(); + m_perfMonMS = Util.EnvironmentTickCount(); ScenePresence[] avatars = m_scene.GetScenePresences(); @@ -2314,14 +2304,14 @@ namespace OpenSim.Region.Framework.Scenes } m_scene.StatsReporter.AddAgentUpdates(avatars.Length); - m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); //Animator.SendAnimPack(); } public void SendFullUpdateToAllClients() { - m_perfMonMS = EnvironmentTickCount(); + m_perfMonMS = Util.EnvironmentTickCount(); // only send update from root agents to other clients; children are only "listening posts" List avatars = m_scene.GetAvatars(); @@ -2331,7 +2321,7 @@ namespace OpenSim.Region.Framework.Scenes } m_scene.StatsReporter.AddAgentUpdates(avatars.Count); - m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); Animator.SendAnimPack(); } @@ -2373,7 +2363,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendAppearanceToAllOtherAgents() { - m_perfMonMS = EnvironmentTickCount(); + m_perfMonMS = Util.EnvironmentTickCount(); m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) { @@ -2382,8 +2372,8 @@ namespace OpenSim.Region.Framework.Scenes SendAppearanceToOtherAgent(scenePresence); } }); - - m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); + + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); } /// @@ -3084,7 +3074,9 @@ namespace OpenSim.Region.Framework.Scenes // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents( // as of this comment the interval is set in AddToPhysicalScene - + if (Animator!=null) + Animator.UpdateMovementAnimations(); + CollisionEventUpdate collisionData = (CollisionEventUpdate)e; Dictionary coldata = collisionData.m_objCollisionList; @@ -3096,7 +3088,7 @@ namespace OpenSim.Region.Framework.Scenes m_lastColCount = coldata.Count; } - if (coldata.Count != 0) + if (coldata.Count != 0 && Animator != null) { switch (Animator.CurrentMovementAnimation) { @@ -3200,11 +3192,13 @@ namespace OpenSim.Region.Framework.Scenes // I don't get it but mono crashes when you try to dispose of this timer, // unsetting the elapsed callback should be enough to allow for cleanup however. - //m_reprioritizationTimer.Dispose(); + // m_reprioritizationTimer.Dispose(); m_sceneViewer.Close(); RemoveFromPhysicalScene(); + m_animator.Close(); + m_animator = null; } public ScenePresence() diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index f92f440117..e368c2ae33 100644 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs @@ -75,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes UnAckedBytes = 24, } - // Sending a stats update every 3 seconds + // Sending a stats update every 3 seconds- private int statsUpdatesEveryMS = 3000; private float statsUpdateFactor = 0; private float m_timeDilation = 0; @@ -240,7 +240,7 @@ namespace OpenSim.Region.Framework.Scenes sb[12].StatID = (uint)Stats.OtherMS; sb[12].StatValue = m_otherMS / statsUpdateFactor; - sb[13].StatID = (uint)Stats.InPacketsPerSecond; + sb[13].StatID = (uint)Stats.InPacketsPerSecond; sb[13].StatValue = (m_inPacketsPerSecond / statsUpdateFactor); sb[14].StatID = (uint)Stats.OutPacketsPerSecond; diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 6d515e9eca..217d307443 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -36,7 +36,7 @@ namespace OpenSim.Region.Physics.Manager { public delegate void physicsCrash(); - public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance); + public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal); public abstract class PhysicsScene { @@ -204,7 +204,7 @@ namespace OpenSim.Region.Physics.Manager public virtual void RaycastWorld(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) { if (retMethod != null) - retMethod(false, Vector3.Zero, 0, 999999999999f); + retMethod(false, Vector3.Zero, 0, 999999999999f, Vector3.Zero); } private class NullPhysicsScene : PhysicsScene diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 905d3ba431..b99baa2ab3 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -1243,7 +1243,10 @@ namespace OpenSim.Region.Physics.OdePlugin { if (m_eventsubscription > m_requestedUpdateFrequency) { - base.SendCollisionUpdate(CollisionEventsThisFrame); + if (CollisionEventsThisFrame != null) + { + base.SendCollisionUpdate(CollisionEventsThisFrame); + } CollisionEventsThisFrame = new CollisionEventUpdate(); m_eventsubscription = 0; } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 8459daba07..c27c420aa8 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -743,6 +743,8 @@ namespace OpenSim.Region.Physics.OdePlugin break; } } + if (returnMass > _parent_scene.maximumMassObject) + returnMass = _parent_scene.maximumMassObject; return returnMass; }// end CalculateMass @@ -753,6 +755,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (Body != (IntPtr) 0) { float newmass = CalculateMass(); + //m_log.Info("[PHYSICS]: New Mass: " + newmass.ToString()); d.MassSetBoxTotal(out pMass, newmass, _size.X, _size.Y, _size.Z); diff --git a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs index c8ae229187..732e835789 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs @@ -145,6 +145,7 @@ namespace OpenSim.Region.Physics.OdePlugin uint hitConsumerID = 0; float distance = 999999999999f; Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f); + Vector3 snormal = Vector3.Zero; // Find closest contact and object. lock (m_contactResults) @@ -157,6 +158,7 @@ namespace OpenSim.Region.Physics.OdePlugin hitConsumerID = cResult.ConsumerID; distance = cResult.Depth; hitYN = true; + snormal = cResult.Normal; } } @@ -165,7 +167,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Return results if (req.callbackMethod != null) - req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance); + req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal); } // This is the standard Near. Uses space AABBs to speed up detection. @@ -310,7 +312,8 @@ namespace OpenSim.Region.Physics.OdePlugin collisionresult.ConsumerID = ((OdePrim)p1).m_localID; collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); collisionresult.Depth = contacts[i].depth; - + collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, + contacts[i].normal.Z); lock (m_contactResults) m_contactResults.Add(collisionresult); } @@ -325,6 +328,8 @@ namespace OpenSim.Region.Physics.OdePlugin collisionresult.ConsumerID = ((OdePrim)p2).m_localID; collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); collisionresult.Depth = contacts[i].depth; + collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, + contacts[i].normal.Z); lock (m_contactResults) m_contactResults.Add(collisionresult); @@ -358,5 +363,6 @@ namespace OpenSim.Region.Physics.OdePlugin public Vector3 Pos; public float Depth; public uint ConsumerID; + public Vector3 Normal; } } diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index a0aba2a892..0384d6edc1 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -207,6 +207,7 @@ namespace OpenSim.Region.Physics.OdePlugin private float avMovementDivisorWalk = 1.3f; private float avMovementDivisorRun = 0.8f; private float minimumGroundFlightOffset = 3f; + public float maximumMassObject = 10000.01f; public bool meshSculptedPrim = true; public bool forceSimplePrimMeshing = false; @@ -480,6 +481,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_NINJA_physics_joints_enabled = physicsconfig.GetBoolean("use_NINJA_physics_joints", false); minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f); + maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", 10000.01f); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 267928b743..e694f15611 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3588,6 +3588,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { parentPrim.DelinkFromGroup(part.LocalId, true); } + parentPrim.HasGroupChanged = true; + parentPrim.ScheduleGroupForFullUpdate(); parentPrim.TriggerScriptChangedEvent(Changed.LINK); if (parts.Count > 0) @@ -3599,6 +3601,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api part.UpdateFlag = 0; newRoot.ParentGroup.LinkToGroup(part.ParentGroup); } + newRoot.ParentGroup.HasGroupChanged = true; + newRoot.ParentGroup.ScheduleGroupForFullUpdate(); } } else @@ -3607,6 +3611,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; parentPrim.DelinkFromGroup(childPrim.LocalId, true); + parentPrim.HasGroupChanged = true; + parentPrim.ScheduleGroupForFullUpdate(); parentPrim.TriggerScriptChangedEvent(Changed.LINK); } } @@ -3626,6 +3632,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parentPrim.DelinkFromGroup(part.LocalId, true); parentPrim.TriggerScriptChangedEvent(Changed.LINK); } + parentPrim.HasGroupChanged = true; + parentPrim.ScheduleGroupForFullUpdate(); } public LSL_String llGetLinkKey(int linknum) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 49c69ab9e4..184af19ebf 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -150,7 +150,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine } else { - m_scriptsLock.ExitReadLock(); + if (m_scriptsLock.RecursiveReadCount > 0) + { + m_scriptsLock.ExitReadLock(); + } } } private void lockScriptsForWrite(bool locked) @@ -179,7 +182,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine } else { - m_scriptsLock.ExitWriteLock(); + if (m_scriptsLock.RecursiveWriteCount > 0) + { + m_scriptsLock.ExitWriteLock(); + } } } diff --git a/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs b/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs index c2ad9db027..a1c032ec64 100644 --- a/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs @@ -67,7 +67,7 @@ namespace OpenSim.Services.Connectors IConfig authorizationConfig = source.Configs["AuthorizationService"]; if (authorizationConfig == null) { - m_log.Error("[AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini"); + m_log.Info("[AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini"); throw new Exception("Authorization connector init error"); } diff --git a/bin/IronMath.dll b/bin/IronMath.dll deleted file mode 100644 index 4960cc6653..0000000000 Binary files a/bin/IronMath.dll and /dev/null differ diff --git a/bin/IronPython.dll b/bin/IronPython.dll deleted file mode 100644 index 2efe7ef6e2..0000000000 Binary files a/bin/IronPython.dll and /dev/null differ diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index f9d9ca6b36..62aceb1a39 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -91,7 +91,7 @@ ; Maximum total size, and maximum size where a prim can be physical NonPhysicalPrimMax = 256 - PhysicalPrimMax = 10 + PhysicalPrimMax = 10 ; (I think this was moved to the Regions.ini!) ClampPrimSize = false ; Region crossing @@ -342,7 +342,7 @@ ; The MessagingServer is a companion of the UserServer. It uses ; user_send_key and user_recv_key, too - ;messaging_server_url = "http://127.0.0.1:8006" + messaging_server_url = "http://127.0.0.1:8006" ; What is reported as the "X-Secondlife-Shard" ; Defaults to the user server url if not set @@ -597,6 +597,9 @@ body_motor_joint_maxforce_tensor_linux = 5 body_motor_joint_maxforce_tensor_win = 5 + ; Maximum mass an object can be before it is clamped + maximum_mass_object = 10000.01 + ; ## ; ## Sculpted Prim settings ; ## @@ -1155,7 +1158,6 @@ safemode = false [VivoxVoice] - ; The VivoxVoice module will allow you to provide voice on your ; region(s). It uses the same voice technology as the LL grid and ; works with recent LL clients (we have tested 1.22.9.110075, so @@ -1296,6 +1298,15 @@ RootReprioritizationDistance = 10.0 ChildReprioritizationDistance = 20.0 + +[WebStats] +; View region statistics via a web page +; See http://opensimulator.org/wiki/FAQ#Region_Statistics_on_a_Web_Page +; Use a web browser and type in the "Login URI" + "/SStats/" +; For example- http://127.0.0.1:9000/SStats/ +; enabled=false + + ;; ;; These are defaults that are overwritten below in [Architecture]. ;; These defaults allow OpenSim to work out of the box with