From 5e4d6cab00cb29cd088ab7b62ab13aff103b64cb Mon Sep 17 00:00:00 2001 From: onefang Date: Sun, 19 May 2019 21:24:15 +1000 Subject: Dump OpenSim 0.9.0.1 into it's own branch. --- OpenSim/Addons/Groups/GroupsExtendedData.cs | 4 +- OpenSim/Addons/Groups/GroupsMessagingModule.cs | 34 +- OpenSim/Addons/Groups/GroupsModule.cs | 404 +- .../Hypergrid/GroupsServiceHGConnectorModule.cs | 20 +- .../Hypergrid/HGGroupsServiceRobustConnector.cs | 11 +- OpenSim/Addons/Groups/IGroupsServicesConnector.cs | 8 +- .../Local/GroupsServiceLocalConnectorModule.cs | 10 +- OpenSim/Addons/Groups/Properties/AssemblyInfo.cs | 10 +- .../Groups/Remote/GroupsServiceRemoteConnector.cs | 4 +- .../Remote/GroupsServiceRemoteConnectorModule.cs | 14 +- .../Groups/Remote/GroupsServiceRobustConnector.cs | 21 +- OpenSim/Addons/Groups/Service/GroupsService.cs | 59 +- OpenSim/Addons/Groups/Service/GroupsServiceBase.cs | 110 +- OpenSim/Addons/Groups/Service/HGGroupsService.cs | 2 +- OpenSim/Addons/OfflineIM/OfflineIMRegionModule.cs | 16 - .../Addons/OfflineIM/Properties/AssemblyInfo.cs | 10 +- .../Remote/OfflineIMServiceRemoteConnector.cs | 4 +- .../Addons/OfflineIM/Service/OfflineIMService.cs | 2 +- .../LoadRegions/LoadRegionsPlugin.cs | 2 +- .../LoadRegions/Properties/AssemblyInfo.cs | 3 +- .../LoadRegions/RegionLoaderFileSystem.cs | 25 +- .../LoadRegions/RegionLoaderWebServer.cs | 106 +- .../Properties/AssemblyInfo.cs | 10 +- .../RegionModulesControllerPlugin.cs | 12 +- .../RemoteController/Properties/AssemblyInfo.cs | 10 +- .../RemoteController/RemoteAdminPlugin.cs | 386 +- OpenSim/Capabilities/Caps.cs | 29 +- OpenSim/Capabilities/CapsHandlers.cs | 35 +- .../AvatarPickerSearchHandler.cs | 2 +- .../Handlers/FetchInventory/FetchInvDescHandler.cs | 46 +- .../FetchInventory/FetchInventory2Handler.cs | 33 +- .../FetchInventory2ServerConnector.cs | 71 + .../Tests/FetchInventory2HandlerTests.cs | 2 +- .../FetchInventoryDescendents2HandlerTests.cs | 7 +- .../GetDisplayNames/GetDisplayNamesHandler.cs | 61 +- .../GetDisplayNamesServerConnector.cs | 2 - .../Handlers/GetMesh/GetMeshHandler.cs | 332 +- .../Handlers/GetMesh/GetMeshServerConnector.cs | 16 +- .../Handlers/GetTexture/GetTextureHandler.cs | 267 +- .../Handlers/GetTexture/GetTextureRobustHandler.cs | 394 ++ .../GetTexture/GetTextureServerConnector.cs | 6 +- .../GetTexture/Tests/GetTextureHandlerTests.cs | 4 +- .../Handlers/Properties/AssemblyInfo.cs | 10 +- .../UploadBakedTextureHandler.cs | 26 +- .../UploadBakedTextureServerConnector.cs | 2 +- OpenSim/Capabilities/LLSD.cs | 4 +- OpenSim/Capabilities/LLSDAssetUploadComplete.cs | 7 + OpenSim/Capabilities/LLSDAssetUploadRequest.cs | 15 +- OpenSim/Capabilities/LLSDAssetUploadResponse.cs | 35 +- OpenSim/Capabilities/LLSDAvatarPicker.cs | 2 +- OpenSim/Capabilities/LLSDHelpers.cs | 5 + OpenSim/Capabilities/LLSDInventoryItem.cs | 6 +- OpenSim/Capabilities/LLSDStreamHandler.cs | 3 + OpenSim/Capabilities/Properties/AssemblyInfo.cs | 8 +- OpenSim/ConsoleClient/ConsoleClient.cs | 6 +- OpenSim/ConsoleClient/Properties/AssemblyInfo.cs | 8 +- OpenSim/Data/AssetDataBase.cs | 2 +- OpenSim/Data/DBGuids.cs | 2 +- OpenSim/Data/IAssetData.cs | 2 +- OpenSim/Data/IAvatarData.cs | 2 +- OpenSim/Data/IEstateDataStore.cs | 16 +- OpenSim/Data/IGridUserData.cs | 2 +- OpenSim/Data/IGroupsData.cs | 2 +- OpenSim/Data/IHGTravelingData.cs | 2 +- OpenSim/Data/IMuteListData.cs | 44 + OpenSim/Data/IOfflineIMData.cs | 2 +- OpenSim/Data/IPresenceData.cs | 2 +- OpenSim/Data/IProfilesData.cs | 2 +- OpenSim/Data/IRegionData.cs | 2 +- OpenSim/Data/IUserAccountData.cs | 1 + OpenSim/Data/IXGroupData.cs | 6 +- OpenSim/Data/Migration.cs | 26 +- OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs | 2 +- OpenSim/Data/MySQL/MySQLAssetData.cs | 112 +- OpenSim/Data/MySQL/MySQLAuthenticationData.cs | 58 +- OpenSim/Data/MySQL/MySQLAvatarData.cs | 2 +- OpenSim/Data/MySQL/MySQLEstateData.cs | 26 +- OpenSim/Data/MySQL/MySQLFSAssetData.cs | 397 +- OpenSim/Data/MySQL/MySQLFramework.cs | 60 +- OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | 184 +- OpenSim/Data/MySQL/MySQLGroupsData.cs | 23 +- OpenSim/Data/MySQL/MySQLInventoryData.cs | 26 +- OpenSim/Data/MySQL/MySQLMigrations.cs | 6 +- OpenSim/Data/MySQL/MySQLMuteListData.cs | 67 + OpenSim/Data/MySQL/MySQLOfflineIMData.cs | 2 +- OpenSim/Data/MySQL/MySQLPresenceData.cs | 8 +- OpenSim/Data/MySQL/MySQLRegionData.cs | 78 +- OpenSim/Data/MySQL/MySQLSimulationData.cs | 710 ++- OpenSim/Data/MySQL/MySQLUserAccountData.cs | 40 +- OpenSim/Data/MySQL/MySQLUserProfilesData.cs | 588 +- OpenSim/Data/MySQL/MySQLXAssetData.cs | 113 +- OpenSim/Data/MySQL/MySQLXInventoryData.cs | 16 +- OpenSim/Data/MySQL/Properties/AssemblyInfo.cs | 2 +- OpenSim/Data/MySQL/Resources/AgentPrefs.migrations | 2 +- OpenSim/Data/MySQL/Resources/AssetStore.migrations | 76 +- OpenSim/Data/MySQL/Resources/AuthStore.migrations | 37 +- OpenSim/Data/MySQL/Resources/Avatar.migrations | 23 +- .../Data/MySQL/Resources/EstateStore.migrations | 80 +- .../Data/MySQL/Resources/FSAssetStore.migrations | 2 +- .../Data/MySQL/Resources/FriendsStore.migrations | 36 +- OpenSim/Data/MySQL/Resources/GridStore.migrations | 141 +- .../Data/MySQL/Resources/GridUserStore.migrations | 2 +- .../Data/MySQL/Resources/HGTravelStore.migrations | 2 +- OpenSim/Data/MySQL/Resources/IM_Store.migrations | 46 +- .../Data/MySQL/Resources/InventoryStore.migrations | 143 +- OpenSim/Data/MySQL/Resources/LogStore.migrations | 2 +- .../Data/MySQL/Resources/MuteListStore.migrations | 16 + OpenSim/Data/MySQL/Resources/Presence.migrations | 37 +- .../Data/MySQL/Resources/RegionStore.migrations | 1183 ++-- .../Data/MySQL/Resources/UserAccount.migrations | 56 +- .../Data/MySQL/Resources/UserProfiles.migrations | 28 +- OpenSim/Data/MySQL/Resources/UserStore.migrations | 168 - .../Data/MySQL/Resources/XAssetStore.migrations | 4 +- OpenSim/Data/MySQL/Resources/XMute.migrations | 16 + .../MySQL/Resources/os_groups_Store.migrations | 14 +- OpenSim/Data/Null/NullEstateData.cs | 6 +- OpenSim/Data/Null/NullFriendsData.cs | 10 +- OpenSim/Data/Null/NullPresenceData.cs | 8 +- OpenSim/Data/Null/NullRegionData.cs | 20 +- OpenSim/Data/Null/NullSimulationData.cs | 22 + OpenSim/Data/Null/NullUserAccountData.cs | 37 +- OpenSim/Data/Null/Properties/AssemblyInfo.cs | 2 +- OpenSim/Data/PGSQL/PGSQLAgentPreferencesData.cs | 16 +- OpenSim/Data/PGSQL/PGSQLAssetData.cs | 21 +- OpenSim/Data/PGSQL/PGSQLAuthenticationData.cs | 6 +- OpenSim/Data/PGSQL/PGSQLAvatarData.cs | 2 +- OpenSim/Data/PGSQL/PGSQLEstateData.cs | 2 +- OpenSim/Data/PGSQL/PGSQLFSAssetData.cs | 316 ++ OpenSim/Data/PGSQL/PGSQLFriendsData.cs | 6 +- OpenSim/Data/PGSQL/PGSQLGenericTableHandler.cs | 51 +- OpenSim/Data/PGSQL/PGSQLGroupsData.cs | 40 +- OpenSim/Data/PGSQL/PGSQLInventoryData.cs | 58 +- OpenSim/Data/PGSQL/PGSQLManager.cs | 4 +- OpenSim/Data/PGSQL/PGSQLMigration.cs | 4 +- OpenSim/Data/PGSQL/PGSQLOfflineIMData.cs | 2 +- OpenSim/Data/PGSQL/PGSQLPresenceData.cs | 4 +- OpenSim/Data/PGSQL/PGSQLRegionData.cs | 82 +- OpenSim/Data/PGSQL/PGSQLSimulationData.cs | 307 +- OpenSim/Data/PGSQL/PGSQLUserAccountData.cs | 25 +- OpenSim/Data/PGSQL/PGSQLUserProfilesData.cs | 12 +- OpenSim/Data/PGSQL/PGSQLXAssetData.cs | 94 +- OpenSim/Data/PGSQL/PGSQLXInventoryData.cs | 19 +- OpenSim/Data/PGSQL/Properties/AssemblyInfo.cs | 2 +- OpenSim/Data/PGSQL/Resources/AgentPrefs.migrations | 19 + OpenSim/Data/PGSQL/Resources/AuthStore.migrations | 8 + .../Data/PGSQL/Resources/EstateStore.migrations | 410 +- .../Data/PGSQL/Resources/FSAssetStore.migrations | 14 + OpenSim/Data/PGSQL/Resources/Presence.migrations | 0 .../Data/PGSQL/Resources/RegionStore.migrations | 67 +- .../Data/PGSQL/Resources/UserAccount.migrations | 6 + .../Data/PGSQL/Resources/UserProfiles.migrations | 10 +- OpenSim/Data/Properties/AssemblyInfo.cs | 2 +- OpenSim/Data/SQLite/Properties/AssemblyInfo.cs | 2 +- .../Data/SQLite/Resources/AgentPrefs.migrations | 2 +- .../Data/SQLite/Resources/AssetStore.migrations | 71 +- .../Data/SQLite/Resources/EstateStore.migrations | 68 +- .../SQLite/Resources/InventoryStore.migrations | 92 - .../Data/SQLite/Resources/RegionStore.migrations | 549 +- .../Data/SQLite/Resources/UserAccount.migrations | 8 + .../Data/SQLite/Resources/UserProfiles.migrations | 2 +- OpenSim/Data/SQLite/Resources/UserStore.migrations | 169 - OpenSim/Data/SQLite/SQLiteAssetData.cs | 12 +- OpenSim/Data/SQLite/SQLiteAuthenticationData.cs | 6 +- OpenSim/Data/SQLite/SQLiteEstateData.cs | 12 +- OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs | 4 +- OpenSim/Data/SQLite/SQLiteGridUserData.cs | 2 +- OpenSim/Data/SQLite/SQLiteHGTravelData.cs | 2 +- OpenSim/Data/SQLite/SQLiteInventoryStore.cs | 916 --- OpenSim/Data/SQLite/SQLiteSimulationData.cs | 158 +- OpenSim/Data/SQLite/SQLiteUserAccountData.cs | 7 +- OpenSim/Data/SQLite/SQLiteUserProfilesData.cs | 165 +- OpenSim/Data/SQLite/SQLiteUtils.cs | 6 +- OpenSim/Data/SQLite/SQLiteXInventoryData.cs | 14 +- OpenSim/Data/Tests/AssetTests.cs | 24 +- OpenSim/Data/Tests/BasicDataServiceTest.cs | 14 +- OpenSim/Data/Tests/DefaultTestConns.cs | 10 +- OpenSim/Data/Tests/EstateTests.cs | 18 +- OpenSim/Data/Tests/InventoryTests.cs | 33 +- OpenSim/Data/Tests/PropertyScrambler.cs | 2 +- OpenSim/Data/Tests/RegionTests.cs | 161 +- .../Data/Tests/Resources/TestDataConnections.ini | 4 +- OpenSim/Framework/AgentCircuitData.cs | 10 +- OpenSim/Framework/AgentUpdateArgs.cs | 2 + OpenSim/Framework/AnimationSet.cs | 186 + OpenSim/Framework/AssemblyInfo.cs | 2 +- OpenSim/Framework/AssetBase.cs | 19 +- .../Filesystem/Properties/AssemblyInfo.cs | 10 +- OpenSim/Framework/AssetRequestToClient.cs | 6 +- OpenSim/Framework/AvatarAppearance.cs | 162 +- OpenSim/Framework/AvatarWearable.cs | 38 +- OpenSim/Framework/BasicDOSProtector.cs | 14 +- OpenSim/Framework/BlockingQueue.cs | 8 +- OpenSim/Framework/Cache.cs | 83 +- OpenSim/Framework/CapsUtil.cs | 2 +- OpenSim/Framework/ChildAgentDataUpdate.cs | 337 +- OpenSim/Framework/CircularBuffer.cs | 20 +- OpenSim/Framework/Client/IClientIPEndpoint.cs | 2 +- OpenSim/Framework/ClientInfo.cs | 10 - OpenSim/Framework/ClientManager.cs | 48 +- OpenSim/Framework/CnmMemoryCache.cs | 140 +- OpenSim/Framework/CnmSynchronizedCache.cs | 106 +- OpenSim/Framework/ColliderData.cs | 1 + OpenSim/Framework/ConfigurationMember.cs | 530 ++ OpenSim/Framework/Console/AssemblyInfo.cs | 2 +- OpenSim/Framework/Console/CommandConsole.cs | 44 +- OpenSim/Framework/Console/ConsoleBase.cs | 8 +- OpenSim/Framework/Console/ConsolePluginCommand.cs | 0 OpenSim/Framework/Console/ConsoleUtil.cs | 22 +- OpenSim/Framework/Console/LocalConsole.cs | 24 +- OpenSim/Framework/Console/MockConsole.cs | 4 +- OpenSim/Framework/Console/RemoteConsole.cs | 317 +- OpenSim/Framework/Constants.cs | 12 +- OpenSim/Framework/Crc32.cs | 139 + OpenSim/Framework/CustomTypes.cs | 43 + OpenSim/Framework/DAMap.cs | 40 +- OpenSim/Framework/DOMap.cs | 2 +- .../Framework/DoubleDictionaryThreadAbortSafe.cs | 193 +- OpenSim/Framework/EntityTransferContext.cs | 70 + OpenSim/Framework/EstateBan.cs | 2 +- OpenSim/Framework/EstateSettings.cs | 109 +- OpenSim/Framework/GridInstantMessage.cs | 2 + OpenSim/Framework/IAssetCache.cs | 71 + OpenSim/Framework/IClientAPI.cs | 221 +- OpenSim/Framework/ICnmCache.cs | 106 +- OpenSim/Framework/IImprovedAssetCache.cs | 64 - OpenSim/Framework/ILandChannel.cs | 11 +- OpenSim/Framework/ILandObject.cs | 94 +- OpenSim/Framework/IMoneyModule.cs | 9 +- OpenSim/Framework/IPrimCounts.cs | 14 +- OpenSim/Framework/IRegistryCore.cs | 2 +- OpenSim/Framework/IScene.cs | 4 +- OpenSim/Framework/ISceneAgent.cs | 17 +- OpenSim/Framework/InventoryFolderImpl.cs | 2 +- OpenSim/Framework/InventoryItemBase.cs | 110 +- OpenSim/Framework/InventoryNodeBase.cs | 8 +- OpenSim/Framework/LandData.cs | 58 +- OpenSim/Framework/LandUpdateArgs.cs | 3 + OpenSim/Framework/Lazy.cs | 4 +- OpenSim/Framework/LocklessQueue.cs | 16 +- OpenSim/Framework/LogWriter.cs | 0 OpenSim/Framework/MapAndArray.cs | 12 +- OpenSim/Framework/MapItemReplyStruct.cs | 2 +- OpenSim/Framework/MetricsCollector.cs | 8 +- OpenSim/Framework/Monitoring/BaseStatsCollector.cs | 26 +- OpenSim/Framework/Monitoring/Checks/Check.cs | 8 +- OpenSim/Framework/Monitoring/ChecksManager.cs | 45 +- .../Monitoring/Interfaces/IStatsCollector.cs | 2 +- OpenSim/Framework/Monitoring/JobEngine.cs | 162 +- .../Monitoring/Properties/AssemblyInfo.cs | 10 +- .../Framework/Monitoring/ServerStatsCollector.cs | 77 +- .../Framework/Monitoring/SimExtraStatsCollector.cs | 56 +- OpenSim/Framework/Monitoring/Stats/CounterStat.cs | 0 .../Framework/Monitoring/Stats/EventHistogram.cs | 346 +- OpenSim/Framework/Monitoring/Stats/Stat.cs | 51 +- OpenSim/Framework/Monitoring/StatsLogger.cs | 6 +- OpenSim/Framework/Monitoring/StatsManager.cs | 106 +- OpenSim/Framework/Monitoring/Watchdog.cs | 61 +- OpenSim/Framework/Monitoring/WorkManager.cs | 48 +- OpenSim/Framework/MuteData.cs | 41 + OpenSim/Framework/NetworkServersInfo.cs | 2 + OpenSim/Framework/NetworkUtil.cs | 4 +- OpenSim/Framework/OSChatMessage.cs | 21 +- OpenSim/Framework/ObjectChangeData.cs | 80 + OpenSim/Framework/OutboundUrlFilter.cs | 30 +- OpenSim/Framework/ParcelMediaCommandEnum.cs | 2 +- OpenSim/Framework/PermissionsUtil.cs | 57 +- OpenSim/Framework/PhysicsInertia.cs | 263 + OpenSim/Framework/PluginLoader.cs | 17 +- OpenSim/Framework/PluginManager.cs | 54 +- OpenSim/Framework/PrimeNumberHelper.cs | 2 +- OpenSim/Framework/PrimitiveBaseShape.cs | 153 +- OpenSim/Framework/PriorityQueue.cs | 88 +- OpenSim/Framework/RegionInfo.cs | 419 +- OpenSim/Framework/RegionSettings.cs | 42 +- OpenSim/Framework/RestClient.cs | 36 +- OpenSim/Framework/SLUtil.cs | 14 +- .../Framework/Serialization/ArchiveConstants.cs | 4 +- .../External/ExternalRepresentationUtils.cs | 9 +- .../Serialization/External/LandDataSerializer.cs | 1 + .../Serialization/External/OspResolver.cs | 44 +- .../External/RegionSettingsSerializer.cs | 35 +- .../External/UserInventoryItemSerializer.cs | 24 +- .../External/UserProfileSerializer.cs | 12 +- .../Serialization/Properties/AssemblyInfo.cs | 10 +- .../Framework/Serialization/TarArchiveWriter.cs | 12 +- OpenSim/Framework/Servers/BaseOpenSimServer.cs | 73 +- .../Framework/Servers/HttpServer/BaseHttpServer.cs | 204 +- .../Servers/HttpServer/BaseRequestHandler.cs | 14 +- .../Servers/HttpServer/BaseStreamHandler.cs | 4 +- .../BaseStreamHandlerBasicDOSProtector.cs | 8 +- .../HttpServer/GenericHTTPBasicDOSProtector.cs | 6 +- .../Servers/HttpServer/Interfaces/IHttpServer.cs | 34 +- .../HttpServer/Interfaces/IStreamHandler.cs | 2 +- .../Servers/HttpServer/JsonRpcRequestManager.cs | 7 +- .../Servers/HttpServer/JsonRpcResponse.cs | 2 +- .../Framework/Servers/HttpServer/OSHttpRequest.cs | 12 +- .../Framework/Servers/HttpServer/OSHttpResponse.cs | 4 +- .../Servers/HttpServer/OSHttpStatusCodes.cs | 2 +- .../Servers/HttpServer/PollServiceEventArgs.cs | 10 +- .../Servers/HttpServer/PollServiceHttpRequest.cs | 85 +- .../HttpServer/PollServiceRequestManager.cs | 327 +- .../Servers/HttpServer/Properties/AssemblyInfo.cs | 10 +- .../Servers/HttpServer/RestDeserialiseHandler.cs | 2 + .../Servers/HttpServer/RestSessionService.cs | 6 +- .../Servers/HttpServer/RestStreamHandler.cs | 7 +- .../Servers/HttpServer/WebsocketServerHandler.cs | 82 +- .../Servers/HttpServer/XmlRpcBasicDOSProtector.cs | 6 +- OpenSim/Framework/Servers/MainServer.cs | 26 +- .../Framework/Servers/Properties/AssemblyInfo.cs | 8 +- OpenSim/Framework/Servers/ServerBase.cs | 180 +- OpenSim/Framework/Servers/Tests/OSHttpTests.cs | 341 +- .../Framework/Servers/Tests/VersionInfoTests.cs | 2 +- .../ServiceAuth/BasicHttpAuthentication.cs | 2 +- .../ServiceAuth/CompoundAuthentication.cs | 2 +- OpenSim/Framework/SimStats.cs | 24 +- OpenSim/Framework/TaskInventoryDictionary.cs | 196 +- OpenSim/Framework/TaskInventoryItem.cs | 11 + OpenSim/Framework/TerrainData.cs | 324 +- OpenSim/Framework/Tests/AgentCircuitDataTest.cs | 11 +- .../Framework/Tests/AgentCircuitManagerTests.cs | 2 +- OpenSim/Framework/Tests/AnimationTests.cs | 2 +- OpenSim/Framework/Tests/CacheTests.cs | 4 +- OpenSim/Framework/Tests/LocationTest.cs | 2 +- OpenSim/Framework/Tests/MundaneFrameworkTests.cs | 23 +- OpenSim/Framework/Tests/PrimeNumberHelperTests.cs | 6 +- OpenSim/Framework/Tests/UtilTest.cs | 13 +- OpenSim/Framework/ThrottleOutPacketType.cs | 2 + OpenSim/Framework/UserProfileData.cs | 8 +- OpenSim/Framework/UserProfiles.cs | 27 +- OpenSim/Framework/Util.cs | 735 ++- OpenSim/Framework/VersionInfo.cs | 32 +- OpenSim/Framework/WearableCacheItem.cs | 77 +- OpenSim/Framework/WebUtil.cs | 220 +- OpenSim/Region/Application/Application.cs | 69 +- OpenSim/Region/Application/ConfigurationLoader.cs | 24 +- OpenSim/Region/Application/IApplicationPlugin.cs | 2 +- OpenSim/Region/Application/OpenSim.cs | 197 +- OpenSim/Region/Application/OpenSimBase.cs | 185 +- .../Region/Application/Properties/AssemblyInfo.cs | 10 +- .../Region/Application/RegionApplicationBase.cs | 38 +- .../Linden/Caps/AgentPreferencesModule.cs | 2 +- .../Linden/Caps/AvatarPickerSearchModule.cs | 2 +- .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 1610 ++++-- .../Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs | 6 +- .../Linden/Caps/BunchOfCaps/MeshCost.cs | 746 +++ .../Linden/Caps/EventQueue/EventQueueGetModule.cs | 521 +- .../Linden/Caps/EventQueue/EventQueueHelper.cs | 110 +- .../Caps/EventQueue/Tests/EventQueueTests.cs | 14 +- .../Linden/Caps/GetDisplayNamesModule.cs | 144 - .../ClientStack/Linden/Caps/GetMeshModule.cs | 329 +- .../ClientStack/Linden/Caps/GetTextureModule.cs | 412 +- .../Linden/Caps/MeshUploadFlagModule.cs | 22 +- .../NewFileAgentInventoryVariablePriceModule.cs | 297 - .../Linden/Caps/ObjectCaps/ObjectAdd.cs | 14 +- .../Caps/ObjectCaps/UploadObjectAssetModule.cs | 18 +- .../Linden/Caps/Properties/AssemblyInfo.cs | 10 +- .../ClientStack/Linden/Caps/RegionConsoleModule.cs | 18 +- .../Linden/Caps/SimulatorFeaturesModule.cs | 17 +- .../Caps/Tests/WebFetchInvDescModuleTests.cs | 4 +- .../Linden/Caps/UploadBakedTextureModule.cs | 203 +- .../Linden/Caps/WebFetchInvDescModule.cs | 101 +- OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs | 7 +- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 3447 ++++++----- .../ClientStack/Linden/UDP/LLImageManager.cs | 2 +- .../Region/ClientStack/Linden/UDP/LLUDPClient.cs | 388 +- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 778 ++- .../ClientStack/Linden/UDP/LLUDPServerCommands.cs | 87 +- .../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 139 +- .../Region/ClientStack/Linden/UDP/PacketPool.cs | 10 +- .../Linden/UDP/Properties/AssemblyInfo.cs | 10 +- .../Linden/UDP/Tests/BasicCircuitTests.cs | 47 +- .../Linden/UDP/Tests/PacketHandlerTests.cs | 8 +- .../ClientStack/Linden/UDP/Tests/ThrottleTests.cs | 75 +- .../Region/ClientStack/Linden/UDP/ThrottleRates.cs | 27 +- .../Region/ClientStack/Linden/UDP/TokenBucket.cs | 405 +- .../Linden/UDP/UnackedPacketCollection.cs | 21 +- .../Region/ClientStack/Properties/AssemblyInfo.cs | 8 +- .../AssetTransaction/AgentAssetsTransactions.cs | 30 +- .../AssetTransaction/AssetTransactionModule.cs | 12 +- .../Agent/AssetTransaction/AssetXferUploader.cs | 295 +- .../Region/CoreModules/Agent/IPBan/IPBanModule.cs | 8 +- .../Region/CoreModules/Agent/IPBan/SceneBanner.cs | 4 +- .../Agent/TextureSender/J2KDecoderModule.cs | 11 +- .../Region/CoreModules/Agent/Xfer/XferModule.cs | 365 +- .../Region/CoreModules/Asset/CenomeAssetCache.cs | 38 +- OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs | 23 +- .../Region/CoreModules/Asset/FlotsamAssetCache.cs | 371 +- .../CoreModules/Asset/GlynnTuckerAssetCache.cs | 24 +- .../Asset/Tests/FlotsamAssetCacheTests.cs | 2 +- .../Avatar/Attachments/AttachmentsModule.cs | 367 +- .../Attachments/Tests/AttachmentsModuleTests.cs | 92 +- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 616 +- .../Tests/AvatarFactoryModuleTests.cs | 18 +- .../Avatar/BakedTextures/XBakesModule.cs | 97 +- .../Region/CoreModules/Avatar/Chat/ChatModule.cs | 293 +- .../Avatar/Chat/Tests/ChatModuleTests.cs | 67 +- .../CoreModules/Avatar/Combat/CombatModule.cs | 2 - .../Avatar/Commands/UserCommandsModule.cs | 8 +- .../CoreModules/Avatar/Dialog/DialogModule.cs | 6 +- .../Avatar/Friends/CallingCardModule.cs | 5 +- .../CoreModules/Avatar/Friends/FriendsModule.cs | 169 +- .../Avatar/Friends/FriendsRequestHandler.cs | 17 +- .../CoreModules/Avatar/Friends/HGFriendsModule.cs | 58 +- .../CoreModules/Avatar/Friends/HGStatusNotifier.cs | 2 +- .../Avatar/Friends/Tests/FriendModuleTests.cs | 2 +- .../CoreModules/Avatar/Gestures/GesturesModule.cs | 20 +- .../Region/CoreModules/Avatar/Gods/GodsModule.cs | 213 +- .../CoreModules/Avatar/Groups/GroupsModule.cs | 19 +- .../InstantMessage/HGMessageTransferModule.cs | 31 +- .../Avatar/InstantMessage/InstantMessageModule.cs | 69 +- .../Avatar/InstantMessage/MessageTransferModule.cs | 297 +- .../Avatar/InstantMessage/MuteListModule.cs | 4 +- .../Avatar/InstantMessage/MuteListModuleTst.cs | 229 + .../Avatar/InstantMessage/OfflineMessageModule.cs | 132 +- .../Avatar/InstantMessage/XMuteModule.cs | 239 + .../Archiver/InventoryArchiveReadRequest.cs | 297 +- .../Inventory/Archiver/InventoryArchiveUtils.cs | 38 +- .../Archiver/InventoryArchiveWriteRequest.cs | 48 +- .../Inventory/Archiver/InventoryArchiverModule.cs | 217 +- .../Tests/InventoryArchiveLoadPathTests.cs | 120 +- .../Archiver/Tests/InventoryArchiveLoadTests.cs | 84 +- .../Archiver/Tests/InventoryArchiveSaveTests.cs | 60 +- .../Archiver/Tests/InventoryArchiveTestCase.cs | 74 +- .../Inventory/Transfer/InventoryTransferModule.cs | 236 +- .../Transfer/Tests/InventoryTransferModuleTests.cs | 178 +- .../Region/CoreModules/Avatar/Lure/HGLureModule.cs | 6 +- .../Region/CoreModules/Avatar/Lure/LureModule.cs | 30 +- .../Avatar/Profile/BasicProfileModule.cs | 6 +- .../Avatar/UserProfiles/UserProfileModule.cs | 986 +++- .../Framework/Caps/CapabilitiesModule.cs | 150 +- .../Framework/DynamicAttributes/DAExampleModule.cs | 30 +- .../Framework/DynamicAttributes/DOExampleModule.cs | 24 +- .../EntityTransfer/EntityTransferModule.cs | 1709 +++--- .../EntityTransfer/EntityTransferStateMachine.cs | 44 +- .../EntityTransfer/HGEntityTransferModule.cs | 84 +- .../Framework/InterfaceCommander/Commander.cs | 20 +- .../Framework/InventoryAccess/HGAssetMapper.cs | 8 +- .../InventoryAccess/HGInventoryAccessModule.cs | 86 +- .../InventoryAccess/InventoryAccessModule.cs | 557 +- .../InventoryAccess/Tests/HGAssetMapperTests.cs | 9 +- .../Tests/InventoryAccessModuleTests.cs | 64 +- .../CoreModules/Framework/Library/LibraryModule.cs | 6 +- .../Framework/Library/LocalInventoryService.cs | 15 +- .../Framework/Monitoring/MonitorModule.cs | 12 +- .../Framework/Search/BasicSearchModule.cs | 2 +- .../ServiceThrottle/ServiceThrottleModule.cs | 148 +- .../Statistics/Logging/BinaryLoggingModule.cs | 24 +- .../UserManagement/HGUserManagementModule.cs | 14 +- .../Tests/HGUserManagementModuleTests.cs | 2 +- .../UserManagement/UserManagementModule.cs | 345 +- .../CoreModules/Hypergrid/HGWorldMapModule.cs | 8 +- .../Region/CoreModules/Properties/AssemblyInfo.cs | 10 +- .../DynamicTexture/DynamicTextureModule.cs | 147 +- .../Scripting/EMailModules/EmailModule.cs | 31 +- .../Scripting/HttpRequest/ScriptsHttpRequests.cs | 259 +- .../HttpRequest/Tests/ScriptsHttpRequestsTests.cs | 22 +- .../CoreModules/Scripting/LSLHttp/UrlModule.cs | 542 +- .../Scripting/LoadImageURL/LoadImageURLModule.cs | 56 +- .../ScriptModuleComms/ScriptModuleCommsModule.cs | 10 +- .../VectorRender/Tests/VectorRenderModuleTests.cs | 48 +- .../Scripting/VectorRender/VectorRenderModule.cs | 122 +- .../Scripting/WorldComm/WorldCommModule.cs | 124 +- .../CoreModules/Scripting/XMLRPC/XMLRPCModule.cs | 6 +- .../Asset/AssetServiceInConnectorModule.cs | 6 +- .../AuthenticationServiceInConnectorModule.cs | 4 +- .../Grid/GridInfoServiceInConnectorModule.cs | 4 +- .../Hypergrid/HypergridServiceInConnectorModule.cs | 6 +- .../Inventory/InventoryServiceInConnectorModule.cs | 4 +- .../Land/LandServiceInConnectorModule.cs | 33 +- .../Login/LLLoginServiceInConnectorModule.cs | 4 +- .../MapImage/MapImageServiceInConnectorModule.cs | 4 +- .../Neighbour/NeighbourServiceInConnectorModule.cs | 2 +- .../SimulationServiceInConnectorModule.cs | 2 +- .../LocalUserProfilesServiceConnector.cs | 36 +- .../LocalAgentPreferencesServiceConnector.cs | 2 +- .../RemoteAgentPreferencesServiceConnector.cs | 6 +- .../ServiceConnectorsOut/Asset/HGAssetBroker.cs | 73 +- .../Asset/LocalAssetServiceConnector.cs | 44 +- .../Asset/RemoteAssetServiceConnector.cs | 6 +- .../LocalAuthenticationServiceConnector.cs | 11 +- .../RemoteAuthenticationServiceConnector.cs | 2 +- .../LocalAuthorizationServiceConnector.cs | 4 +- .../RemoteAuthorizationServiceConnector.cs | 16 +- .../Avatar/LocalAvatarServiceConnector.cs | 8 +- .../Avatar/RemoteAvatarServiceConnector.cs | 2 +- .../Grid/LocalGridServiceConnector.cs | 164 +- .../ServiceConnectorsOut/Grid/RegionCache.cs | 102 - .../ServiceConnectorsOut/Grid/RegionInfoCache.cs | 965 +++- .../Grid/RemoteGridServiceConnector.cs | 154 +- .../Grid/Tests/GridConnectorsTests.cs | 6 +- .../GridUser/ActivityDetector.cs | 35 +- .../Inventory/HGInventoryBroker.cs | 70 +- .../Inventory/InventoryCache.cs | 13 +- .../Inventory/LocalInventoryServiceConnector.cs | 18 +- .../Inventory/RemoteXInventoryServiceConnector.cs | 16 +- .../Land/LocalLandServiceConnector.cs | 25 +- .../Land/RemoteLandServiceConnector.cs | 2 +- .../MapImage/MapImageServiceModule.cs | 52 +- .../MuteList/LocalMuteListServiceConnector.cs | 188 + .../MuteList/RemoteMuteListServiceConnector.cs | 143 + .../Neighbour/LocalNeighbourServiceConnector.cs | 147 - .../Neighbour/NeighbourServiceOutConnector.cs | 136 + .../Neighbour/RemoteNeighourServiceConnector.cs | 157 - .../Presence/PresenceDetector.cs | 18 +- .../Presence/Tests/PresenceConnectorsTests.cs | 2 +- .../Simulation/LocalSimulationConnector.cs | 10 +- .../Simulation/RemoteSimulationConnector.cs | 17 +- .../LocalUserAccountServiceConnector.cs | 55 +- .../RemoteUserAccountServiceConnector.cs | 61 +- .../UserAccounts/UserAccountCache.cs | 103 +- .../CoreModules/World/Access/AccessModule.cs | 2 +- .../World/Archiver/ArchiveReadRequest.cs | 363 +- .../World/Archiver/ArchiveScenesGroup.cs | 4 +- .../World/Archiver/ArchiveWriteRequest.cs | 122 +- .../CoreModules/World/Archiver/ArchiverModule.cs | 93 +- .../CoreModules/World/Archiver/AssetsArchiver.cs | 11 +- .../CoreModules/World/Archiver/AssetsDearchiver.cs | 1 + .../CoreModules/World/Archiver/AssetsRequest.cs | 232 +- .../World/Archiver/DearchiveScenesGroup.cs | 39 +- .../World/Archiver/Tests/ArchiverTests.cs | 209 +- .../World/Archiver/Tests/Resources/test-sound.wav | Bin .../Region/CoreModules/World/Cloud/CloudModule.cs | 86 +- .../CoreModules/World/Estate/EstateConnector.cs | 228 + .../World/Estate/EstateManagementCommands.cs | 38 +- .../World/Estate/EstateManagementModule.cs | 648 ++- .../CoreModules/World/Estate/EstateModule.cs | 271 + .../World/Estate/EstateRequestHandler.cs | 300 + .../CoreModules/World/Estate/XEstateConnector.cs | 218 - .../CoreModules/World/Estate/XEstateModule.cs | 255 - .../World/Estate/XEstateRequestHandler.cs | 288 - .../Region/CoreModules/World/Land/DwellModule.cs | 27 +- .../Region/CoreModules/World/Land/LandChannel.cs | 62 +- .../CoreModules/World/Land/LandManagementModule.cs | 1333 +++-- .../Region/CoreModules/World/Land/LandObject.cs | 886 ++- .../CoreModules/World/Land/PrimCountModule.cs | 177 +- .../World/Land/Tests/LandManagementModuleTests.cs | 40 +- .../World/Land/Tests/PrimCountModuleTests.cs | 224 +- .../CoreModules/World/LegacyMap/MapImageModule.cs | 23 +- .../World/LegacyMap/ShadedMapTileRenderer.cs | 12 +- .../World/LegacyMap/TexturedMapTileRenderer.cs | 53 +- .../World/LightShare/LightShareModule.cs | 7 +- .../CoreModules/World/Media/Moap/MoapModule.cs | 255 +- .../World/Media/Moap/Tests/MoapTests.cs | 36 +- .../World/Objects/BuySell/BuySellModule.cs | 92 +- .../World/Objects/Commands/ObjectCommandsModule.cs | 120 +- .../World/Permissions/PermissionsModule.cs | 2096 ++++--- .../World/Region/RegionCommandsModule.cs | 91 +- .../CoreModules/World/Region/RestartModule.cs | 186 +- .../World/Serialiser/SerialiseObjects.cs | 2 +- .../World/Serialiser/SerialiserModule.cs | 10 +- .../World/Serialiser/Tests/SerialiserTests.cs | 28 +- .../Region/CoreModules/World/Sound/SoundModule.cs | 174 +- OpenSim/Region/CoreModules/World/Sun/SunModule.cs | 12 +- .../World/Terrain/Effects/ChannelDigger.cs | 4 +- .../World/Terrain/Effects/CookieCutter.cs | 2 +- .../Terrain/Effects/DefaultTerrainGenerator.cs | 2 +- .../CoreModules/World/Terrain/FileLoaders/BMP.cs | 10 +- .../CoreModules/World/Terrain/FileLoaders/GIF.cs | 10 +- .../Terrain/FileLoaders/GenericSystemDrawing.cs | 81 +- .../CoreModules/World/Terrain/FileLoaders/JPEG.cs | 14 +- .../CoreModules/World/Terrain/FileLoaders/LLRAW.cs | 10 +- .../CoreModules/World/Terrain/FileLoaders/PNG.cs | 10 +- .../CoreModules/World/Terrain/FileLoaders/TIFF.cs | 10 +- .../World/Terrain/FloodBrushes/FlattenArea.cs | 11 +- .../World/Terrain/FloodBrushes/LowerArea.cs | 10 +- .../World/Terrain/FloodBrushes/NoiseArea.cs | 13 +- .../World/Terrain/FloodBrushes/RaiseArea.cs | 10 +- .../World/Terrain/FloodBrushes/RevertArea.cs | 10 +- .../World/Terrain/FloodBrushes/SmoothArea.cs | 11 +- .../World/Terrain/ITerrainFloodEffect.cs | 3 +- .../CoreModules/World/Terrain/ITerrainLoader.cs | 2 +- .../World/Terrain/ITerrainPaintableEffect.cs | 3 +- .../World/Terrain/PaintBrushes/ErodeSphere.cs | 29 +- .../World/Terrain/PaintBrushes/FlattenSphere.cs | 9 +- .../World/Terrain/PaintBrushes/LowerSphere.cs | 30 +- .../World/Terrain/PaintBrushes/NoiseSphere.cs | 13 +- .../World/Terrain/PaintBrushes/OlsenSphere.cs | 12 +- .../World/Terrain/PaintBrushes/RaiseSphere.cs | 32 +- .../World/Terrain/PaintBrushes/RevertSphere.cs | 14 +- .../World/Terrain/PaintBrushes/SmoothSphere.cs | 20 +- .../World/Terrain/PaintBrushes/WeatherSphere.cs | 10 +- .../CoreModules/World/Terrain/TerrainModifier.cs | 3 - .../CoreModules/World/Terrain/TerrainModule.cs | 698 ++- .../World/Terrain/Tests/TerrainModuleTests.cs | 4 +- .../CoreModules/World/Terrain/Tests/TerrainTest.cs | 10 +- .../World/Vegetation/VegetationModule.cs | 25 +- .../CoreModules/World/Warp3DMap/TerrainSplat.cs | 12 +- .../World/Warp3DMap/Warp3DImageModule.cs | 239 +- .../World/Wind/Plugins/ConfigurableWind.cs | 19 +- .../World/Wind/Plugins/SimpleRandomWind.cs | 21 +- .../Region/CoreModules/World/Wind/WindModule.cs | 88 +- .../CoreModules/World/WorldMap/MapSearchModule.cs | 167 +- .../CoreModules/World/WorldMap/WorldMapModule.cs | 1579 +++--- .../Interfaces/IAgentAssetTransactions.cs | 4 +- .../Framework/Interfaces/IAttachmentsModule.cs | 15 +- .../Framework/Interfaces/IBakedTextureModule.cs | 5 +- .../Region/Framework/Interfaces/IBuySellModule.cs | 2 +- .../Framework/Interfaces/ICapabilitiesModule.cs | 20 +- .../Region/Framework/Interfaces/ICloudModule.cs | 2 +- OpenSim/Region/Framework/Interfaces/ICommander.cs | 4 +- .../Region/Framework/Interfaces/IDwellModule.cs | 1 + .../Framework/Interfaces/IDynamicFloaterModule.cs | 2 +- .../Framework/Interfaces/IDynamicMenuModule.cs | 1 + .../Framework/Interfaces/IDynamicTextureManager.cs | 26 +- .../Region/Framework/Interfaces/IEntityCreator.cs | 2 +- .../Framework/Interfaces/IEntityInventory.cs | 27 +- .../Framework/Interfaces/IEntityTransferModule.cs | 9 +- .../Region/Framework/Interfaces/IEstateModule.cs | 2 + OpenSim/Region/Framework/Interfaces/IEtcdModule.cs | 37 + OpenSim/Region/Framework/Interfaces/IEventQueue.cs | 22 +- .../Framework/Interfaces/IExternalCapsModule.cs | 2 +- .../Region/Framework/Interfaces/IFriendsModule.cs | 2 + OpenSim/Region/Framework/Interfaces/IGodsModule.cs | 7 +- .../Framework/Interfaces/IGroupsMessagingModule.cs | 12 +- .../Region/Framework/Interfaces/IGroupsModule.cs | 7 +- .../Region/Framework/Interfaces/IHttpRequests.cs | 6 +- .../Framework/Interfaces/IInventoryAccessModule.cs | 17 +- .../Framework/Interfaces/IJsonStoreModule.cs | 6 +- .../Framework/Interfaces/IMapImageUploadModule.cs | 9 +- .../Framework/Interfaces/IMessageTransferModule.cs | 2 +- OpenSim/Region/Framework/Interfaces/IMoapModule.cs | 8 +- OpenSim/Region/Framework/Interfaces/INPCModule.cs | 21 +- .../Framework/Interfaces/IPermissionsModule.cs | 2 +- .../Region/Framework/Interfaces/IPresenceModule.cs | 2 +- .../Framework/Interfaces/IRegionArchiverModule.cs | 28 +- .../Framework/Interfaces/IRegionCombinerModule.cs | 64 - .../Region/Framework/Interfaces/IRegionConsole.cs | 4 + .../Framework/Interfaces/IRegionModuleBase.cs | 2 +- .../Interfaces/IRegionSerialiserModule.cs | 4 +- .../Region/Framework/Interfaces/IRestartModule.cs | 1 + .../Region/Framework/Interfaces/ISearchModule.cs | 2 +- .../Framework/Interfaces/ISimulationDataService.cs | 12 +- .../Framework/Interfaces/ISimulationDataStore.cs | 22 +- OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 47 + .../Region/Framework/Interfaces/ISoundModule.cs | 2 +- .../Region/Framework/Interfaces/ITerrainChannel.cs | 8 + .../Region/Framework/Interfaces/ITerrainModule.cs | 12 +- OpenSim/Region/Framework/Interfaces/IUrlModule.cs | 7 +- .../Interfaces/IUserAccountCacheModule.cs | 35 + .../Region/Framework/Interfaces/IVoiceModule.cs | 2 +- .../Framework/Interfaces/IWindModelPlugin.cs | 2 +- OpenSim/Region/Framework/Interfaces/IWindModule.cs | 2 +- OpenSim/Region/Framework/Interfaces/IWorldComm.cs | 2 +- .../Region/Framework/Interfaces/IWorldMapModule.cs | 3 +- .../Region/Framework/Properties/AssemblyInfo.cs | 10 +- .../Framework/Scenes/Animation/AnimationSet.cs | 18 +- .../Framework/Scenes/Animation/BinBVHAnimation.cs | 40 +- .../Scenes/Animation/DefaultAvatarAnimations.cs | 6 +- .../Scenes/Animation/MovementAnimationOverrides.cs | 102 + .../Scenes/Animation/ScenePresenceAnimator.cs | 518 +- .../Framework/Scenes/AsyncInventorySender.cs | 9 +- .../Scenes/AsyncSceneObjectGroupDeleter.cs | 38 +- OpenSim/Region/Framework/Scenes/Border.cs | 148 - .../Framework/Scenes/CoalescedSceneObjects.cs | 40 +- OpenSim/Region/Framework/Scenes/CollisionSounds.cs | 342 ++ OpenSim/Region/Framework/Scenes/EntityManager.cs | 4 +- OpenSim/Region/Framework/Scenes/EventManager.cs | 337 +- OpenSim/Region/Framework/Scenes/GodController.cs | 287 + OpenSim/Region/Framework/Scenes/KeyframeMotion.cs | 372 +- OpenSim/Region/Framework/Scenes/Prioritizer.cs | 164 +- .../Region/Framework/Scenes/RegionStatsHandler.cs | 8 +- OpenSim/Region/Framework/Scenes/SOPMaterial.cs | 177 + OpenSim/Region/Framework/Scenes/SOPVehicle.cs | 803 +++ OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 948 ++-- .../Framework/Scenes/Scene.PacketHandlers.cs | 291 +- .../Region/Framework/Scenes/Scene.Permissions.cs | 525 +- OpenSim/Region/Framework/Scenes/Scene.cs | 2560 +++++---- OpenSim/Region/Framework/Scenes/SceneBase.cs | 23 +- .../Framework/Scenes/SceneCommunicationService.cs | 59 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 833 +-- OpenSim/Region/Framework/Scenes/SceneManager.cs | 256 +- .../Framework/Scenes/SceneObjectGroup.Inventory.cs | 337 +- .../Region/Framework/Scenes/SceneObjectGroup.cs | 3442 ++++++++--- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3024 ++++++---- .../Framework/Scenes/SceneObjectPartInventory.cs | 973 ++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 5029 +++++++++++------ .../Framework/Scenes/ScenePresenceStateMachine.cs | 6 +- .../CoalescedSceneObjectsSerializer.cs | 30 +- .../Scenes/Serialization/SceneObjectSerializer.cs | 317 +- .../Scenes/Serialization/SceneXmlLoader.cs | 14 +- .../Region/Framework/Scenes/SimStatsReporter.cs | 629 +-- OpenSim/Region/Framework/Scenes/TerrainChannel.cs | 182 +- .../Region/Framework/Scenes/TerrainCompressor.cs | 1611 ++++-- .../Region/Framework/Scenes/Tests/BorderTests.cs | 340 -- .../Framework/Scenes/Tests/EntityManagerTests.cs | 22 +- .../Framework/Scenes/Tests/SceneGraphTests.cs | 20 +- .../Scenes/Tests/SceneObjectBasicTests.cs | 39 +- .../Framework/Scenes/Tests/SceneObjectCopyTests.cs | 34 +- .../Scenes/Tests/SceneObjectCrossingTests.cs | 51 +- .../Scenes/Tests/SceneObjectDeRezTests.cs | 71 +- .../Scenes/Tests/SceneObjectLinkingTests.cs | 56 +- .../Scenes/Tests/SceneObjectResizeTests.cs | 6 +- .../Scenes/Tests/SceneObjectSpatialTests.cs | 3 +- .../Scenes/Tests/SceneObjectStatusTests.cs | 16 +- .../Scenes/Tests/SceneObjectUndoRedoTests.cs | 4 +- .../Scenes/Tests/SceneObjectUserGroupTests.cs | 37 +- .../Scenes/Tests/ScenePresenceAgentTests.cs | 15 +- .../Scenes/Tests/ScenePresenceAnimationTests.cs | 2 +- .../Scenes/Tests/ScenePresenceAutopilotTests.cs | 4 +- .../Scenes/Tests/ScenePresenceCapabilityTests.cs | 8 +- .../Scenes/Tests/ScenePresenceCrossingTests.cs | 8 +- .../Scenes/Tests/ScenePresenceSitTests.cs | 4 +- .../Scenes/Tests/ScenePresenceTeleportTests.cs | 10 +- .../Framework/Scenes/Tests/SceneStatisticsTests.cs | 2 +- .../Framework/Scenes/Tests/SceneTelehubTests.cs | 4 +- .../Region/Framework/Scenes/Tests/SceneTests.cs | 4 +- .../Scenes/Tests/SharedRegionModuleTests.cs | 18 +- .../Framework/Scenes/Tests/TaskInventoryTests.cs | 22 +- .../Framework/Scenes/Tests/UserInventoryTests.cs | 68 +- .../Framework/Scenes/Tests/UuidGathererTests.cs | 18 +- OpenSim/Region/Framework/Scenes/UndoState.cs | 367 +- OpenSim/Region/Framework/Scenes/UuidGatherer.cs | 231 +- .../Server/IRCClientView.cs | 352 +- .../Agent/TextureSender/J2KDecoderCommandModule.cs | 20 +- .../Agent/UDP/Linden/LindenUDPInfoModule.cs | 299 +- .../OptionalModules/Asset/AssetInfoModule.cs | 32 +- .../Avatar/Animations/AnimationsCommandModule.cs | 31 +- .../Avatar/Appearance/AppearanceInfoModule.cs | 42 +- .../Avatar/Attachments/AttachmentsCommandModule.cs | 43 +- .../Avatar/Attachments/TempAttachmentsModule.cs | 29 +- .../OptionalModules/Avatar/Chat/ChannelState.cs | 27 +- .../OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 4 +- .../OptionalModules/Avatar/Chat/IRCConnector.cs | 58 +- .../OptionalModules/Avatar/Chat/RegionState.cs | 43 +- .../Avatar/Concierge/ConciergeModule.cs | 87 +- .../Avatar/Friends/FriendsCommandsModule.cs | 20 +- .../Avatar/SitStand/SitStandCommandsModule.cs | 22 +- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 64 +- .../Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 183 +- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 237 +- .../Avatar/XmlRpcGroups/GroupsModule.cs | 517 +- .../XmlRpcGroups/IGroupsServicesConnector.cs | 7 +- .../SimianGroupsServicesConnectorModule.cs | 95 +- .../Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 23 +- .../XmlRpcGroupsServicesConnectorModule.cs | 86 +- .../DataSnapshot/DataSnapshotManager.cs | 5 +- .../OptionalModules/DataSnapshot/LandSnapshot.cs | 13 +- .../OptionalModules/DataSnapshot/ObjectSnapshot.cs | 3 +- .../BareBonesNonShared/BareBonesNonSharedModule.cs | 28 +- .../BareBonesShared/BareBonesSharedModule.cs | 32 +- .../WebSocketEchoTest/WebSocketEchoModule.cs | 10 +- .../Framework/Monitoring/EtcdMonitoringModule.cs | 195 + .../Framework/Monitoring/MonitorServicesModule.cs | 8 +- .../OptionalModules/Materials/MaterialsModule.cs | 453 +- .../PhysicsParameters/PhysicsParameters.cs | 18 +- .../PrimLimitsModule/PrimLimitsModule.cs | 125 +- .../OptionalModules/Properties/AssemblyInfo.cs | 10 +- .../RegionCombinerClientEventForwarder.cs | 94 - .../RegionCombinerIndividualEventForwarder.cs | 139 - .../RegionCombinerLargeLandChannel.cs | 201 - .../RegionCombinerModule/RegionCombinerModule.cs | 880 --- .../RegionCombinerPermissionModule.cs | 270 - .../RegionCombinerModule/RegionConnections.cs | 94 - .../RegionCombinerModule/RegionCourseLocation.cs | 43 - .../RegionCombinerModule/RegionData.cs | 40 - .../Scripting/JsonStore/JsonStore.cs | 130 +- .../Scripting/JsonStore/JsonStoreCommands.cs | 8 +- .../Scripting/JsonStore/JsonStoreModule.cs | 78 +- .../Scripting/JsonStore/JsonStoreScriptModule.cs | 114 +- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 80 +- .../Minimodule/Interfaces/IAvatarAttachment.cs | 2 +- .../Minimodule/Interfaces/IInventoryItem.cs | 2 +- .../Scripting/Minimodule/Interfaces/IObject.cs | 16 +- .../Scripting/Minimodule/InventoryItem.cs | 8 +- .../Scripting/Minimodule/MicroScheduler.cs | 2 +- .../Scripting/Minimodule/SOPObject.cs | 28 +- .../Scripting/Minimodule/SOPObjectInventory.cs | 36 +- .../Scripting/Minimodule/SPAvatar.cs | 8 +- .../Scripting/Minimodule/SPAvatarAttachment.cs | 6 +- .../Scripting/Minimodule/Test/TestModule.cs | 4 +- .../OptionalModules/Scripting/Minimodule/World.cs | 6 +- .../RegionReadyModule/RegionReadyModule.cs | 38 +- .../XmlRpcRouterModule/XmlRpcGridRouterModule.cs | 8 +- .../XmlRpcRouterModule/XmlRpcRouterModule.cs | 5 +- .../FreeswitchServiceInConnectorModule.cs | 4 +- .../UserStatistics/Clients_report.cs | 23 +- .../UserStatistics/Default_Report.cs | 19 +- .../OptionalModules/UserStatistics/HTMLUtil.cs | 4 +- .../OptionalModules/UserStatistics/LogLinesAJAX.cs | 12 +- .../UserStatistics/Prototype_distributor.cs | 2 +- .../UserStatistics/Sessions_Report.cs | 11 +- .../OptionalModules/UserStatistics/SimStatsAJAX.cs | 8 +- .../UserStatistics/WebStatsModule.cs | 40 +- .../ViewerSupport/CameraOnlyModeModule.cs | 7 +- .../ViewerSupport/DynamicFloaterModule.cs | 2 +- .../ViewerSupport/DynamicMenuModule.cs | 11 +- .../ViewerSupport/GodNamesModule.cs | 4 +- .../ViewerSupport/SimulatorFeaturesHelper.cs | 102 +- .../ViewerSupport/SpecialUIModule.cs | 5 +- .../World/AutoBackup/AutoBackupModule.cs | 791 +-- .../World/AutoBackup/AutoBackupModuleState.cs | 70 +- .../World/MoneyModule/SampleMoneyModule.cs | 156 +- .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 181 +- .../Region/OptionalModules/World/NPC/NPCModule.cs | 99 +- .../World/NPC/Tests/NPCModuleTests.cs | 8 +- .../World/SceneCommands/SceneCommandsModule.cs | 122 +- .../World/TreePopulator/TreePopulatorModule.cs | 724 ++- .../PhysicsModules/BasicPhysics/AssemblyInfo.cs | 2 +- .../BasicPhysics/BasicPhysicsActor.cs | 19 +- .../BasicPhysics/BasicPhysicsPrim.cs | 19 +- .../BasicPhysics/BasicPhysicsScene.cs | 8 +- .../Region/PhysicsModules/BulletS/BSAPIUnman.cs | 30 +- OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs | 318 +- .../PhysicsModules/BulletS/BSActorAvatarMove.cs | 106 +- .../Region/PhysicsModules/BulletS/BSActorHover.cs | 0 .../PhysicsModules/BulletS/BSActorLockAxis.cs | 0 .../PhysicsModules/BulletS/BSActorMoveToTarget.cs | 4 +- .../PhysicsModules/BulletS/BSActorSetForce.cs | 0 .../PhysicsModules/BulletS/BSActorSetTorque.cs | 2 +- OpenSim/Region/PhysicsModules/BulletS/BSActors.cs | 0 .../Region/PhysicsModules/BulletS/BSApiTemplate.cs | 141 +- .../Region/PhysicsModules/BulletS/BSCharacter.cs | 323 +- .../Region/PhysicsModules/BulletS/BSConstraint.cs | 0 .../PhysicsModules/BulletS/BSConstraint6Dof.cs | 0 .../BulletS/BSConstraintCollection.cs | 0 .../BulletS/BSConstraintConeTwist.cs | 0 .../PhysicsModules/BulletS/BSConstraintHinge.cs | 0 .../PhysicsModules/BulletS/BSConstraintSlider.cs | 0 .../PhysicsModules/BulletS/BSConstraintSpring.cs | 0 .../Region/PhysicsModules/BulletS/BSDynamics.cs | 10 +- OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs | 4 +- .../PhysicsModules/BulletS/BSLinksetCompound.cs | 1 + .../PhysicsModules/BulletS/BSLinksetConstraints.cs | 0 .../Region/PhysicsModules/BulletS/BSMaterials.cs | 0 OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs | 0 OpenSim/Region/PhysicsModules/BulletS/BSParam.cs | 238 +- .../Region/PhysicsModules/BulletS/BSPhysObject.cs | 123 +- OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs | 157 +- .../PhysicsModules/BulletS/BSPrimDisplaced.cs | 1 - .../PhysicsModules/BulletS/BSPrimLinkable.cs | 7 +- OpenSim/Region/PhysicsModules/BulletS/BSScene.cs | 329 +- .../PhysicsModules/BulletS/BSShapeCollection.cs | 7 +- OpenSim/Region/PhysicsModules/BulletS/BSShapes.cs | 10 +- .../PhysicsModules/BulletS/BSTerrainHeightmap.cs | 24 +- .../PhysicsModules/BulletS/BSTerrainManager.cs | 0 .../Region/PhysicsModules/BulletS/BSTerrainMesh.cs | 0 .../Region/PhysicsModules/BulletS/BulletSimData.cs | 1 + .../PhysicsModules/BulletS/BulletSimTODO.txt | 0 .../PhysicsModules/BulletS/ExtendedPhysics.cs | 2 +- .../BulletS/Properties/AssemblyInfo.cs | 10 +- .../PhysicsModules/BulletS/Tests/BasicVehicles.cs | 0 .../PhysicsModules/BulletS/Tests/BulletSimTests.cs | 112 +- .../BulletS/Tests/BulletSimTestsUtil.cs | 6 +- .../PhysicsModules/BulletS/Tests/HullCreation.cs | 2 +- .../Region/PhysicsModules/BulletS/Tests/Raycast.cs | 124 + .../ConvexDecompositionDotNet/CTri.cs | 26 +- .../ConvexDecompositionDotNet/Concavity.cs | 12 +- .../ConvexDecompositionDotNet/ConvexBuilder.cs | 12 +- .../ConvexDecomposition.cs | 12 +- .../ConvexDecompositionDotNet/ConvexResult.cs | 12 +- .../ConvexDecompositionDotNet/HullClasses.cs | 12 +- .../ConvexDecompositionDotNet/HullTriangle.cs | 12 +- .../ConvexDecompositionDotNet/HullUtils.cs | 79 +- .../ConvexDecompositionDotNet/Plane.cs | 12 +- .../ConvexDecompositionDotNet/PlaneTri.cs | 12 +- .../Properties/AssemblyInfo.cs | 12 +- .../ConvexDecompositionDotNet/Quaternion.cs | 18 +- .../ConvexDecompositionDotNet/SplitPlane.cs | 12 +- .../ConvexDecompositionDotNet/VertexLookup.cs | 12 +- .../ConvexDecompositionDotNet/float2.cs | 12 +- .../ConvexDecompositionDotNet/float3.cs | 12 +- .../ConvexDecompositionDotNet/float3x3.cs | 12 +- .../ConvexDecompositionDotNet/float4.cs | 12 +- .../ConvexDecompositionDotNet/float4x4.cs | 170 +- .../ConvexDecompositionDotNet/int3.cs | 12 +- .../ConvexDecompositionDotNet/int4.cs | 12 +- .../Meshing/Meshmerizer/HelperTypes.cs | 2 +- .../PhysicsModules/Meshing/Meshmerizer/Mesh.cs | 87 +- .../Meshing/Meshmerizer/Meshmerizer.cs | 43 +- .../Meshing/Meshmerizer/PrimMesher.cs | 6 +- .../Meshing/Meshmerizer/SculptMap.cs | 60 +- .../Meshing/Properties/AssemblyInfo.cs | 14 +- .../Region/PhysicsModules/Meshing/ZeroMesher.cs | 25 +- OpenSim/Region/PhysicsModules/Ode/AssemblyInfo.cs | 2 +- OpenSim/Region/PhysicsModules/Ode/ODEApi.cs | 2025 +++++++ OpenSim/Region/PhysicsModules/Ode/ODECharacter.cs | 33 +- OpenSim/Region/PhysicsModules/Ode/ODEDynamics.cs | 11 +- OpenSim/Region/PhysicsModules/Ode/ODEModule.cs | 89 + OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs | 720 +-- .../PhysicsModules/Ode/ODERayCastRequestManager.cs | 97 +- .../Region/PhysicsModules/Ode/OdePhysicsJoint.cs | 2 - OpenSim/Region/PhysicsModules/Ode/OdeScene.cs | 980 +--- .../PhysicsModules/Ode/Tests/ODETestClass.cs | 18 +- OpenSim/Region/PhysicsModules/Ode/drawstuff.cs | 98 - OpenSim/Region/PhysicsModules/POS/AssemblyInfo.cs | 2 +- OpenSim/Region/PhysicsModules/POS/POSCharacter.cs | 11 +- OpenSim/Region/PhysicsModules/POS/POSPrim.cs | 5 +- OpenSim/Region/PhysicsModules/POS/POSScene.cs | 8 +- .../PhysicsModules/SharedBase/AssemblyInfo.cs | 2 +- .../Region/PhysicsModules/SharedBase/IMesher.cs | 31 +- .../SharedBase/IPhysicsParameters.cs | 0 .../PhysicsModules/SharedBase/NullPhysicsScene.cs | 2 +- .../PhysicsModules/SharedBase/PhysicsActor.cs | 311 +- .../PhysicsModules/SharedBase/PhysicsScene.cs | 85 +- .../PhysicsModules/SharedBase/PhysicsVector.cs | 2 +- .../PhysicsModules/SharedBase/VehicleConstants.cs | 47 +- OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs | 2024 +++++++ .../Region/PhysicsModules/ubOde/ODECharacter.cs | 2036 +++++++ OpenSim/Region/PhysicsModules/ubOde/ODEDynamics.cs | 1205 ++++ .../Region/PhysicsModules/ubOde/ODEMeshWorker.cs | 946 ++++ OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs | 112 + OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs | 4256 ++++++++++++++ .../ubOde/ODERayCastRequestManager.cs | 689 +++ OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs | 2824 +++++++++ .../Region/PhysicsModules/ubOde/ODESitAvatar.cs | 356 ++ .../ubOde/Properties/AssemblyInfo.cs | 61 + .../PhysicsModules/ubOdeMeshing/HelperTypes.cs | 340 ++ OpenSim/Region/PhysicsModules/ubOdeMeshing/Mesh.cs | 636 +++ .../PhysicsModules/ubOdeMeshing/Meshmerizer.cs | 1602 ++++++ .../PhysicsModules/ubOdeMeshing/PrimMesher.cs | 1707 ++++++ .../ubOdeMeshing/Properties/AssemblyInfo.cs | 36 + .../PhysicsModules/ubOdeMeshing/SculptMap.cs | 238 + .../PhysicsModules/ubOdeMeshing/SculptMesh.cs | 220 + .../Region/ScriptEngine/Interfaces/ICompiler.cs | 2 +- .../ScriptEngine/Interfaces/IScriptEngine.cs | 6 +- .../ScriptEngine/Interfaces/IScriptInstance.cs | 6 +- .../Api/Implementation/AsyncCommandManager.cs | 123 +- .../Shared/Api/Implementation/CM_Api.cs | 129 + .../Shared/Api/Implementation/LSL_Api.cs | 5966 ++++++++++++++------ .../Shared/Api/Implementation/LS_Api.cs | 18 +- .../Shared/Api/Implementation/MOD_Api.cs | 84 +- .../Shared/Api/Implementation/OSSL_Api.cs | 2065 +++++-- .../Api/Implementation/Plugins/SensorRepeat.cs | 62 +- .../Shared/Api/Implementation/Plugins/Timer.cs | 34 +- .../Api/Implementation/Properties/AssemblyInfo.cs | 10 +- .../ScriptEngine/Shared/Api/Interface/ICM_Api.cs | 46 + .../ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 24 +- .../ScriptEngine/Shared/Api/Interface/IMOD_Api.cs | 2 +- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 50 +- .../ScriptEngine/Shared/Api/Runtime/CM_Stub.cs | 71 + .../ScriptEngine/Shared/Api/Runtime/Executor.cs | 2 + .../Shared/Api/Runtime/LSL_Constants.cs | 79 +- .../ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | 113 +- .../ScriptEngine/Shared/Api/Runtime/LS_Stub.cs | 21 + .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 173 +- ...nSim.Region.ScriptEngine.Shared.Api.Runtime.mdp | 48 - .../Shared/Api/Runtime/Properties/AssemblyInfo.cs | 8 +- .../ScriptEngine/Shared/Api/Runtime/ScriptBase.cs | 2 + .../Region/ScriptEngine/Shared/AssemblyResolver.cs | 2 +- .../Shared/CodeTools/CSCodeGenerator.cs | 584 +- .../Shared/CodeTools/CSReservedWords.cs | 2 +- .../ScriptEngine/Shared/CodeTools/Compiler.cs | 230 +- .../Shared/CodeTools/ICodeConverter.cs | 3 + .../Shared/CodeTools/LSL2CSCodeTransformer.cs | 2 +- .../Shared/CodeTools/Properties/AssemblyInfo.cs | 10 +- .../Shared/CodeTools/Tests/CSCodeGeneratorTest.cs | 2 +- .../Shared/CodeTools/Tests/CompilerTest.cs | 13 +- .../Shared/CodeTools/Tests/LSL_EventTests.cs | 24 +- .../ScriptEngine/Shared/CodeTools/lsl.lexer.cs | 6 +- .../ScriptEngine/Shared/CodeTools/lsl.parser.cs | 1710 +++--- OpenSim/Region/ScriptEngine/Shared/Helpers.cs | 91 +- .../Shared/Instance/Properties/AssemblyInfo.cs | 10 +- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 205 +- .../Shared/Instance/ScriptSerializer.cs | 1 + .../Shared/Instance/Tests/CoopTerminationTests.cs | 76 +- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 172 +- .../ScriptEngine/Shared/Properties/AssemblyInfo.cs | 8 +- .../Shared/Tests/LSL_ApiAvatarTests.cs | 2 + .../ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs | 25 +- .../Shared/Tests/LSL_ApiInventoryTests.cs | 21 +- .../Shared/Tests/LSL_ApiLinkingTests.cs | 4 +- .../ScriptEngine/Shared/Tests/LSL_ApiListTests.cs | 4 +- .../Shared/Tests/LSL_ApiNotecardTests.cs | 8 +- .../Shared/Tests/LSL_ApiObjectTests.cs | 28 +- .../ScriptEngine/Shared/Tests/LSL_ApiTest.cs | 10 +- .../Shared/Tests/LSL_TypesTestLSLFloat.cs | 2 +- .../Shared/Tests/LSL_TypesTestLSLInteger.cs | 2 +- .../Shared/Tests/LSL_TypesTestLSLString.cs | 2 +- .../ScriptEngine/Shared/Tests/LSL_TypesTestList.cs | 2 + .../ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs | 4 +- .../XEngine/Api/Runtime/XEngineScriptBase.cs | 2 +- .../Region/ScriptEngine/XEngine/EventManager.cs | 29 +- .../XEngine/Properties/AssemblyInfo.cs | 10 +- .../XEngine/Tests/XEngineBasicTests.cs | 2 +- .../XEngine/Tests/XEngineCrossingTests.cs | 40 +- .../XEngine/Tests/XEnginePersistenceTests.cs | 2 + OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 236 +- OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs | 2 +- OpenSim/Server/Base/CommandManager.cs | 90 +- OpenSim/Server/Base/HttpServerBase.cs | 35 +- OpenSim/Server/Base/Properties/AssemblyInfo.cs | 10 +- OpenSim/Server/Base/ProtocolVersions.cs | 14 +- OpenSim/Server/Base/ServerUtils.cs | 179 +- OpenSim/Server/Base/ServicesServerBase.cs | 202 +- .../AgentPreferencesServerPostHandler.cs | 3 +- .../Server/Handlers/Asset/AssetServerConnector.cs | 14 +- .../Server/Handlers/Asset/AssetServerGetHandler.cs | 4 +- .../Asset/Tests/AssetServerPostHandlerTests.cs | 12 +- .../AuthenticationServerPostHandler.cs | 28 +- .../Authentication/OpenIdServerConnector.cs | 2 +- .../Handlers/Authentication/OpenIdServerHandler.cs | 11 +- .../AuthorizationServerPostHandler.cs | 2 +- .../Handlers/Avatar/AvatarServerPostHandler.cs | 12 +- OpenSim/Server/Handlers/BakedTextures/XBakes.cs | 4 +- .../Server/Handlers/BakedTextures/XBakesHandler.cs | 2 +- .../Handlers/BakedTextures/XBakesPostHandler.cs | 8 +- OpenSim/Server/Handlers/Base/ServerConnector.cs | 6 +- .../Handlers/Estate/EstateDataRobustConnector.cs | 7 +- .../Handlers/Friends/FriendsServerPostHandler.cs | 6 +- OpenSim/Server/Handlers/Grid/GridInfoHandlers.cs | 10 +- .../Server/Handlers/Grid/GridServerPostHandler.cs | 20 +- .../Handlers/GridUser/GridUserServerConnector.cs | 2 +- .../Handlers/GridUser/GridUserServerPostHandler.cs | 11 +- OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs | 4 +- .../Handlers/Hypergrid/HGFriendServerConnector.cs | 2 +- .../Hypergrid/HGFriendsServerPostHandler.cs | 18 +- .../Server/Handlers/Hypergrid/HomeAgentHandlers.cs | 2 +- .../Server/Handlers/Hypergrid/HypergridHandlers.cs | 7 +- .../Hypergrid/InstantMessageServerConnector.cs | 2 +- .../Handlers/Hypergrid/UserAgentServerConnector.cs | 5 +- .../Inventory/InventoryServerInConnector.cs | 24 +- .../Handlers/Inventory/XInventoryInConnector.cs | 22 +- OpenSim/Server/Handlers/Land/LandHandlers.cs | 3 +- .../Server/Handlers/Land/LandServiceInConnector.cs | 2 +- OpenSim/Server/Handlers/Login/LLLoginHandlers.cs | 19 +- .../Handlers/Login/LLLoginServiceInConnector.cs | 4 +- .../Server/Handlers/Map/MapAddServerConnector.cs | 29 +- .../Server/Handlers/Map/MapGetServerConnector.cs | 28 +- .../Handlers/Map/MapRemoveServerConnector.cs | 256 + .../Handlers/MuteList/MuteListServerConnector.cs | 63 + .../Handlers/MuteList/MuteListServerPostHandler.cs | 240 + .../Server/Handlers/Neighbour/NeighbourHandlers.cs | 2 +- .../Neighbour/NeighbourServiceInConnector.cs | 2 +- .../Handlers/Presence/PresenceServerPostHandler.cs | 4 +- .../Handlers/Profiles/UserProfilesConnector.cs | 6 +- .../Handlers/Profiles/UserProfilesHandlers.cs | 109 +- OpenSim/Server/Handlers/Properties/AssemblyInfo.cs | 10 +- .../Server/Handlers/Simulation/AgentHandlers.cs | 110 +- .../Server/Handlers/Simulation/ObjectHandlers.cs | 2 + .../UserAccounts/UserAccountServerPostHandler.cs | 66 +- OpenSim/Server/Properties/AssemblyInfo.cs | 8 +- OpenSim/Server/ServerMain.cs | 17 +- OpenSim/Services/AssetService/AssetService.cs | 11 +- .../AssetService/Properties/AssemblyInfo.cs | 10 +- OpenSim/Services/AssetService/XAssetService.cs | 10 +- .../AuthenticationServiceBase.cs | 15 +- .../PasswordAuthenticationService.cs | 94 +- .../Properties/AssemblyInfo.cs | 10 +- .../WebkeyAuthenticationService.cs | 15 +- .../WebkeyOrPasswordAuthenticationService.cs | 23 +- .../Properties/AssemblyInfo.cs | 10 +- OpenSim/Services/AvatarService/AvatarService.cs | 4 +- .../Services/AvatarService/AvatarServiceBase.cs | 2 +- .../AvatarService/Properties/AssemblyInfo.cs | 10 +- OpenSim/Services/Base/Properties/AssemblyInfo.cs | 10 +- OpenSim/Services/Base/ServiceBase.cs | 11 +- .../AgentPreferences/AgentPreferencesConnector.cs | 4 +- .../Connectors/Asset/AssetServicesConnector.cs | 458 +- .../AuthenticationServicesConnector.cs | 7 + .../AuthorizationServicesConnector.cs | 16 +- .../Connectors/Avatar/AvatarServicesConnector.cs | 4 +- .../Connectors/Estate/EstateDataConnector.cs | 8 +- .../Connectors/Friends/FriendsServicesConnector.cs | 2 +- .../Connectors/Friends/FriendsSimConnector.cs | 68 +- .../Connectors/Grid/GridServicesConnector.cs | 17 +- .../Hypergrid/GatekeeperServiceConnector.cs | 23 +- .../Hypergrid/HGFriendsServicesConnector.cs | 5 +- .../Connectors/Hypergrid/HeloServicesConnector.cs | 2 +- .../Hypergrid/UserAgentServiceConnector.cs | 30 +- .../Inventory/XInventoryServicesConnector.cs | 62 +- .../Connectors/Land/LandServicesConnector.cs | 29 +- .../MapImage/MapImageServicesConnector.cs | 66 +- .../MuteList/MuteListServicesConnector.cs | 183 + .../Neighbour/NeighbourServicesConnector.cs | 8 +- .../Presence/PresenceServicesConnector.cs | 15 +- .../Services/Connectors/Properties/AssemblyInfo.cs | 10 +- .../SimianGrid/SimianAssetServiceConnector.cs | 52 +- .../SimianAuthenticationServiceConnector.cs | 6 + .../SimianGrid/SimianAvatarServiceConnector.cs | 11 +- .../SimianGrid/SimianExternalCapsModule.cs | 16 +- .../Services/Connectors/SimianGrid/SimianGrid.cs | 18 +- .../SimianGrid/SimianGridMaptileModule.cs | 16 +- .../SimianGrid/SimianGridServiceConnector.cs | 21 +- .../SimianGrid/SimianInventoryServiceConnector.cs | 37 +- .../SimianGrid/SimianPresenceServiceConnector.cs | 10 +- .../Connectors/SimianGrid/SimianProfiles.cs | 14 +- .../SimianUserAccountServiceConnector.cs | 16 +- .../Simulation/SimulationServiceConnector.cs | 71 +- .../UserAccounts/UserAccountServicesConnector.cs | 99 +- .../Services/EstateService/EstateDataService.cs | 8 +- OpenSim/Services/FSAssetService/FSAssetService.cs | 199 +- .../FreeswitchService/FreeswitchService.cs | 58 +- .../FreeswitchService/Properties/AssemblyInfo.cs | 10 +- .../Services/Friends/Properties/AssemblyInfo.cs | 10 +- OpenSim/Services/GridService/GridService.cs | 294 +- OpenSim/Services/GridService/GridServiceBase.cs | 2 +- OpenSim/Services/GridService/HypergridLinker.cs | 189 +- .../GridService/Properties/AssemblyInfo.cs | 10 +- .../Services/HypergridService/GatekeeperService.cs | 151 +- .../Services/HypergridService/HGAssetService.cs | 2 +- .../Services/HypergridService/HGFSAssetService.cs | 2 +- .../Services/HypergridService/HGFriendsService.cs | 2 +- .../HypergridService/HGInstantMessageService.cs | 2 +- .../HypergridService/HGInventoryService.cs | 12 +- .../HypergridService/HGRemoteAssetService.cs | 240 + .../HypergridService/HGSuitcaseInventoryService.cs | 20 +- .../HypergridService/Properties/AssemblyInfo.cs | 10 +- .../Services/HypergridService/UserAccountCache.cs | 12 +- .../Services/HypergridService/UserAgentService.cs | 25 +- .../Interfaces/IAgentPreferencesService.cs | 4 +- OpenSim/Services/Interfaces/IAssetService.cs | 6 +- OpenSim/Services/Interfaces/IAttachmentsService.cs | 38 + .../Services/Interfaces/IAuthenticationService.cs | 3 +- .../Services/Interfaces/IAuthorizationService.cs | 24 +- OpenSim/Services/Interfaces/IAvatarService.cs | 15 +- OpenSim/Services/Interfaces/IEstateDataService.cs | 34 +- OpenSim/Services/Interfaces/IGridService.cs | 102 +- OpenSim/Services/Interfaces/IGridUserService.cs | 14 +- OpenSim/Services/Interfaces/IHypergridServices.cs | 8 +- OpenSim/Services/Interfaces/IInventoryService.cs | 10 +- OpenSim/Services/Interfaces/ILoginService.cs | 4 +- OpenSim/Services/Interfaces/IMapImageService.cs | 6 +- OpenSim/Services/Interfaces/IMuteLIstService.cs | 41 + OpenSim/Services/Interfaces/IOfflineIMService.cs | 4 +- OpenSim/Services/Interfaces/ISimulationService.cs | 21 +- OpenSim/Services/Interfaces/IUserAccountService.cs | 6 + OpenSim/Services/Interfaces/IUserManagement.cs | 3 +- .../Services/Interfaces/IUserProfilesService.cs | 8 +- OpenSim/Services/Interfaces/OpenProfileClient.cs | 4 +- .../Services/Interfaces/Properties/AssemblyInfo.cs | 10 +- .../InventoryService/Properties/AssemblyInfo.cs | 10 +- .../Tests/XInventoryServiceTests.cs | 54 +- .../Services/InventoryService/XInventoryService.cs | 62 +- OpenSim/Services/LLLoginService/LLLoginResponse.cs | 39 +- OpenSim/Services/LLLoginService/LLLoginService.cs | 211 +- .../LLLoginService/Properties/AssemblyInfo.cs | 10 +- .../Services/MapImageService/MapImageService.cs | 127 +- .../MapImageService/Properties/AssemblyInfo.cs | 10 +- .../Services/MuteListService/MuteListService.cs | 127 + .../Services/PresenceService/PresenceService.cs | 10 +- .../PresenceService/PresenceServiceBase.cs | 2 +- .../PresenceService/Properties/AssemblyInfo.cs | 10 +- .../SimulationService/SimulationDataService.cs | 15 + .../UserAccountService/AgentPreferencesService.cs | 4 +- .../Services/UserAccountService/GridUserService.cs | 4 +- .../UserAccountService/GridUserServiceBase.cs | 2 +- .../UserAccountService/Properties/AssemblyInfo.cs | 10 +- .../UserAccountService/UserAccountService.cs | 383 +- .../UserProfilesService/UserProfilesService.cs | 44 +- .../UserProfilesService/UserProfilesServiceBase.cs | 4 +- OpenSim/Tests/Clients/Grid/GridClient.cs | 205 + OpenSim/Tests/Common/DatabaseTestAttribute.cs | 6 +- OpenSim/Tests/Common/Helpers/AssetHelpers.cs | 32 +- .../Common/Helpers/BaseRequestHandlerHelpers.cs | 2 +- OpenSim/Tests/Common/Helpers/ClientStackHelpers.cs | 6 +- .../Tests/Common/Helpers/EntityTransferHelpers.cs | 12 +- OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 74 +- .../Tests/Common/Helpers/TaskInventoryHelpers.cs | 12 +- OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs | 4 +- .../Tests/Common/Helpers/UserInventoryHelpers.cs | 20 +- OpenSim/Tests/Common/LongRunningAttribute.cs | 4 +- OpenSim/Tests/Common/Mock/BaseAssetRepository.cs | 8 +- OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs | 3 +- .../Common/Mock/MockGroupsServicesConnector.cs | 28 +- OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs | 58 +- OpenSim/Tests/Common/Mock/MockScriptEngine.cs | 10 +- OpenSim/Tests/Common/Mock/TestClient.cs | 128 +- .../Tests/Common/Mock/TestEventQueueGetModule.cs | 27 +- OpenSim/Tests/Common/Mock/TestGroupsDataPlugin.cs | 339 ++ OpenSim/Tests/Common/Mock/TestHttpClientContext.cs | 16 +- OpenSim/Tests/Common/Mock/TestHttpRequest.cs | 82 +- OpenSim/Tests/Common/Mock/TestHttpResponse.cs | 38 +- .../Tests/Common/Mock/TestInventoryDataPlugin.cs | 40 +- OpenSim/Tests/Common/Mock/TestLLUDPServer.cs | 30 +- OpenSim/Tests/Common/Mock/TestLandChannel.cs | 9 +- OpenSim/Tests/Common/Mock/TestScene.cs | 6 +- .../Tests/Common/Mock/TestXInventoryDataPlugin.cs | 10 +- OpenSim/Tests/Common/TestHelpers.cs | 8 +- OpenSim/Tests/Performance/NPCPerformanceTests.cs | 4 +- OpenSim/Tests/Permissions/Common.cs | 374 ++ OpenSim/Tests/Permissions/DirectTransferTests.cs | 153 + OpenSim/Tests/Permissions/IndirectTransferTests.cs | 132 + OpenSim/Tests/Robust/Clients/Grid/GridClient.cs | 4 +- .../Robust/Clients/Inventory/InventoryClient.cs | 7 +- OpenSim/Tests/Robust/Server/DemonServer.cs | 4 +- .../Tests/Stress/VectorRenderModuleStressTests.cs | 7 +- OpenSim/Tools/Compiler/Program.cs | 4 +- OpenSim/Tools/Compiler/Properties/AssemblyInfo.cs | 10 +- OpenSim/Tools/Configger/ConfigurationLoader.cs | 36 +- OpenSim/Tools/Configger/Properties/AssemblyInfo.cs | 10 +- OpenSim/Tools/Configger/Util.cs | 8 +- .../Tools/pCampBot/Behaviours/AbstractBehaviour.cs | 4 +- .../Tools/pCampBot/Behaviours/CrossBehaviour.cs | 6 +- .../Tools/pCampBot/Behaviours/GrabbingBehaviour.cs | 6 +- .../Behaviours/InventoryDownloadBehaviour.cs | 6 +- OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs | 8 +- .../Tools/pCampBot/Behaviours/PhysicsBehaviour2.cs | 6 +- .../Tools/pCampBot/Behaviours/TeleportBehaviour.cs | 4 +- .../Tools/pCampBot/Behaviours/TwitchyBehaviour.cs | 8 +- OpenSim/Tools/pCampBot/Bot.cs | 24 +- OpenSim/Tools/pCampBot/BotManager.cs | 34 +- OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs | 2 +- OpenSim/Tools/pCampBot/Properties/AssemblyInfo.cs | 10 +- OpenSim/Tools/pCampBot/pCampBot.cs | 6 +- 1194 files changed, 95094 insertions(+), 45660 deletions(-) create mode 100644 OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2ServerConnector.cs create mode 100644 OpenSim/Capabilities/Handlers/GetTexture/GetTextureRobustHandler.cs create mode 100644 OpenSim/Data/IMuteListData.cs create mode 100644 OpenSim/Data/MySQL/MySQLMuteListData.cs create mode 100644 OpenSim/Data/MySQL/Resources/MuteListStore.migrations delete mode 100644 OpenSim/Data/MySQL/Resources/UserStore.migrations create mode 100644 OpenSim/Data/MySQL/Resources/XMute.migrations mode change 100644 => 100755 OpenSim/Data/Null/NullEstateData.cs create mode 100644 OpenSim/Data/PGSQL/PGSQLFSAssetData.cs mode change 100644 => 100755 OpenSim/Data/PGSQL/PGSQLGroupsData.cs mode change 100644 => 100755 OpenSim/Data/PGSQL/PGSQLPresenceData.cs mode change 100644 => 100755 OpenSim/Data/PGSQL/PGSQLSimulationData.cs create mode 100644 OpenSim/Data/PGSQL/Resources/AgentPrefs.migrations create mode 100644 OpenSim/Data/PGSQL/Resources/FSAssetStore.migrations mode change 100644 => 100755 OpenSim/Data/PGSQL/Resources/Presence.migrations delete mode 100644 OpenSim/Data/SQLite/Resources/InventoryStore.migrations delete mode 100644 OpenSim/Data/SQLite/Resources/UserStore.migrations delete mode 100644 OpenSim/Data/SQLite/SQLiteInventoryStore.cs create mode 100644 OpenSim/Framework/AnimationSet.cs create mode 100644 OpenSim/Framework/ConfigurationMember.cs mode change 100644 => 100755 OpenSim/Framework/Console/ConsoleBase.cs mode change 100644 => 100755 OpenSim/Framework/Console/ConsolePluginCommand.cs create mode 100644 OpenSim/Framework/Crc32.cs create mode 100644 OpenSim/Framework/CustomTypes.cs create mode 100644 OpenSim/Framework/EntityTransferContext.cs create mode 100644 OpenSim/Framework/IAssetCache.cs delete mode 100644 OpenSim/Framework/IImprovedAssetCache.cs mode change 100644 => 100755 OpenSim/Framework/LogWriter.cs mode change 100644 => 100755 OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs mode change 100644 => 100755 OpenSim/Framework/Monitoring/Stats/CounterStat.cs mode change 100644 => 100755 OpenSim/Framework/Monitoring/Stats/EventHistogram.cs create mode 100644 OpenSim/Framework/MuteData.cs create mode 100644 OpenSim/Framework/ObjectChangeData.cs create mode 100644 OpenSim/Framework/PhysicsInertia.cs create mode 100644 OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs delete mode 100644 OpenSim/Region/ClientStack/Linden/Caps/GetDisplayNamesModule.cs delete mode 100644 OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs create mode 100644 OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModuleTst.cs create mode 100644 OpenSim/Region/CoreModules/Avatar/InstantMessage/XMuteModule.cs delete mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs create mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsOut/MuteList/LocalMuteListServiceConnector.cs create mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsOut/MuteList/RemoteMuteListServiceConnector.cs delete mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs create mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/NeighbourServiceOutConnector.cs delete mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/RemoteNeighourServiceConnector.cs mode change 100644 => 100755 OpenSim/Region/CoreModules/World/Archiver/Tests/Resources/test-sound.wav create mode 100644 OpenSim/Region/CoreModules/World/Estate/EstateConnector.cs create mode 100644 OpenSim/Region/CoreModules/World/Estate/EstateModule.cs create mode 100644 OpenSim/Region/CoreModules/World/Estate/EstateRequestHandler.cs delete mode 100644 OpenSim/Region/CoreModules/World/Estate/XEstateConnector.cs delete mode 100644 OpenSim/Region/CoreModules/World/Estate/XEstateModule.cs delete mode 100644 OpenSim/Region/CoreModules/World/Estate/XEstateRequestHandler.cs create mode 100644 OpenSim/Region/Framework/Interfaces/IEtcdModule.cs delete mode 100644 OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs create mode 100644 OpenSim/Region/Framework/Interfaces/ISnmpModule.cs create mode 100644 OpenSim/Region/Framework/Interfaces/IUserAccountCacheModule.cs create mode 100644 OpenSim/Region/Framework/Scenes/Animation/MovementAnimationOverrides.cs delete mode 100644 OpenSim/Region/Framework/Scenes/Border.cs create mode 100644 OpenSim/Region/Framework/Scenes/CollisionSounds.cs create mode 100644 OpenSim/Region/Framework/Scenes/GodController.cs create mode 100644 OpenSim/Region/Framework/Scenes/SOPMaterial.cs create mode 100644 OpenSim/Region/Framework/Scenes/SOPVehicle.cs mode change 100644 => 100755 OpenSim/Region/Framework/Scenes/Scene.cs mode change 100644 => 100755 OpenSim/Region/Framework/Scenes/SceneGraph.cs mode change 100644 => 100755 OpenSim/Region/Framework/Scenes/SimStatsReporter.cs delete mode 100644 OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs create mode 100644 OpenSim/Region/OptionalModules/Framework/Monitoring/EtcdMonitoringModule.cs mode change 100644 => 100755 OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs delete mode 100644 OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerClientEventForwarder.cs delete mode 100644 OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs delete mode 100644 OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerLargeLandChannel.cs delete mode 100644 OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerModule.cs delete mode 100644 OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerPermissionModule.cs delete mode 100644 OpenSim/Region/OptionalModules/RegionCombinerModule/RegionConnections.cs delete mode 100644 OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCourseLocation.cs delete mode 100644 OpenSim/Region/OptionalModules/RegionCombinerModule/RegionData.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSActorHover.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSActorMoveToTarget.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSActorSetForce.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSActorSetTorque.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSActors.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSConstraint.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSConstraint6Dof.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSConstraintCollection.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSConstraintConeTwist.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSConstraintHinge.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSConstraintSlider.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSConstraintSpring.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSLinksetConstraints.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSMaterials.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSParam.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSShapes.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSTerrainManager.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSTerrainMesh.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BulletSimTODO.txt mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/Tests/BasicVehicles.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTests.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTestsUtil.cs create mode 100755 OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs create mode 100644 OpenSim/Region/PhysicsModules/Ode/ODEApi.cs create mode 100644 OpenSim/Region/PhysicsModules/Ode/ODEModule.cs delete mode 100644 OpenSim/Region/PhysicsModules/Ode/drawstuff.cs mode change 100644 => 100755 OpenSim/Region/PhysicsModules/SharedBase/IPhysicsParameters.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOde/ODEDynamics.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOde/ODESitAvatar.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOde/Properties/AssemblyInfo.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOdeMeshing/HelperTypes.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOdeMeshing/Mesh.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOdeMeshing/Properties/AssemblyInfo.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOdeMeshing/SculptMap.cs create mode 100644 OpenSim/Region/PhysicsModules/ubOdeMeshing/SculptMesh.cs create mode 100644 OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs create mode 100644 OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs create mode 100644 OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs delete mode 100644 OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp mode change 100644 => 100755 OpenSim/Region/ScriptEngine/XEngine/XEngine.cs create mode 100644 OpenSim/Server/Handlers/Map/MapRemoveServerConnector.cs create mode 100644 OpenSim/Server/Handlers/MuteList/MuteListServerConnector.cs create mode 100644 OpenSim/Server/Handlers/MuteList/MuteListServerPostHandler.cs create mode 100644 OpenSim/Services/Connectors/MuteList/MuteListServicesConnector.cs create mode 100644 OpenSim/Services/HypergridService/HGRemoteAssetService.cs create mode 100644 OpenSim/Services/Interfaces/IAttachmentsService.cs create mode 100644 OpenSim/Services/Interfaces/IMuteLIstService.cs create mode 100644 OpenSim/Services/MuteListService/MuteListService.cs create mode 100644 OpenSim/Tests/Clients/Grid/GridClient.cs create mode 100644 OpenSim/Tests/Common/Mock/TestGroupsDataPlugin.cs create mode 100644 OpenSim/Tests/Permissions/Common.cs create mode 100644 OpenSim/Tests/Permissions/DirectTransferTests.cs create mode 100644 OpenSim/Tests/Permissions/IndirectTransferTests.cs (limited to 'OpenSim') diff --git a/OpenSim/Addons/Groups/GroupsExtendedData.cs b/OpenSim/Addons/Groups/GroupsExtendedData.cs index c783b9e..d92c442 100644 --- a/OpenSim/Addons/Groups/GroupsExtendedData.cs +++ b/OpenSim/Addons/Groups/GroupsExtendedData.cs @@ -46,7 +46,7 @@ namespace OpenSim.Groups public string AccessToken; } - public class ExtendedGroupMembersData + public class ExtendedGroupMembersData { // This is the only difference: this is a string public string AgentID; @@ -65,7 +65,7 @@ namespace OpenSim.Groups public UUID RoleID; // This is the only difference: this is a string public string MemberID; - + } public struct ExtendedGroupNoticeData diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs index e95db41..f4d3490 100644 --- a/OpenSim/Addons/Groups/GroupsMessagingModule.cs +++ b/OpenSim/Addons/Groups/GroupsMessagingModule.cs @@ -131,7 +131,7 @@ namespace OpenSim.Groups { if (!m_groupMessagingEnabled) return; - + scene.RegisterModuleInterface(this); m_sceneList.Add(scene); @@ -163,7 +163,7 @@ namespace OpenSim.Groups if (m_groupData == null) { m_log.Error("[Groups.Messaging]: Could not get IGroupsServicesConnector, GroupsMessagingModule is now disabled."); - RemoveRegion(scene); + RemoveRegion(scene); return; } @@ -218,7 +218,7 @@ namespace OpenSim.Groups m_msgTransferModule = null; } - public Type ReplaceableInterface + public Type ReplaceableInterface { get { return null; } } @@ -262,7 +262,7 @@ namespace OpenSim.Groups { if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - + GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID.ToString(), groupID, null); if (groupInfo != null) @@ -279,7 +279,7 @@ namespace OpenSim.Groups { SendMessageToGroup(im, groupID, UUID.Zero, null); } - + public void SendMessageToGroup( GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func sendCondition) { @@ -355,9 +355,9 @@ namespace OpenSim.Groups { if (!sendCondition(member)) { - if (m_debugEnabled) + if (m_debugEnabled) m_log.DebugFormat( - "[Groups.Messaging]: Not sending to {0} as they do not fulfill send condition", + "[Groups.Messaging]: Not sending to {0} as they do not fulfill send condition", member.AgentID); continue; @@ -366,7 +366,7 @@ namespace OpenSim.Groups else if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID)) { // Don't deliver messages to people who have dropped this session - if (m_debugEnabled) + if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID); continue; @@ -414,7 +414,7 @@ namespace OpenSim.Groups "[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms", groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick); } - + #region SimGridEventHandlers void OnClientLogin(IClientAPI client) @@ -445,13 +445,13 @@ namespace OpenSim.Groups // The instant message module will only deliver messages of dialog types: // MessageFromAgent, StartTyping, StopTyping, MessageFromObject // - // Any other message type will not be delivered to a client by the + // Any other message type will not be delivered to a client by the // Instant Message Module UUID regionID = new UUID(msg.RegionID); if (m_debugEnabled) { - m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}", + m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, regionID); DebugGridInstantMessage(msg); @@ -508,7 +508,7 @@ namespace OpenSim.Groups m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he has an agent in region of origin", sp.UUID); return; } - else + else { if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: not skipping agent {0}", sp.UUID); @@ -531,7 +531,7 @@ namespace OpenSim.Groups } } }); - + } } } @@ -555,7 +555,7 @@ namespace OpenSim.Groups break; case (byte)InstantMessageDialog.SessionSend: - // User hasn't dropped, so they're in the session, + // User hasn't dropped, so they're in the session, // maybe we should deliver it. IClientAPI client = GetActiveClient(new UUID(msg.toAgentID)); if (client != null) @@ -627,6 +627,7 @@ namespace OpenSim.Groups , false //canVoiceChat , false //isModerator , false //text mute + , true // Enter ); } } @@ -654,7 +655,7 @@ namespace OpenSim.Groups UUID AgentID = new UUID(im.fromAgentID); GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null); - + if (groupInfo != null) { AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); @@ -669,6 +670,7 @@ namespace OpenSim.Groups , false //canVoiceChat , false //isModerator , false //text mute + , true ); } } @@ -679,7 +681,7 @@ namespace OpenSim.Groups UUID GroupID = new UUID(im.imSessionID); UUID AgentID = new UUID(im.fromAgentID); - if (m_debugEnabled) + if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); //If this agent is sending a message, then they want to be in the session diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs index d121d1a..5b76e0a 100644 --- a/OpenSim/Addons/Groups/GroupsModule.cs +++ b/OpenSim/Addons/Groups/GroupsModule.cs @@ -51,7 +51,7 @@ namespace OpenSim.Groups private List m_sceneList = new List(); private IMessageTransferModule m_msgTransferModule = null; - + private IGroupsServicesConnector m_groupData = null; private IUserManagement m_UserManagement; @@ -137,13 +137,6 @@ namespace OpenSim.Groups if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnMakeRootAgent += OnMakeRoot; - scene.EventManager.OnMakeChildAgent += OnMakeChild; - scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - // The InstantMessageModule itself doesn't do this, - // so lets see if things explode if we don't do it - // scene.EventManager.OnClientClosed += OnClientClosed; if (m_groupData == null) { @@ -182,6 +175,11 @@ namespace OpenSim.Groups m_sceneList.Add(scene); } + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnMakeRootAgent += OnMakeRoot; + scene.EventManager.OnMakeChildAgent += OnMakeChild; + scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; + scene.EventManager.OnClientClosed += OnClientClosed; } @@ -196,6 +194,7 @@ namespace OpenSim.Groups scene.EventManager.OnMakeRootAgent -= OnMakeRoot; scene.EventManager.OnMakeChildAgent -= OnMakeChild; scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; + scene.EventManager.OnClientClosed -= OnClientClosed; lock (m_sceneList) { @@ -211,7 +210,7 @@ namespace OpenSim.Groups if (m_debugEnabled) m_log.Debug("[Groups]: Shutting down Groups module."); } - public Type ReplaceableInterface + public Type ReplaceableInterface { get { return null; } } @@ -237,6 +236,7 @@ namespace OpenSim.Groups client.OnRequestAvatarProperties += OnRequestAvatarProperties; } + private void OnMakeRoot(ScenePresence sp) { if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -245,8 +245,12 @@ namespace OpenSim.Groups // Used for Notices and Group Invites/Accept/Reject sp.ControllingClient.OnInstantMessage += OnInstantMessage; - // Send client their groups information. - SendAgentGroupDataUpdate(sp.ControllingClient, sp.UUID); + // Send out group data update for compatibility. + // There might be some problem with the thread we're generating this on but not + // doing the update at this time causes problems (Mantis #7920 and #7915) + // TODO: move sending this update to a later time in the rootification of the client. + if(!sp.haveGroupInformation) + SendAgentGroupDataUpdate(sp.ControllingClient, false); } private void OnMakeChild(ScenePresence sp) @@ -262,23 +266,28 @@ namespace OpenSim.Groups { if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetRequestingAgentID(remoteClient), avatarID).ToArray(); GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID); remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); } - /* - * This becomes very problematic in a shared module. In a shared module you may have more then one - * reference to IClientAPI's, one for 0 or 1 root connections, and 0 or more child connections. - * The OnClientClosed event does not provide anything to indicate which one of those should be closed - * nor does it provide what scene it was from so that the specific reference can be looked up. - * The InstantMessageModule.cs does not currently worry about unregistering the handles, - * and it should be an issue, since it's the client that references us not the other way around - * , so as long as we don't keep a reference to the client laying around, the client can still be GC'ed - private void OnClientClosed(UUID AgentId) + private void OnClientClosed(UUID AgentId, Scene scene) { - if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (scene == null) + return; + + ScenePresence sp = scene.GetScenePresence(AgentId); + IClientAPI client = sp.ControllingClient; + if (client != null) + { + client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest; + client.OnRequestAvatarProperties -= OnRequestAvatarProperties; + // make child possible not called? + client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest; + client.OnInstantMessage -= OnInstantMessage; + } + /* lock (m_ActiveClients) { if (m_ActiveClients.ContainsKey(AgentId)) @@ -296,31 +305,22 @@ namespace OpenSim.Groups if (m_debugEnabled) m_log.WarnFormat("[Groups]: Client closed that wasn't registered here."); } - - } } */ + } + private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) { - if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - UUID activeGroupID = UUID.Zero; - string activeGroupTitle = string.Empty; - string activeGroupName = string.Empty; - ulong activeGroupPowers = (ulong)GroupPowers.None; - - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetRequestingAgentIDStr(remoteClient), dataForAgentID.ToString()); - if (membership != null) - { - activeGroupID = membership.GroupID; - activeGroupTitle = membership.GroupTitle; - activeGroupPowers = membership.GroupPowers; - } + // this a private message for own agent only + if (dataForAgentID != GetRequestingAgentID(remoteClient)) + return; - SendAgentDataUpdate(remoteClient, dataForAgentID, activeGroupID, activeGroupName, activeGroupPowers, activeGroupTitle); + SendAgentGroupDataUpdate(remoteClient, false); - SendScenePresenceUpdate(dataForAgentID, activeGroupTitle); + // also current viewers do ignore it and ask later on a much nicer thread + // its a info request not a change, so nothing is sent to others + // they do get the group title with the avatar object update on arrivel to a region } private void HandleUUIDGroupNameRequest(UUID GroupID, IClientAPI remoteClient) @@ -394,12 +394,14 @@ namespace OpenSim.Groups msg.binaryBucket = new byte[0]; OutgoingInstantMessage(msg, invitee); - - UpdateAllClientsWithGroupInfo(invitee); + IClientAPI inviteeClient = GetActiveRootClient(invitee); + if(inviteeClient !=null) + { + SendAgentGroupDataUpdate(inviteeClient,true); + } } m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID); - } // Reject @@ -444,17 +446,16 @@ namespace OpenSim.Groups UUID itemID = binBucketMap["item_id"].AsUUID(); UUID ownerID = binBucketMap["owner_id"].AsUUID(); - item = new InventoryItemBase(itemID, ownerID); - item = m_sceneList[0].InventoryService.GetItem(item); + item = m_sceneList[0].InventoryService.GetItem(ownerID, itemID); } else m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType()); } if (m_groupData.AddGroupNotice(GetRequestingAgentIDStr(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, - hasAttachment, + hasAttachment, (byte)(item == null ? 0 : item.AssetType), - item == null ? null : item.Name, + item == null ? null : item.Name, item == null ? UUID.Zero : item.ID, item == null ? UUID.Zero.ToString() : item.Owner.ToString())) { @@ -463,7 +464,6 @@ namespace OpenSim.Groups OnNewGroupNotice(GroupID, NoticeID); } - // Send notice out to everyone that wants notices foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), GroupID)) { @@ -497,7 +497,7 @@ namespace OpenSim.Groups m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId); string message; - InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId, + InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId, giver, notice.noticeData.AttachmentItemID, out message); if (itemCopy == null) @@ -508,12 +508,11 @@ namespace OpenSim.Groups remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0); } - } - + // Interop, received special 210 code for ejecting a group member // this only works within the comms servers domain, and won't work hypergrid - // TODO:FIXME: Use a presense server of some kind to find out where the + // TODO:FIXME: Use a presense server of some kind to find out where the // client actually is, and try contacting that region directly to notify them, // or provide the notification via xmlrpc update queue if ((im.dialog == 210)) @@ -524,14 +523,16 @@ namespace OpenSim.Groups UUID ejecteeID = new UUID(im.toAgentID); + im.imSessionID = UUID.Zero.Guid; im.dialog = (byte)InstantMessageDialog.MessageFromAgent; OutgoingInstantMessage(im, ejecteeID); - IClientAPI ejectee = GetActiveClient(ejecteeID); + IClientAPI ejectee = GetActiveRootClient(ejecteeID); if (ejectee != null) { UUID groupID = new UUID(im.imSessionID); ejectee.SendAgentDropGroup(groupID); + SendAgentGroupDataUpdate(ejectee,true); } } } @@ -551,7 +552,7 @@ namespace OpenSim.Groups case (byte)InstantMessageDialog.GroupInvitation: case (byte)InstantMessageDialog.GroupNotice: UUID toAgentID = new UUID(msg.toAgentID); - IClientAPI localClient = GetActiveClient(toAgentID); + IClientAPI localClient = GetActiveRootClient(toAgentID); if (localClient != null) { localClient.SendInstantMessage(msg); @@ -576,7 +577,7 @@ namespace OpenSim.Groups { return m_groupData.GetGroupRecord(UUID.Zero.ToString(), UUID.Zero, name); } - + public void ActivateGroup(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -584,10 +585,10 @@ namespace OpenSim.Groups m_groupData.SetAgentActiveGroup(GetRequestingAgentIDStr(remoteClient), GetRequestingAgentIDStr(remoteClient), groupID); // Changing active group changes title, active powers, all kinds of things - // anyone who is in any region that can see this client, should probably be + // anyone who is in any region that can see this client, should probably be // updated with new group info. At a minimum, they should get ScenePresence // updated with new title. - UpdateAllClientsWithGroupInfo(remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, true); } /// @@ -619,10 +620,10 @@ namespace OpenSim.Groups public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) + if (m_debugEnabled) m_log.DebugFormat( "[Groups]: GroupMembersRequest called for {0} from client {1}", groupID, remoteClient.Name); - + List data = m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), groupID); if (m_debugEnabled) @@ -634,7 +635,6 @@ namespace OpenSim.Groups } return data; - } public List GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID) @@ -706,7 +706,7 @@ namespace OpenSim.Groups public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) { - if (m_debugEnabled) + if (m_debugEnabled) m_log.DebugFormat( "[Groups]: {0} called with groupID={1}, agentID={2}", System.Reflection.MethodBase.GetCurrentMethod().Name, groupID, agentID); @@ -714,6 +714,12 @@ namespace OpenSim.Groups return m_groupData.GetAgentGroupMembership(UUID.Zero.ToString(), agentID.ToString(), groupID); } + public GroupMembershipData GetActiveMembershipData(UUID agentID) + { + string agentIDstr = agentID.ToString(); + return m_groupData.GetAgentActiveMembership(agentIDstr, agentIDstr); + } + public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -750,7 +756,7 @@ namespace OpenSim.Groups if (avatar != null) { - if (avatar.UserLevel < m_levelGroupCreate) + if (avatar.GodController.UserLevel < m_levelGroupCreate) { remoteClient.SendCreateGroupReply(UUID.Zero, false, String.Format("Insufficient permissions to create a group. Requires level {0}", m_levelGroupCreate)); return UUID.Zero; @@ -758,7 +764,7 @@ namespace OpenSim.Groups } // check funds - // is there is a money module present ? + // is there a money module present ? IMoneyModule money = scene.RequestModuleInterface(); if (money != null) { @@ -770,18 +776,18 @@ namespace OpenSim.Groups } string reason = string.Empty; - UUID groupID = m_groupData.CreateGroup(remoteClient.AgentId, name, charter, showInList, insigniaID, membershipFee, openEnrollment, + UUID groupID = m_groupData.CreateGroup(remoteClient.AgentId, name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId, out reason); if (groupID != UUID.Zero) { - if (money != null) - money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, MoneyTransactionType.GroupCreate); + if (money != null && money.GroupCreationCharge > 0) + money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, MoneyTransactionType.GroupCreate, name); - remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); + remoteClient.SendCreateGroupReply(groupID, true, "Group created successfully"); // Update the founder with new group information. - SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); + SendAgentGroupDataUpdate(remoteClient, true); } else remoteClient.SendCreateGroupReply(groupID, false, reason); @@ -817,7 +823,7 @@ namespace OpenSim.Groups if (membership != null) { return membership.GroupTitle; - } + } return string.Empty; } @@ -833,8 +839,8 @@ namespace OpenSim.Groups // TODO: Not sure what all is needed here, but if the active group role change is for the group // the client currently has set active, then we need to do a scene presence update too // if (m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient)).GroupID == GroupID) - - UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient)); + + SendDataUpdate(remoteClient, true); } @@ -875,7 +881,7 @@ namespace OpenSim.Groups } // TODO: This update really should send out updates for everyone in the role that just got changed. - SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); + SendDataUpdate(remoteClient, true); } public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) @@ -893,7 +899,7 @@ namespace OpenSim.Groups case 1: // Remove m_groupData.RemoveAgentFromGroupRole(GetRequestingAgentIDStr(remoteClient), memberID.ToString(), groupID, roleID); - + break; default: m_log.ErrorFormat("[Groups]: {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes); @@ -901,7 +907,7 @@ namespace OpenSim.Groups } // TODO: This update really should send out updates for everyone in the role that just got changed. - SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); + SendDataUpdate(remoteClient, true); } public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) @@ -969,27 +975,37 @@ namespace OpenSim.Groups return msg; } - public void SendAgentGroupDataUpdate(IClientAPI remoteClient) + public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // Send agent information about his groups - SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); - } + GroupRecord groupRecord = GetGroupRecord(groupID); + IMoneyModule money = remoteClient.Scene.RequestModuleInterface(); - public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + // Should check to see if there's an outstanding invitation + + if (money != null && groupRecord.MembershipFee > 0) + { + // Does the agent have the funds to cover the group join fee? + if (!money.AmountCovered(remoteClient.AgentId, groupRecord.MembershipFee)) + { + remoteClient.SendAlertMessage("Insufficient funds to join the group."); + remoteClient.SendJoinGroupReply(groupID, false); + return; + } + } string reason = string.Empty; - // Should check to see if OpenEnrollment, or if there's an outstanding invitation + if (m_groupData.AddAgentToGroup(GetRequestingAgentIDStr(remoteClient), GetRequestingAgentIDStr(remoteClient), groupID, UUID.Zero, string.Empty, out reason)) { + if (money != null && groupRecord.MembershipFee > 0) + money.ApplyCharge(remoteClient.AgentId, groupRecord.MembershipFee, MoneyTransactionType.GroupJoin, groupRecord.GroupName); remoteClient.SendJoinGroupReply(groupID, true); // Should this send updates to everyone in the group? - SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); + SendAgentGroupDataUpdate(remoteClient, true); if (reason != string.Empty) // A warning @@ -1011,7 +1027,7 @@ namespace OpenSim.Groups // SL sends out notifcations to the group messaging session that the person has left // Should this also update everyone who is in the group? - SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); + SendAgentGroupDataUpdate(remoteClient, true); } public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) @@ -1070,10 +1086,31 @@ namespace OpenSim.Groups return; } + IClientAPI ejecteeClient = GetActiveRootClient(ejecteeID); + // Send Message to Ejectee GridInstantMessage msg = new GridInstantMessage(); - - msg.imSessionID = UUID.Zero.Guid; + + // if local send a normal message + if(ejecteeClient != null) + { + msg.imSessionID = UUID.Zero.Guid; + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; + // also execute and send update + ejecteeClient.SendAgentDropGroup(groupID); + SendAgentGroupDataUpdate(ejecteeClient,true); + } + else // send + { + // Interop, received special 210 code for ejecting a group member + // this only works within the comms servers domain, and won't work hypergrid + // TODO:FIXME: Use a presence server of some kind to find out where the + // client actually is, and try contacting that region directly to notify them, + // or provide the notification via xmlrpc update queue + + msg.imSessionID = groupInfo.GroupID.Guid; + msg.dialog = (byte)210; //interop + } msg.fromAgentID = agentID.Guid; // msg.fromAgentID = info.GroupID; msg.toAgentID = ejecteeID.Guid; @@ -1081,7 +1118,7 @@ namespace OpenSim.Groups msg.timestamp = 0; msg.fromAgentName = agentName; msg.message = string.Format("You have been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName); - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; + msg.fromGroup = false; msg.offline = (byte)0; msg.ParentEstateID = 0; @@ -1091,11 +1128,7 @@ namespace OpenSim.Groups OutgoingInstantMessage(msg, ejecteeID); // Message to ejector - // Interop, received special 210 code for ejecting a group member - // this only works within the comms servers domain, and won't work hypergrid - // TODO:FIXME: Use a presense server of some kind to find out where the - // client actually is, and try contacting that region directly to notify them, - // or provide the notification via xmlrpc update queue + msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; @@ -1111,7 +1144,7 @@ namespace OpenSim.Groups { msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName, "Unknown member"); } - msg.dialog = (byte)210; //interop + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; msg.fromGroup = false; msg.offline = (byte)0; msg.ParentEstateID = 0; @@ -1119,11 +1152,6 @@ namespace OpenSim.Groups msg.RegionID = regionInfo.RegionID.Guid; msg.binaryBucket = new byte[0]; OutgoingInstantMessage(msg, agentID); - - - // SL sends out messages to everyone in the group - // Who all should receive updates and what should they be updated with? - UpdateAllClientsWithGroupInfo(ejecteeID); } public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID) @@ -1186,6 +1214,18 @@ namespace OpenSim.Groups #endregion #region Client/Update Tools + private IClientAPI GetActiveRootClient(UUID agentID) + { + foreach (Scene scene in m_sceneList) + { + ScenePresence sp = scene.GetScenePresence(agentID); + if (sp != null && !sp.IsChildAgent && !sp.IsDeleted) + { + return sp.ControllingClient; + } + } + return null; + } /// /// Try to find an active IClientAPI reference for agentID giving preference to root connections @@ -1198,7 +1238,7 @@ namespace OpenSim.Groups foreach (Scene scene in m_sceneList) { ScenePresence sp = scene.GetScenePresence(agentID); - if (sp != null) + if (sp != null&& !sp.IsDeleted) { if (!sp.IsChildAgent) { @@ -1215,71 +1255,6 @@ namespace OpenSim.Groups return child; } - /// - /// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'. - /// - private void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, UUID dataForAgentID, GroupMembershipData[] data) - { - if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // NPCs currently don't have a CAPs structure or event queues. There is a strong argument for conveying this information - // to them anyway since it makes writing server-side bots a lot easier, but for now we don't do anything. - if (remoteClient.SceneAgent.PresenceType == PresenceType.Npc) - return; - - OSDArray AgentData = new OSDArray(1); - OSDMap AgentDataMap = new OSDMap(1); - AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID)); - AgentData.Add(AgentDataMap); - - OSDArray GroupData = new OSDArray(data.Length); - OSDArray NewGroupData = new OSDArray(data.Length); - - foreach (GroupMembershipData membership in data) - { - if (GetRequestingAgentID(remoteClient) != dataForAgentID) - { - if (!membership.ListInProfile) - { - // If we're sending group info to remoteclient about another agent, - // filter out groups the other agent doesn't want to share. - continue; - } - } - - OSDMap GroupDataMap = new OSDMap(6); - OSDMap NewGroupDataMap = new OSDMap(1); - - GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID)); - GroupDataMap.Add("GroupPowers", OSD.FromULong(membership.GroupPowers)); - GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices)); - GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture)); - GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution)); - GroupDataMap.Add("GroupName", OSD.FromString(membership.GroupName)); - NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile)); - - GroupData.Add(GroupDataMap); - NewGroupData.Add(NewGroupDataMap); - } - - OSDMap llDataStruct = new OSDMap(3); - llDataStruct.Add("AgentData", AgentData); - llDataStruct.Add("GroupData", GroupData); - llDataStruct.Add("NewGroupData", NewGroupData); - - if (m_debugEnabled) - { - m_log.InfoFormat("[Groups]: {0}", OSDParser.SerializeJsonString(llDataStruct)); - } - - IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); - - if (queue != null) - { - queue.Enqueue(queue.BuildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient)); - } - } - private void SendScenePresenceUpdate(UUID AgentID, string Title) { if (m_debugEnabled) m_log.DebugFormat("[Groups]: Updating scene title for {0} with title: {1}", AgentID, Title); @@ -1296,53 +1271,39 @@ namespace OpenSim.Groups presence.Grouptitle = Title; if (! presence.IsChildAgent) - presence.SendAvatarDataToAllClients(); + presence.SendAvatarDataToAllAgents(); } } } } - /// - /// Send updates to all clients who might be interested in groups data for dataForClientID - /// - private void UpdateAllClientsWithGroupInfo(UUID dataForClientID) + public void SendAgentGroupDataUpdate(IClientAPI remoteClient) { - if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // TODO: Probably isn't nessesary to update every client in every scene. - // Need to examine client updates and do only what's nessesary. - lock (m_sceneList) - { - foreach (Scene scene in m_sceneList) - { - scene.ForEachClient(delegate(IClientAPI client) { SendAgentGroupDataUpdate(client, dataForClientID); }); - } - } + SendAgentGroupDataUpdate(remoteClient, true); } /// - /// Update remoteClient with group information about dataForAgentID + /// Tell remoteClient about its agent groups, and optionally send title to others /// - private void SendAgentGroupDataUpdate(IClientAPI remoteClient, UUID dataForAgentID) + private void SendAgentGroupDataUpdate(IClientAPI remoteClient, bool tellOthers) { if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name); + // NPCs currently don't have a CAPs structure or event queues. There is a strong argument for conveying this information + // to them anyway since it makes writing server-side bots a lot easier, but for now we don't do anything. + if (remoteClient.SceneAgent.PresenceType == PresenceType.Npc) + return; + // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff - OnAgentDataUpdateRequest(remoteClient, dataForAgentID, UUID.Zero); + UUID agentID = GetRequestingAgentID(remoteClient); - // Need to send a group membership update to the client - // UDP version doesn't seem to behave nicely. But we're going to send it out here - // with an empty group membership to hopefully remove groups being displayed due - // to the core Groups Stub - //remoteClient.SendGroupMembership(new GroupMembershipData[0]); + SendDataUpdate(remoteClient, tellOthers); - GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID); - SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); + GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, agentID); - //remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); - if (remoteClient.AgentId == dataForAgentID) - remoteClient.RefreshGroupMembership(); + remoteClient.UpdateGroupMembership(membershipArray); + remoteClient.SendAgentGroupDataUpdate(agentID, membershipArray); } /// @@ -1381,7 +1342,7 @@ namespace OpenSim.Groups membershipArray = membershipData.ToArray(); } } - + if (m_debugEnabled) { m_log.InfoFormat("[Groups]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); @@ -1394,27 +1355,49 @@ namespace OpenSim.Groups return membershipArray; } - - private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) + //tell remoteClient about its agent group info, and optionally send title to others + private void SendDataUpdate(IClientAPI remoteClient, bool tellOthers) { - if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff - string firstname = "Unknown", lastname = "Unknown"; - string name = m_UserManagement.GetUserName(dataForAgentID); - if (!string.IsNullOrEmpty(name)) + UUID activeGroupID = UUID.Zero; + string activeGroupTitle = string.Empty; + string activeGroupName = string.Empty; + ulong activeGroupPowers = (ulong)GroupPowers.None; + + UUID agentID = GetRequestingAgentID(remoteClient); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(agentID.ToString(), agentID.ToString()); + if (membership != null) { - string[] parts = name.Split(new char[] { ' ' }); - if (parts.Length >= 2) - { - firstname = parts[0]; - lastname = parts[1]; - } + activeGroupID = membership.GroupID; + activeGroupTitle = membership.GroupTitle; + activeGroupPowers = membership.GroupPowers; + activeGroupName = membership.GroupName; } - - remoteClient.SendAgentDataUpdate(dataForAgentID, activeGroupID, firstname, + + UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, agentID); + string firstname, lastname; + if (account != null) + { + firstname = account.FirstName; + lastname = account.LastName; + } + else + { + firstname = "Unknown"; + lastname = "Unknown"; + } + + remoteClient.SendAgentDataUpdate(agentID, activeGroupID, firstname, lastname, activeGroupPowers, activeGroupName, activeGroupTitle); + + if (tellOthers) + SendScenePresenceUpdate(agentID, activeGroupTitle); + + ScenePresence sp = (ScenePresence)remoteClient.SceneAgent; + if (sp != null) + sp.Grouptitle = activeGroupTitle; } #endregion @@ -1425,7 +1408,7 @@ namespace OpenSim.Groups { if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - IClientAPI localClient = GetActiveClient(msgTo); + IClientAPI localClient = GetActiveRootClient(msgTo); if (localClient != null) { if (m_debugEnabled) m_log.InfoFormat("[Groups]: MsgTo ({0}) is local, delivering directly", localClient.Name); @@ -1463,5 +1446,4 @@ namespace OpenSim.Groups } } - } diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs index 7d57de1..9852581 100644 --- a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs +++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs @@ -103,7 +103,7 @@ namespace OpenSim.Groups if (!m_Enabled) return; - m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName); + m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName); scene.RegisterModuleInterface(this); m_Scenes.Add(scene); @@ -135,7 +135,7 @@ namespace OpenSim.Groups { m_LocalGroupsConnector = new GroupsServiceLocalConnectorModule(m_Config, m_UserManagement); // Also, if local, create the endpoint for the HGGroupsService - new HGGroupsServiceRobustConnector(m_Config, MainServer.Instance, string.Empty, + new HGGroupsServiceRobustConnector(m_Config, MainServer.Instance, string.Empty, scene.RequestModuleInterface(), scene.RequestModuleInterface()); } @@ -170,7 +170,7 @@ namespace OpenSim.Groups if (sp is ScenePresence && ((ScenePresence)sp).PresenceType != PresenceType.Npc) { AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId); - if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 && + if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 && m_OfflineIM != null && m_Messaging != null) { List ims = m_OfflineIM.GetMessages(aCircuit.AgentID); @@ -184,12 +184,12 @@ namespace OpenSim.Groups #region IGroupsServicesConnector - public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, + public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID, out string reason) { reason = string.Empty; if (m_UserManagement.IsLocalGridUser(RequestingAgentID)) - return m_LocalGroupsConnector.CreateGroup(RequestingAgentID, name, charter, showInList, insigniaID, + return m_LocalGroupsConnector.CreateGroup(RequestingAgentID, name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason); else { @@ -198,14 +198,14 @@ namespace OpenSim.Groups } } - public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, + public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, out string reason) { reason = string.Empty; string url = string.Empty; string name = string.Empty; if (IsLocal(groupID, out url, out name)) - return m_LocalGroupsConnector.UpdateGroup(AgentUUI(RequestingAgentID), groupID, charter, showInList, insigniaID, membershipFee, + return m_LocalGroupsConnector.UpdateGroup(AgentUUI(RequestingAgentID), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, out reason); else { @@ -374,7 +374,7 @@ namespace OpenSim.Groups } } - + return new List(); } @@ -626,7 +626,7 @@ namespace OpenSim.Groups } if (agent != null) return Util.ProduceUserUniversalIdentifier(agent); - + // we don't know anything about this foreign user // try asking the user management module, which may know more return m_UserManagement.GetUserUUI(AgentID); @@ -664,7 +664,7 @@ namespace OpenSim.Groups string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty; if (Util.ParseUniversalUserIdentifier(uID, out userID, out url, out first, out last, out tmp)) m_UserManagement.AddUser(userID, first, last, url); - + return userID; } diff --git a/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs index f60c1a5..51f3ec1 100644 --- a/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs +++ b/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs @@ -64,8 +64,8 @@ namespace OpenSim.Groups m_log.DebugFormat("[Groups.RobustHGConnector]: Starting with config name {0}", m_ConfigName); - string homeURI = Util.GetConfigVarFromSections(config, "HomeURI", - new string[] { "Startup", "Hypergrid", m_ConfigName}, string.Empty); + string homeURI = Util.GetConfigVarFromSections(config, "HomeURI", + new string[] { "Startup", "Hypergrid", m_ConfigName}, string.Empty); if (homeURI == string.Empty) throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide the HomeURI [Startup] or in section {0}", m_ConfigName)); @@ -115,9 +115,10 @@ namespace OpenSim.Groups protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); + body = body.Trim(); //m_log.DebugFormat("[XXX]: query String: {0}", body); diff --git a/OpenSim/Addons/Groups/IGroupsServicesConnector.cs b/OpenSim/Addons/Groups/IGroupsServicesConnector.cs index a09b59e..8a6e88d 100644 --- a/OpenSim/Addons/Groups/IGroupsServicesConnector.cs +++ b/OpenSim/Addons/Groups/IGroupsServicesConnector.cs @@ -34,9 +34,9 @@ namespace OpenSim.Groups { public interface IGroupsServicesConnector { - UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, + UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID, out string reason); - bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, + bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, out string reason); ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName); List FindGroups(string RequestingAgentID, string search); @@ -75,7 +75,7 @@ namespace OpenSim.Groups /// If the user is a member of the group then the data structure is returned. If not, then null is returned. /// ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID); - + /// /// Get information about the groups to which a user belongs. /// @@ -87,7 +87,7 @@ namespace OpenSim.Groups /// List GetAgentGroupMemberships(string RequestingAgentID, string AgentID); - bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, + bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID); GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID); List GetGroupNotices(string RequestingAgentID, UUID GroupID); diff --git a/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs b/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs index 8e30df5..c7877c6 100644 --- a/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs +++ b/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs @@ -108,7 +108,7 @@ namespace OpenSim.Groups if (!m_Enabled) return; - m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName); + m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName); scene.RegisterModuleInterface(this); m_Scenes.Add(scene); } @@ -146,16 +146,16 @@ namespace OpenSim.Groups #region IGroupsServicesConnector - public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, + public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID, out string reason) { m_log.DebugFormat("[Groups]: Creating group {0}", name); reason = string.Empty; - return m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID, + return m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason); } - public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, + public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, out string reason) { reason = string.Empty; @@ -296,7 +296,7 @@ namespace OpenSim.Groups public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID) { - return m_GroupsService.AddGroupNotice(RequestingAgentID, groupID, noticeID, fromName, subject, message, + return m_GroupsService.AddGroupNotice(RequestingAgentID, groupID, noticeID, fromName, subject, message, hasAttachment, attType, attName, attItemID, attOwnerID); } diff --git a/OpenSim/Addons/Groups/Properties/AssemblyInfo.cs b/OpenSim/Addons/Groups/Properties/AssemblyInfo.cs index cf0de1d..e9be9c4 100644 --- a/OpenSim/Addons/Groups/Properties/AssemblyInfo.cs +++ b/OpenSim/Addons/Groups/Properties/AssemblyInfo.cs @@ -3,7 +3,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Mono.Addins; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("OpenSim.Addons.Groups")] @@ -15,8 +15,8 @@ using Mono.Addins; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] @@ -26,11 +26,11 @@ using Mono.Addins; // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("0.8.3.*")] +[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] [assembly: Addin("OpenSim.Groups", OpenSim.VersionInfo.VersionNumber)] [assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs index 7450c14..8f6be0d 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs @@ -41,7 +41,7 @@ using Nini.Config; namespace OpenSim.Groups { - public class GroupsServiceRemoteConnector + public class GroupsServiceRemoteConnector { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -71,7 +71,7 @@ namespace OpenSim.Groups } /// - m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, authentication {1}", + m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, authentication {1}", m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString())); } diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs index d4739c6..b6c75a8 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs @@ -113,7 +113,7 @@ namespace OpenSim.Groups if (!m_Enabled) return; - m_log.DebugFormat("[Groups.RemoteConnector]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName); + m_log.DebugFormat("[Groups.RemoteConnector]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName); scene.RegisterModuleInterface(this); m_Scenes.Add(scene); } @@ -151,7 +151,7 @@ namespace OpenSim.Groups #region IGroupsServicesConnector - public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, + public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID, out string reason) { m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name); @@ -167,7 +167,7 @@ namespace OpenSim.Groups return groupID; } - public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, + public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, out string reason) { string r = string.Empty; @@ -186,9 +186,9 @@ namespace OpenSim.Groups if (GroupID == UUID.Zero && (GroupName == null || GroupName != null && GroupName == string.Empty)) return null; - return m_CacheWrapper.GetGroupRecord(RequestingAgentID,GroupID,GroupName, delegate - { - return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName); + return m_CacheWrapper.GetGroupRecord(RequestingAgentID,GroupID,GroupName, delegate + { + return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName); }); } @@ -362,7 +362,7 @@ namespace OpenSim.Groups m_GroupsService.RemoveAgentToGroupInvite(RequestingAgentID, inviteID); } - public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, + public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID) { GroupNoticeInfo notice = new GroupNoticeInfo(); diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs index 26e844e..8502bb5 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs @@ -91,9 +91,10 @@ namespace OpenSim.Groups protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); + body = body.Trim(); //m_log.DebugFormat("[XXX]: query String: {0}", body); @@ -286,7 +287,7 @@ namespace OpenSim.Groups string requestingAgentID = request["RequestingAgentID"].ToString(); if (!m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID)) - NullResult(result, string.Format("Insufficient permissions.", agentID)); + NullResult(result, string.Format("Insufficient permissions. {0}", agentID)); else result["RESULT"] = "true"; } @@ -393,7 +394,7 @@ namespace OpenSim.Groups if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID") || !request.ContainsKey("Name") || !request.ContainsKey("Description") || !request.ContainsKey("Title") || - !request.ContainsKey("Powers") || !request.ContainsKey("OP")) + !request.ContainsKey("Powers") || !request.ContainsKey("OP")) NullResult(result, "Bad network data"); else @@ -519,11 +520,11 @@ namespace OpenSim.Groups bool success = false; if (op == "ADD") - success = m_GroupsService.AddAgentToGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(), + success = m_GroupsService.AddAgentToGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(), new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString())); else if (op == "DELETE") - success = m_GroupsService.RemoveAgentFromGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(), + success = m_GroupsService.RemoveAgentFromGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(), new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString())); result["RESULT"] = success.ToString(); @@ -647,8 +648,8 @@ namespace OpenSim.Groups string op = request["OP"].ToString(); if (op == "ADD" && request.ContainsKey("GroupID") && request.ContainsKey("RoleID") && request.ContainsKey("AgentID")) - { - bool success = m_GroupsService.AddAgentToGroupInvite(request["RequestingAgentID"].ToString(), + { + bool success = m_GroupsService.AddAgentToGroupInvite(request["RequestingAgentID"].ToString(), new UUID(request["InviteID"].ToString()), new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()), request["AgentID"].ToString()); @@ -664,7 +665,7 @@ namespace OpenSim.Groups } else if (op == "GET") { - GroupInviteInfo invite = m_GroupsService.GetAgentToGroupInvite(request["RequestingAgentID"].ToString(), + GroupInviteInfo invite = m_GroupsService.GetAgentToGroupInvite(request["RequestingAgentID"].ToString(), new UUID(request["InviteID"].ToString())); if (invite != null) diff --git a/OpenSim/Addons/Groups/Service/GroupsService.cs b/OpenSim/Addons/Groups/Service/GroupsService.cs index 07641ef..ea0fedd 100644 --- a/OpenSim/Addons/Groups/Service/GroupsService.cs +++ b/OpenSim/Addons/Groups/Service/GroupsService.cs @@ -126,7 +126,7 @@ namespace OpenSim.Groups #endregion - public UUID CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, + public UUID CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID, out string reason) { reason = string.Empty; @@ -264,7 +264,7 @@ namespace OpenSim.Groups if (ownerRole != null) ownerRoleID = ownerRole.RoleID; - // Check visibility? + // Check visibility? // When we don't want to check visibility, we pass it "all" as the requestingAgentID bool checkVisibility = !RequestingAgentID.Equals(UUID.Zero.ToString()); @@ -307,20 +307,20 @@ namespace OpenSim.Groups m.Contribution = Int32.Parse(d.Data["Contribution"]); m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false; - GridUserData gud = m_GridUserService.Get(d.PrincipalID); - if (gud != null) - { - if (bool.Parse(gud.Data["Online"])) - { - m.OnlineStatus = @"Online"; - } - else - { - int unixtime = int.Parse(gud.Data["Login"]); - // The viewer is very picky about how these strings are formed. Eg. it will crash on malformed dates! - m.OnlineStatus = (unixtime == 0) ? @"unknown" : Util.ToDateTime(unixtime).ToString("MM/dd/yyyy"); - } - } + GridUserData gud = m_GridUserService.Get(d.PrincipalID); + if (gud != null) + { + if (bool.Parse(gud.Data["Online"])) + { + m.OnlineStatus = @"Online"; + } + else + { + int unixtime = int.Parse(gud.Data["Login"]); + // The viewer is very picky about how these strings are formed. Eg. it will crash on malformed dates! + m.OnlineStatus = (unixtime == 0) ? @"unknown" : Util.ToDateTime(unixtime).ToString("MM/dd/yyyy"); + } + } // Is this person an owner of the group? m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false; @@ -486,7 +486,7 @@ namespace OpenSim.Groups // check permissions bool limited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMemberLimited); bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) | IsOwner(RequestingAgentID, GroupID); - if (!limited || !unlimited) + if (!limited && !unlimited) { m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID); return false; @@ -496,7 +496,7 @@ namespace OpenSim.Groups if (!unlimited && limited) { // check whether person's has this role - RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID); + RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, RequestingAgentID); if (rolemembership == null) { m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID); @@ -516,13 +516,26 @@ namespace OpenSim.Groups return false; // check permissions + bool limited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMemberLimited); bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) || IsOwner(RequestingAgentID, GroupID); - if (!unlimited) + if (!limited && !unlimited) { m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID); return false; } + // AssignMemberLimited means that the person can assign another person to the same roles that she has in the group + if (!unlimited && limited) + { + // check whether person's has this role + RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, RequestingAgentID); + if (rolemembership == null) + { + m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID); + return false; + } + } + RoleMembershipData rolemember = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID); if (rolemember == null) @@ -540,8 +553,8 @@ namespace OpenSim.Groups { newRoleID = r.RoleID; break; - } - } + } + } MembershipData member = m_Database.RetrieveMember(GroupID, AgentID); if (member != null) @@ -699,7 +712,7 @@ namespace OpenSim.Groups m_Database.StoreMember(membership); } - public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, + public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID) { // Check perms @@ -812,7 +825,7 @@ namespace OpenSim.Groups if (RoleID != UUID.Zero) _AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID); - // Make thit this active group + // Make this the active group PrincipalData pdata = new PrincipalData(); pdata.PrincipalID = AgentID; pdata.ActiveGroupID = GroupID; diff --git a/OpenSim/Addons/Groups/Service/GroupsServiceBase.cs b/OpenSim/Addons/Groups/Service/GroupsServiceBase.cs index 8e237aa..98d0172 100644 --- a/OpenSim/Addons/Groups/Service/GroupsServiceBase.cs +++ b/OpenSim/Addons/Groups/Service/GroupsServiceBase.cs @@ -35,67 +35,67 @@ using OpenSim.Services.Base; namespace OpenSim.Groups { - public class GroupsServiceBase : ServiceBase - { - protected IGroupsData m_Database = null; - protected IGridUserData m_GridUserService = null; + public class GroupsServiceBase : ServiceBase + { + protected IGroupsData m_Database = null; + protected IGridUserData m_GridUserService = null; - public GroupsServiceBase(IConfigSource config, string cName) - : base(config) - { - string dllName = String.Empty; - string connString = String.Empty; - string realm = "os_groups"; - string usersRealm = "GridUser"; - string configName = (cName == string.Empty) ? "Groups" : cName; + public GroupsServiceBase(IConfigSource config, string cName) + : base(config) + { + string dllName = String.Empty; + string connString = String.Empty; + string realm = "os_groups"; + string usersRealm = "GridUser"; + string configName = (cName == string.Empty) ? "Groups" : cName; - // - // Try reading the [DatabaseService] section, if it exists - // - IConfig dbConfig = config.Configs["DatabaseService"]; - if (dbConfig != null) - { - if (dllName == String.Empty) - dllName = dbConfig.GetString("StorageProvider", String.Empty); - if (connString == String.Empty) - connString = dbConfig.GetString("ConnectionString", String.Empty); - } + // + // Try reading the [DatabaseService] section, if it exists + // + IConfig dbConfig = config.Configs["DatabaseService"]; + if (dbConfig != null) + { + if (dllName == String.Empty) + dllName = dbConfig.GetString("StorageProvider", String.Empty); + if (connString == String.Empty) + connString = dbConfig.GetString("ConnectionString", String.Empty); + } - // - // [Groups] section overrides [DatabaseService], if it exists - // - IConfig groupsConfig = config.Configs[configName]; - if (groupsConfig != null) - { - dllName = groupsConfig.GetString("StorageProvider", dllName); - connString = groupsConfig.GetString("ConnectionString", connString); - realm = groupsConfig.GetString("Realm", realm); - } + // + // [Groups] section overrides [DatabaseService], if it exists + // + IConfig groupsConfig = config.Configs[configName]; + if (groupsConfig != null) + { + dllName = groupsConfig.GetString("StorageProvider", dllName); + connString = groupsConfig.GetString("ConnectionString", connString); + realm = groupsConfig.GetString("Realm", realm); + } - // - // We tried, but this doesn't exist. We can't proceed. - // - if (dllName.Equals(String.Empty)) - throw new Exception("No StorageProvider configured"); + // + // We tried, but this doesn't exist. We can't proceed. + // + if (dllName.Equals(String.Empty)) + throw new Exception("No StorageProvider configured"); - m_Database = LoadPlugin(dllName, new Object[] { connString, realm }); - if (m_Database == null) - throw new Exception("Could not find a storage interface in the given module " + dllName); + m_Database = LoadPlugin(dllName, new Object[] { connString, realm }); + if (m_Database == null) + throw new Exception("Could not find a storage interface in the given module " + dllName); - // - // [GridUserService] section overrides [DatabaseService], if it exists - // - IConfig usersConfig = config.Configs["GridUserService"]; - if (usersConfig != null) - { - dllName = usersConfig.GetString("StorageProvider", dllName); - connString = usersConfig.GetString("ConnectionString", connString); + // + // [GridUserService] section overrides [DatabaseService], if it exists + // + IConfig usersConfig = config.Configs["GridUserService"]; + if (usersConfig != null) + { + dllName = usersConfig.GetString("StorageProvider", dllName); + connString = usersConfig.GetString("ConnectionString", connString); usersRealm = usersConfig.GetString("Realm", usersRealm); - } + } - m_GridUserService = LoadPlugin(dllName, new Object[] { connString, usersRealm }); - if (m_GridUserService == null) - throw new Exception("Could not find a storage inferface for the given users module " + dllName); - } - } + m_GridUserService = LoadPlugin(dllName, new Object[] { connString, usersRealm }); + if (m_GridUserService == null) + throw new Exception("Could not find a storage inferface for the given users module " + dllName); + } + } } diff --git a/OpenSim/Addons/Groups/Service/HGGroupsService.cs b/OpenSim/Addons/Groups/Service/HGGroupsService.cs index 56e999b..7d86f85 100644 --- a/OpenSim/Addons/Groups/Service/HGGroupsService.cs +++ b/OpenSim/Addons/Groups/Service/HGGroupsService.cs @@ -76,7 +76,7 @@ namespace OpenSim.Groups // Check if it already exists GroupData grec = m_Database.RetrieveGroup(groupID); - if (grec == null || + if (grec == null || (grec != null && grec.Data["Location"] != string.Empty && grec.Data["Location"].ToLower() != serviceLocation.ToLower())) { // Create the group diff --git a/OpenSim/Addons/OfflineIM/OfflineIMRegionModule.cs b/OpenSim/Addons/OfflineIM/OfflineIMRegionModule.cs index 5340bcd..d8164e7 100644 --- a/OpenSim/Addons/OfflineIM/OfflineIMRegionModule.cs +++ b/OpenSim/Addons/OfflineIM/OfflineIMRegionModule.cs @@ -114,7 +114,6 @@ namespace OpenSim.OfflineIM scene.ForEachClient(delegate(IClientAPI client) { client.OnRetrieveInstantMessages -= RetrieveInstantMessages; - client.OnMuteListRequest -= OnMuteListRequest; }); } @@ -162,7 +161,6 @@ namespace OpenSim.OfflineIM private void OnNewClient(IClientAPI client) { client.OnRetrieveInstantMessages += RetrieveInstantMessages; - client.OnMuteListRequest += OnMuteListRequest; } private void RetrieveInstantMessages(IClientAPI client) @@ -194,20 +192,6 @@ namespace OpenSim.OfflineIM } } - // Apparently this is needed in order for the viewer to request the IMs. - private void OnMuteListRequest(IClientAPI client, uint crc) - { - m_log.DebugFormat("[OfflineIM.V2] Got mute list request for crc {0}", crc); - string filename = "mutes" + client.AgentId.ToString(); - - IXfer xfer = client.Scene.RequestModuleInterface(); - if (xfer != null) - { - xfer.AddNewFile(filename, new Byte[0]); - client.SendMuteListUpdate(filename); - } - } - private void UndeliveredMessage(GridInstantMessage im) { if (im.dialog != (byte)InstantMessageDialog.MessageFromObject && diff --git a/OpenSim/Addons/OfflineIM/Properties/AssemblyInfo.cs b/OpenSim/Addons/OfflineIM/Properties/AssemblyInfo.cs index 0699660..fe828bc 100644 --- a/OpenSim/Addons/OfflineIM/Properties/AssemblyInfo.cs +++ b/OpenSim/Addons/OfflineIM/Properties/AssemblyInfo.cs @@ -3,7 +3,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Mono.Addins; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("OpenSim.Addons.OfflineIM")] @@ -15,8 +15,8 @@ using Mono.Addins; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] @@ -26,11 +26,11 @@ using Mono.Addins; // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("0.8.3.*")] +[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] [assembly: Addin("OpenSim.OfflineIM", OpenSim.VersionInfo.VersionNumber)] [assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] diff --git a/OpenSim/Addons/OfflineIM/Remote/OfflineIMServiceRemoteConnector.cs b/OpenSim/Addons/OfflineIM/Remote/OfflineIMServiceRemoteConnector.cs index 047b8be..46d4979 100644 --- a/OpenSim/Addons/OfflineIM/Remote/OfflineIMServiceRemoteConnector.cs +++ b/OpenSim/Addons/OfflineIM/Remote/OfflineIMServiceRemoteConnector.cs @@ -77,7 +77,7 @@ namespace OpenSim.OfflineIM break; } /// - m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: Offline IM server at {0} with auth {1}", + m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: Offline IM server at {0} with auth {1}", m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString())); } @@ -140,7 +140,7 @@ namespace OpenSim.OfflineIM { Dictionary sendData = new Dictionary(); sendData["UserID"] = userID; - + MakeRequest("DELETE", sendData); } diff --git a/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs b/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs index 02084ff..d1ecdce 100644 --- a/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs +++ b/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs @@ -90,7 +90,7 @@ namespace OpenSim.OfflineIM public bool StoreMessage(GridInstantMessage im, out string reason) { reason = string.Empty; - + // Check limits UUID principalID = new UUID(im.toAgentID); long count = m_Database.GetCount("PrincipalID", principalID.ToString()); diff --git a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs index 89224a6..feb73a9 100644 --- a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs +++ b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs @@ -124,7 +124,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions m_log.Debug("[LOAD REGIONS PLUGIN]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + Thread.CurrentThread.ManagedThreadId.ToString() + ")"); - + bool changed = m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]); m_openSim.CreateRegion(regionsToLoad[i], true, out scene); diff --git a/OpenSim/ApplicationPlugins/LoadRegions/Properties/AssemblyInfo.cs b/OpenSim/ApplicationPlugins/LoadRegions/Properties/AssemblyInfo.cs index 6c3c3e3..6b1ea73 100644 --- a/OpenSim/ApplicationPlugins/LoadRegions/Properties/AssemblyInfo.cs +++ b/OpenSim/ApplicationPlugins/LoadRegions/Properties/AssemblyInfo.cs @@ -61,9 +61,8 @@ using Mono.Addins; // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -// [assembly: AssemblyVersion("0.7.6.*")] -[assembly : AssemblyVersion("0.8.2.*")] +[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] [assembly: Addin("OpenSim.ApplicationPlugins.LoadRegions", OpenSim.VersionInfo.VersionNumber)] [assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)] diff --git a/OpenSim/ApplicationPlugins/LoadRegions/RegionLoaderFileSystem.cs b/OpenSim/ApplicationPlugins/LoadRegions/RegionLoaderFileSystem.cs index ea95696..976714c 100644 --- a/OpenSim/ApplicationPlugins/LoadRegions/RegionLoaderFileSystem.cs +++ b/OpenSim/ApplicationPlugins/LoadRegions/RegionLoaderFileSystem.cs @@ -48,7 +48,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions public RegionInfo[] LoadRegions() { - string regionConfigPath = Util.configDir(); + string regionConfigPath = Path.Combine(Util.configDir(), "Regions"); bool allowRegionless = false; try @@ -68,14 +68,13 @@ namespace OpenSim.ApplicationPlugins.LoadRegions } string[] configFiles = Directory.GetFiles(regionConfigPath, "*.xml"); -//// Causes hangs with the actual .ini files if they are in the same place. -//// string[] iniFiles = Directory.GetFiles(regionConfigPath, "*.ini"); + string[] iniFiles = Directory.GetFiles(regionConfigPath, "*.ini"); // Create an empty Regions.ini if there are no existing config files. - if (!allowRegionless && configFiles.Length == 0 /*&& iniFiles.Length == 0*/) + if (!allowRegionless && configFiles.Length == 0 && iniFiles.Length == 0) { new RegionInfo("DEFAULT REGION CONFIG", Path.Combine(regionConfigPath, "Regions.ini"), false, m_configSource); -//// iniFiles = Directory.GetFiles(regionConfigPath, "*.ini"); + iniFiles = Directory.GetFiles(regionConfigPath, "*.ini"); } m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loading config files from {0}", regionConfigPath); @@ -83,7 +82,6 @@ namespace OpenSim.ApplicationPlugins.LoadRegions List regionInfos = new List(); int i = 0; -/* foreach (string file in iniFiles) { m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loading config file {0}", file); @@ -100,22 +98,17 @@ namespace OpenSim.ApplicationPlugins.LoadRegions i++; } } -*/ + foreach (string file in configFiles) { m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loading config file {0}", file); - IConfigSource source = new XmlConfigSource(file); - - foreach (IConfig config in source.Configs) - { - RegionInfo regionInfo = new RegionInfo("REGION CONFIG #" + (i + 1), file, false, m_configSource, config.Name); - regionInfos.Add(regionInfo); + RegionInfo regionInfo = new RegionInfo("REGION CONFIG #" + (i + 1), file, false, m_configSource); + regionInfos.Add(regionInfo); - m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loaded config for region {0}", regionInfo.RegionName); + m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loaded config for region {0}", regionInfo.RegionName); - i++; - } + i++; } return regionInfos.ToArray(); diff --git a/OpenSim/ApplicationPlugins/LoadRegions/RegionLoaderWebServer.cs b/OpenSim/ApplicationPlugins/LoadRegions/RegionLoaderWebServer.cs index 850f3e0..2b91fc5 100644 --- a/OpenSim/ApplicationPlugins/LoadRegions/RegionLoaderWebServer.cs +++ b/OpenSim/ApplicationPlugins/LoadRegions/RegionLoaderWebServer.cs @@ -49,6 +49,9 @@ namespace OpenSim.ApplicationPlugins.LoadRegions public RegionInfo[] LoadRegions() { + int tries = 3; + int wait = 2000; + if (m_configSource == null) { m_log.Error("[WEBLOADER]: Unable to load configuration source!"); @@ -56,7 +59,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions } else { - IConfig startupConfig = (IConfig) m_configSource.Configs["Startup"]; + IConfig startupConfig = (IConfig)m_configSource.Configs["Startup"]; string url = startupConfig.GetString("regionload_webserver_url", String.Empty).Trim(); bool allowRegionless = startupConfig.GetBoolean("allow_regionless", false); @@ -67,82 +70,75 @@ namespace OpenSim.ApplicationPlugins.LoadRegions } else { - RegionInfo[] regionInfos = new RegionInfo[] {}; - int regionCount = 0; - HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url); - webRequest.Timeout = 30000; //30 Second Timeout - m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url); - - try + while (tries > 0) { - string xmlSource = String.Empty; + RegionInfo[] regionInfos = new RegionInfo[] { }; + int regionCount = 0; + HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url); + webRequest.Timeout = 30000; //30 Second Timeout + m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url); - using (HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse()) + try { + HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse(); m_log.Debug("[WEBLOADER]: Downloading region information..."); - - using (Stream s = webResponse.GetResponseStream()) + StreamReader reader = new StreamReader(webResponse.GetResponseStream()); + string xmlSource = String.Empty; + string tempStr = reader.ReadLine(); + while (tempStr != null) { - using (StreamReader reader = new StreamReader(s)) - { - string tempStr = reader.ReadLine(); - while (tempStr != null) - { - xmlSource = xmlSource + tempStr; - tempStr = reader.ReadLine(); - } - } + xmlSource = xmlSource + tempStr; + tempStr = reader.ReadLine(); } - } - - m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " + - xmlSource.Length); - XmlDocument xmlDoc = new XmlDocument(); - xmlDoc.LoadXml(xmlSource); - if (xmlDoc.FirstChild.Name == "Nini") - { - regionCount = xmlDoc.FirstChild.ChildNodes.Count; - - if (regionCount > 0) + m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " + + xmlSource.Length); + XmlDocument xmlDoc = new XmlDocument(); + xmlDoc.XmlResolver = null; + xmlDoc.LoadXml(xmlSource); + if (xmlDoc.FirstChild.Name == "Nini") { - regionInfos = new RegionInfo[regionCount]; - int i; - for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++) + regionCount = xmlDoc.FirstChild.ChildNodes.Count; + + if (regionCount > 0) { - m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml); - regionInfos[i] = - new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i],false,m_configSource); + regionInfos = new RegionInfo[regionCount]; + int i; + for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++) + { + m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml); + regionInfos[i] = + new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i], false, m_configSource); + } } } } - } - catch (WebException ex) - { - using (HttpWebResponse response = (HttpWebResponse)ex.Response) + catch (WebException ex) { - if (response.StatusCode == HttpStatusCode.NotFound) + if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotFound) { if (!allowRegionless) throw ex; } else - { throw ex; - } } - } - if (regionCount > 0 | allowRegionless) - { - return regionInfos; - } - else - { - m_log.Error("[WEBLOADER]: No region configs were available."); - return null; + if (regionCount > 0 | allowRegionless) + return regionInfos; + + m_log.Debug("[WEBLOADER]: Request yielded no regions."); + tries--; + if (tries > 0) + { + m_log.Debug("[WEBLOADER]: Retrying"); + System.Threading.Thread.Sleep(wait); + } } + + m_log.Error("[WEBLOADER]: No region configs were available."); + return null; } } } } -} +} \ No newline at end of file diff --git a/OpenSim/ApplicationPlugins/RegionModulesController/Properties/AssemblyInfo.cs b/OpenSim/ApplicationPlugins/RegionModulesController/Properties/AssemblyInfo.cs index acbdc3a..a45abad 100644 --- a/OpenSim/ApplicationPlugins/RegionModulesController/Properties/AssemblyInfo.cs +++ b/OpenSim/ApplicationPlugins/RegionModulesController/Properties/AssemblyInfo.cs @@ -3,7 +3,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Mono.Addins; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("OpenSim.ApplicationPlugins.RegionModulesController")] @@ -15,8 +15,8 @@ using Mono.Addins; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] @@ -26,11 +26,11 @@ using Mono.Addins; // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("0.8.3.*")] +[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] [assembly: Addin("OpenSim.ApplicationPlugins.RegionModulesController", OpenSim.VersionInfo.VersionNumber)] [assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)] diff --git a/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs b/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs index 8f38a29..2e25c60 100644 --- a/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs +++ b/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs @@ -75,7 +75,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController } #region IApplicationPlugin implementation - + public void Initialise (OpenSimBase openSim) { m_openSim = openSim; @@ -111,7 +111,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController { m_log.InfoFormat( "[REGIONMODULES]: From plugin {0}, (version {1}), loaded {2} modules, {3} shared, {4} non-shared {5} unknown", - loadedModuleData.Key.Id, + loadedModuleData.Key.Id, loadedModuleData.Key.Version, loadedModuleData.Value[0] + loadedModuleData.Value[1] + loadedModuleData.Value[2], loadedModuleData.Value[0], loadedModuleData.Value[1], loadedModuleData.Value[2]); @@ -261,7 +261,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController } #region Region Module interfacesController implementation - + /// /// Check that the given module is no disabled in the [Modules] section of the config files. /// @@ -293,10 +293,10 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController if (className != String.Empty && node.Type.ToString() != className) return false; - } - + } + return true; - } + } // The root of all evil. // This is where we handle adding the modules to scenes when they diff --git a/OpenSim/ApplicationPlugins/RemoteController/Properties/AssemblyInfo.cs b/OpenSim/ApplicationPlugins/RemoteController/Properties/AssemblyInfo.cs index ce87400..590a6a9 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/Properties/AssemblyInfo.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/Properties/AssemblyInfo.cs @@ -3,7 +3,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Mono.Addins; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("OpenSim.ApplicationPlugins.RemoteController")] @@ -15,8 +15,8 @@ using Mono.Addins; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] @@ -26,11 +26,11 @@ using Mono.Addins; // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("0.8.3.*")] +[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] [assembly: Addin("OpenSim.ApplicationPlugins.RemoteController", OpenSim.VersionInfo.VersionNumber)] [assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)] diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 808d9e4..84d87f1 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -74,6 +74,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController private string m_name = "RemoteAdminPlugin"; private string m_version = "0.0"; + private string m_openSimVersion; public string Version { @@ -93,6 +94,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController public void Initialise(OpenSimBase openSim) { + m_openSimVersion = openSim.GetVersionText(); + m_configSource = openSim.ConfigSource.Source; try { @@ -135,10 +138,13 @@ namespace OpenSim.ApplicationPlugins.RemoteController availableMethods["admin_region_query"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRegionQueryMethod); availableMethods["admin_shutdown"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcShutdownMethod); availableMethods["admin_broadcast"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAlertMethod); + availableMethods["admin_dialog"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcDialogMethod); availableMethods["admin_restart"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRestartMethod); availableMethods["admin_load_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadHeightmapMethod); availableMethods["admin_save_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveHeightmapMethod); + availableMethods["admin_reset_land"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcResetLand); + // Agent management availableMethods["admin_get_agents"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentsMethod); availableMethods["admin_teleport_agent"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcTeleportAgentMethod); @@ -163,8 +169,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList); availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload); - // Land management - availableMethods["admin_reset_land"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcResetLand); + // Misc + availableMethods["admin_refresh_search"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshSearch); + availableMethods["admin_refresh_map"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshMap); + availableMethods["admin_get_opensim_version"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetOpenSimVersion); + availableMethods["admin_get_agent_count"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentCount); // Either enable full remote functionality or just selected features string enabledMethods = m_config.GetString("enabled_methods", "all"); @@ -265,32 +274,148 @@ namespace OpenSim.ApplicationPlugins.RemoteController try { - m_log.Info("[RADMIN]: Request to restart Region."); + Scene rebootedScene = null; + bool restartAll = false; - CheckRegionParams(requestData, responseData); + IConfig startupConfig = m_configSource.Configs["Startup"]; + if (startupConfig != null) + { + if (startupConfig.GetBoolean("InworldRestartShutsDown", false)) + { + rebootedScene = m_application.SceneManager.CurrentOrFirstScene; + restartAll = true; + } + } - Scene rebootedScene = null; - GetSceneFromRegionParams(requestData, responseData, out rebootedScene); + if (rebootedScene == null) + { + CheckRegionParams(requestData, responseData); + + GetSceneFromRegionParams(requestData, responseData, out rebootedScene); + } + + IRestartModule restartModule = rebootedScene.RequestModuleInterface(); responseData["success"] = false; responseData["accepted"] = true; responseData["rebooting"] = true; - IRestartModule restartModule = rebootedScene.RequestModuleInterface(); - if (restartModule != null) + string message; + List times = new List(); + + if (requestData.ContainsKey("alerts")) { - List times = new List { 30, 15 }; + string[] alertTimes = requestData["alerts"].ToString().Split( new char[] {','}); + if (alertTimes.Length == 1 && Convert.ToInt32(alertTimes[0]) == -1) + { + m_log.Info("[RADMIN]: Request to cancel restart."); - restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true); - responseData["success"] = true; + if (restartModule != null) + { + message = "Restart has been cancelled"; + + if (requestData.ContainsKey("message")) + message = requestData["message"].ToString(); + + restartModule.AbortRestart(message); + + responseData["success"] = true; + responseData["rebooting"] = false; + + return; + } + } + foreach (string a in alertTimes) + times.Add(Convert.ToInt32(a)); + } + else + { + int timeout = 30; + if (requestData.ContainsKey("milliseconds")) + timeout = Int32.Parse(requestData["milliseconds"].ToString()) / 1000; + while (timeout > 0) + { + times.Add(timeout); + if (timeout > 300) + timeout -= 120; + else if (timeout > 30) + timeout -= 30; + else + timeout -= 15; + } + } + + m_log.Info("[RADMIN]: Request to restart Region."); + + message = "Region is restarting in {0}. Please save what you are doing and log out."; + + if (requestData.ContainsKey("message")) + message = requestData["message"].ToString(); + + bool notice = true; + if (requestData.ContainsKey("noticetype") + && ((string)requestData["noticetype"] == "dialog")) + { + notice = false; + } + + if (startupConfig.GetBoolean("SkipDelayOnEmptyRegion", false)) + { + m_log.Info("[RADMIN]: Counting affected avatars"); + int agents = 0; + + if (restartAll) + { + foreach (Scene s in m_application.SceneManager.Scenes) + { + foreach (ScenePresence sp in s.GetScenePresences()) + { + if (!sp.IsChildAgent && !sp.IsNPC) + agents++; + } + } + } + else + { + foreach (ScenePresence sp in rebootedScene.GetScenePresences()) + { + if (!sp.IsChildAgent && !sp.IsNPC) + agents++; + } + } + + m_log.InfoFormat("[RADMIN]: Avatars in region: {0}", agents); + + if (agents == 0) + { + m_log.Info("[RADMIN]: No avatars detected, shutting down without delay"); + + times.Clear(); + times.Add(0); + } + } + + List restartList; + + if (restartAll) + restartList = m_application.SceneManager.Scenes; + else + restartList = new List() { rebootedScene }; + + foreach (Scene s in m_application.SceneManager.Scenes) + { + restartModule = s.RequestModuleInterface(); + if (restartModule != null) + restartModule.ScheduleRestart(UUID.Zero, message, times.ToArray(), notice); } + responseData["success"] = true; } catch (Exception e) { -// m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace); + m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace); responseData["rebooting"] = false; - throw e; + throw; } m_log.Info("[RADMIN]: Restart Region request complete"); @@ -320,6 +445,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_log.Info("[RADMIN]: Alert request complete"); } + public void XmlRpcDialogMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + Hashtable responseData = (Hashtable)response.Value; + + m_log.Info("[RADMIN]: Dialog request started"); + + Hashtable requestData = (Hashtable)request.Params[0]; + + string message = (string)requestData["message"]; + string fromuuid = (string)requestData["from"]; + m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message); + + responseData["accepted"] = true; + responseData["success"] = true; + + m_application.SceneManager.ForEachScene( + delegate(Scene scene) + { + IDialogModule dialogModule = scene.RequestModuleInterface(); + if (dialogModule != null) + dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message); + }); + + m_log.Info("[RADMIN]: Dialog request complete"); + } + private void XmlRpcLoadHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { m_log.Info("[RADMIN]: Load height maps request started"); @@ -423,13 +574,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController message = "Region is going down now."; } - m_application.SceneManager.ForEachScene( + if (requestData.ContainsKey("noticetype") + && ((string) requestData["noticetype"] == "dialog")) + { + m_application.SceneManager.ForEachScene( + delegate(Scene scene) + { + IDialogModule dialogModule = scene.RequestModuleInterface(); + if (dialogModule != null) + dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message); + }); + } + else + { + if (!requestData.ContainsKey("noticetype") + || ((string)requestData["noticetype"] != "none")) + { + m_application.SceneManager.ForEachScene( + delegate(Scene scene) { IDialogModule dialogModule = scene.RequestModuleInterface(); if (dialogModule != null) dialogModule.SendGeneralAlert(message); }); + } + } // Perform shutdown System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing @@ -441,7 +611,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController } responseData["success"] = true; - + m_log.Info("[RADMIN]: Shutdown Administrator Request complete"); } @@ -613,9 +783,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController { // No INI setting recorded. } - + string regionIniPath; - + if (requestData.Contains("region_file")) { // Make sure that the file to be created is in a subdirectory of the region storage directory. @@ -639,7 +809,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController region.RegionName.Replace(" ", "_").Replace(":", "_"). Replace("/", "_"))); } - + m_log.DebugFormat("[RADMIN] CreateRegion: persisting region {0} to {1}", region.RegionID, regionIniPath); region.SaveRegionToFile("dynamic region", regionIniPath); @@ -648,9 +818,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController { region.Persistent = false; } - + // Set the estate - + // Check for an existing estate List estateIDs = m_application.EstateDataService.GetEstates((string) requestData["estate_name"]); if (estateIDs.Count < 1) @@ -661,12 +831,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController // ok, client wants us to use an explicit UUID // regardless of what the avatar name provided userID = new UUID((string) requestData["estate_owner_uuid"]); - + // Check that the specified user exists Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene; IUserAccountService accountService = currentOrFirst.UserAccountService; UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID, userID); - + if (user == null) throw new Exception("Specified user was not found."); } @@ -675,23 +845,23 @@ namespace OpenSim.ApplicationPlugins.RemoteController // We need to look up the UUID for the avatar with the provided name. string ownerFirst = (string) requestData["estate_owner_first"]; string ownerLast = (string) requestData["estate_owner_last"]; - + Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene; IUserAccountService accountService = currentOrFirst.UserAccountService; UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID, ownerFirst, ownerLast); - + // Check that the specified user exists if (user == null) throw new Exception("Specified user was not found."); - + userID = user.PrincipalID; } else { throw new Exception("Estate owner details not provided."); } - + // Create a new estate with the name provided region.EstateSettings = m_application.EstateDataService.CreateNewEstate(); @@ -718,7 +888,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController throw new Exception("Failed to join estate."); } } - + // Create the region and perform any initial initialization IScene newScene; @@ -1025,7 +1195,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController // Set home position - GridRegion home = scene.GridService.GetRegionByPosition(scopeID, + GridRegion home = scene.GridService.GetRegionByPosition(scopeID, (int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation)); if (null == home) { @@ -1255,7 +1425,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController if ((null != regionXLocation) && (null != regionYLocation)) { - GridRegion home = scene.GridService.GetRegionByPosition(scopeID, + GridRegion home = scene.GridService.GetRegionByPosition(scopeID, (int)Util.RegionToWorldLoc((uint)regionXLocation), (int)Util.RegionToWorldLoc((uint)regionYLocation)); if (null == home) { m_log.WarnFormat("[RADMIN]: Unable to set home region for updated user account {0} {1}", firstName, lastName); @@ -1282,7 +1452,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController throw e; } - + m_log.Info("[RADMIN]: UpdateUserAccount: request complete"); } } @@ -1474,7 +1644,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController GetSceneFromRegionParams(requestData, responseData, out scene); string filename = (string) requestData["filename"]; - + bool mergeOar = false; bool skipAssets = false; @@ -1488,7 +1658,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController } IRegionArchiverModule archiver = scene.RequestModuleInterface(); - Dictionary archiveOptions = new Dictionary(); + Dictionary archiveOptions = new Dictionary(); if (mergeOar) archiveOptions.Add("merge", null); if (skipAssets) archiveOptions.Add("skipAssets", null); if (archiver != null) @@ -1601,7 +1771,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController scene.EventManager.OnOarFileSaved += RemoteAdminOarSaveCompleted; m_log.InfoFormat( - "[RADMIN]: Submitting save OAR request for {0} to file {1}, request ID {2}", + "[RADMIN]: Submitting save OAR request for {0} to file {1}, request ID {2}", scene.Name, filename, requestId); archiver.ArchiveRegion(filename, requestId, options); @@ -1748,21 +1918,31 @@ namespace OpenSim.ApplicationPlugins.RemoteController private void XmlRpcRegionQueryMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { - m_log.Info("[RADMIN]: Received Query XML Administrator Request"); - Hashtable responseData = (Hashtable)response.Value; Hashtable requestData = (Hashtable)request.Params[0]; + int flags = 0; + string text = String.Empty; + int health = 0; + responseData["success"] = true; + CheckRegionParams(requestData, responseData); Scene scene = null; - GetSceneFromRegionParams(requestData, responseData, out scene); - - int health = scene.GetHealth(); - responseData["health"] = health; + try + { + GetSceneFromRegionParams(requestData, responseData, out scene); + health = scene.GetHealth(out flags, out text); + } + catch (Exception e) + { + responseData["error"] = null; + } responseData["success"] = true; - m_log.Info("[RADMIN]: Query XML Administrator Request complete"); + responseData["health"] = health; + responseData["flags"] = flags; + responseData["message"] = text; } private void XmlRpcConsoleCommandMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) @@ -1938,8 +2118,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController Hashtable responseData = (Hashtable)response.Value; // Hashtable requestData = (Hashtable)request.Params[0]; - m_application.SceneManager.ForEachScene(s => - s.RegionInfo.EstateSettings = m_application.EstateDataService.LoadEstateSettings(s.RegionInfo.RegionID, false) + m_application.SceneManager.ForEachScene(s => + s.RegionInfo.EstateSettings = m_application.EstateDataService.LoadEstateSettings(s.RegionInfo.RegionID, false) ); responseData["success"] = true; @@ -2071,7 +2251,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController { Hashtable requestData = (Hashtable)request.Params[0]; Hashtable responseData = (Hashtable)response.Value; - string musicURL = string.Empty; UUID groupID = UUID.Zero; uint flags = 0; @@ -2081,41 +2260,129 @@ namespace OpenSim.ApplicationPlugins.RemoteController set_group = UUID.TryParse(requestData["group"].ToString(), out groupID); if (requestData.Contains("music") && requestData["music"] != null) { + musicURL = requestData["music"].ToString(); set_music = true; } + if (requestData.Contains("flags") && requestData["flags"] != null) set_flags = UInt32.TryParse(requestData["flags"].ToString(), out flags); - m_log.InfoFormat("[RADMIN]: Received Reset Land Request group={0} musicURL={1} flags={2}", - (set_group ? groupID.ToString() : "unchanged"), - (set_music ? musicURL : "unchanged"), + m_log.InfoFormat("[RADMIN]: Received Reset Land Request group={0} musicURL={1} flags={2}", + (set_group ? groupID.ToString() : "unchanged"), + (set_music ? musicURL : "unchanged"), (set_flags ? flags.ToString() : "unchanged")); - m_application.SceneManager.ForEachScene(delegate(Scene s) + m_application.SceneManager.ForEachScene(delegate (Scene s) { List parcels = s.LandChannel.AllParcels(); foreach (ILandObject p in parcels) { if (set_music) p.LandData.MusicURL = musicURL; - if (set_group) p.LandData.GroupID = groupID; - if (set_flags) p.LandData.Flags = flags; - s.LandChannel.UpdateLandObject(p.LandData.LocalID, p.LandData); } } ); + responseData["success"] = true; + m_log.Info("[RADMIN]: Reset Land Request complete"); + } + + private void XmlRpcRefreshSearch(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Refresh Search Request"); + + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; + + CheckRegionParams(requestData, responseData); + + Scene scene = null; + GetSceneFromRegionParams(requestData, responseData, out scene); + + ISearchModule searchModule = scene.RequestModuleInterface(); + if (searchModule != null) + { + searchModule.Refresh(); + responseData["success"] = true; + } + else + { + responseData["success"] = false; + } + m_log.Info("[RADMIN]: Refresh Search Request complete"); + } + + private void XmlRpcRefreshMap(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Refresh Map Request"); + + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; + + CheckRegionParams(requestData, responseData); + + Scene scene = null; + GetSceneFromRegionParams(requestData, responseData, out scene); + + IMapImageUploadModule mapTileModule = scene.RequestModuleInterface(); + if (mapTileModule != null) + { + Util.FireAndForget((x) => + { + mapTileModule.UploadMapTile(scene); + }); + responseData["success"] = true; + } + else + { + responseData["success"] = false; + } + + m_log.Info("[RADMIN]: Refresh Map Request complete"); + } + + private void XmlRpcGetOpenSimVersion(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Get OpenSim Version Request"); + + Hashtable responseData = (Hashtable)response.Value; + + responseData["version"] = m_openSimVersion; responseData["success"] = true; - m_log.Info("[RADMIN]: Reset Land Request complete"); + m_log.Info("[RADMIN]: Get OpenSim Version Request complete"); } + private void XmlRpcGetAgentCount(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Get Agent Count Request"); + + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; + + CheckRegionParams(requestData, responseData); + + Scene scene = null; + GetSceneFromRegionParams(requestData, responseData, out scene); + + if (scene == null) + { + responseData["success"] = false; + } + else + { + responseData["count"] = scene.GetRootAgentCount(); + responseData["success"] = true; + } + + m_log.Info("[RADMIN]: Get Agent Count Request complete"); + } /// /// Parse a float with the given parameter name from a request data hash table. @@ -2584,7 +2851,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController if (destinationFolder.Type != (short)FolderType.Clothing) { destinationFolder = new InventoryFolderBase(); - + destinationFolder.ID = UUID.Random(); destinationFolder.Name = "Clothing"; destinationFolder.Owner = destination; @@ -2605,8 +2872,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController if (wearable[0].ItemID != UUID.Zero) { // Get inventory item and copy it - InventoryItemBase item = new InventoryItemBase(wearable[0].ItemID, source); - item = inventoryService.GetItem(item); + InventoryItemBase item = inventoryService.GetItem(source, wearable[0].ItemID); if (item != null) { @@ -2659,8 +2925,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController if (itemID != UUID.Zero) { // Get inventory item and copy it - InventoryItemBase item = new InventoryItemBase(itemID, source); - item = inventoryService.GetItem(item); + InventoryItemBase item = inventoryService.GetItem(source, itemID); if (item != null) { @@ -2722,11 +2987,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController { sourceFolder = new InventoryFolderBase(); sourceFolder.ID = UUID.Random(); - if (assetType == FolderType.Clothing) + if (assetType == FolderType.Clothing) { sourceFolder.Name = "Clothing"; - } - else + } + else { sourceFolder.Name = "Body Parts"; } @@ -2873,6 +3138,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController if (File.Exists(defaultAppearanceFileName)) { XmlDocument doc = new XmlDocument(); + doc.XmlResolver=null; string name = "*unknown*"; string email = "anon@anon"; uint regionXLocation = 1000; @@ -2939,7 +3205,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController // Set home position - GridRegion home = scene.GridService.GetRegionByPosition(scopeID, + GridRegion home = scene.GridService.GetRegionByPosition(scopeID, (int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation)); if (null == home) { m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", names[0], names[1]); diff --git a/OpenSim/Capabilities/Caps.cs b/OpenSim/Capabilities/Caps.cs index 049afab..7492602 100644 --- a/OpenSim/Capabilities/Caps.cs +++ b/OpenSim/Capabilities/Caps.cs @@ -30,6 +30,7 @@ using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; +using System.Threading; using log4net; using Nini.Config; using OpenMetaverse; @@ -63,7 +64,7 @@ namespace OpenSim.Framework.Capabilities private CapsHandlers m_capsHandlers; - private Dictionary m_pollServiceHandlers + private Dictionary m_pollServiceHandlers = new Dictionary(); private Dictionary m_externalCapsHandlers = new Dictionary(); @@ -71,6 +72,7 @@ namespace OpenSim.Framework.Capabilities private IHttpServer m_httpListener; private UUID m_agentID; private string m_regionName; + private ManualResetEvent m_capsActive = new ManualResetEvent(false); public UUID AgentID { @@ -134,8 +136,14 @@ namespace OpenSim.Framework.Capabilities } m_agentID = agent; - m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL); + m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort); m_regionName = regionName; + m_capsActive.Reset(); + } + + ~Caps() + { + m_capsActive.Dispose(); } /// @@ -152,7 +160,7 @@ namespace OpenSim.Framework.Capabilities public void RegisterPollHandler(string capName, PollServiceEventArgs pollServiceHandler) { // m_log.DebugFormat( -// "[CAPS]: Registering handler with name {0}, url {1} for {2}", +// "[CAPS]: Registering handler with name {0}, url {1} for {2}", // capName, pollServiceHandler.Url, m_agentID, m_regionName); m_pollServiceHandlers.Add(capName, pollServiceHandler); @@ -162,7 +170,7 @@ namespace OpenSim.Framework.Capabilities // uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port; // string protocol = "http"; // string hostName = m_httpListenerHostName; -// +// // if (MainServer.Instance.UseSSL) // { // hostName = MainServer.Instance.SSLCommonName; @@ -230,7 +238,7 @@ namespace OpenSim.Framework.Capabilities string hostName = m_httpListenerHostName; uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port; string protocol = "http"; - + if (MainServer.Instance.UseSSL) { hostName = MainServer.Instance.SSLCommonName; @@ -255,5 +263,16 @@ namespace OpenSim.Framework.Capabilities return caps; } + + public void Activate() + { + m_capsActive.Set(); + } + + public bool WaitForActivation() + { + // Wait for 30s. If that elapses, return false and run without caps + return m_capsActive.WaitOne(120000); + } } } \ No newline at end of file diff --git a/OpenSim/Capabilities/CapsHandlers.cs b/OpenSim/Capabilities/CapsHandlers.cs index 890df90..f5a40df 100644 --- a/OpenSim/Capabilities/CapsHandlers.cs +++ b/OpenSim/Capabilities/CapsHandlers.cs @@ -53,31 +53,15 @@ namespace OpenSim.Framework.Capabilities /// base HTTP server /// host name of the HTTP server /// HTTP port - public CapsHandlers(BaseHttpServer httpListener, string httpListenerHostname, uint httpListenerPort) - : this(httpListener,httpListenerHostname,httpListenerPort, false) - { - } - - /// - /// CapsHandlers is a cap handler container but also takes - /// care of adding and removing cap handlers to and from the - /// supplied BaseHttpServer. - /// - /// base HTTP server - /// host name of the HTTP - /// server - /// HTTP port - public CapsHandlers(IHttpServer httpListener, string httpListenerHostname, uint httpListenerPort, bool https) - { + public CapsHandlers(IHttpServer httpListener, string httpListenerHostname, uint httpListenerPort) + { m_httpListener = httpListener; m_httpListenerHostName = httpListenerHostname; m_httpListenerPort = httpListenerPort; - m_useSSL = https; - if (httpListener != null && m_useSSL) - { - m_httpListenerHostName = httpListener.SSLCommonName; - m_httpListenerPort = httpListener.SSLPort; - } + if (httpListener != null && httpListener.UseSSL) + m_useSSL = true; + else + m_useSSL = false; } /// @@ -90,6 +74,7 @@ namespace OpenSim.Framework.Capabilities lock (m_capsHandlers) { m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path); + m_httpListener.RemoveStreamHandler("PUT", m_capsHandlers[capsName].Path); m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path); m_capsHandlers.Remove(capsName); } @@ -127,9 +112,9 @@ namespace OpenSim.Framework.Capabilities m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[idx].Path); m_capsHandlers.Remove(idx); } - + if (null == value) return; - + m_capsHandlers[idx] = value; m_httpListener.AddStreamHandler(value); } @@ -162,7 +147,7 @@ namespace OpenSim.Framework.Capabilities { Hashtable caps = new Hashtable(); string protocol = "http://"; - + if (m_useSSL) protocol = "https://"; diff --git a/OpenSim/Capabilities/Handlers/AvatarPickerSearch/AvatarPickerSearchHandler.cs b/OpenSim/Capabilities/Handlers/AvatarPickerSearch/AvatarPickerSearchHandler.cs index 426174d..5163169 100644 --- a/OpenSim/Capabilities/Handlers/AvatarPickerSearch/AvatarPickerSearchHandler.cs +++ b/OpenSim/Capabilities/Handlers/AvatarPickerSearch/AvatarPickerSearchHandler.cs @@ -74,7 +74,7 @@ namespace OpenSim.Capabilities.Handlers int page_size = (string.IsNullOrEmpty(psize) ? 500 : Int32.Parse(psize)); int page_number = (string.IsNullOrEmpty(pnumber) ? 1 : Int32.Parse(pnumber)); - + // Full content request httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK; //httpResponse.ContentLength = ??; diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs index 7197049..53ed115 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs @@ -43,7 +43,7 @@ using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Capabilities.Handlers { - public class FetchInvDescHandler + public class FetchInvDescHandler { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -53,14 +53,14 @@ namespace OpenSim.Capabilities.Handlers private IScene m_Scene; // private object m_fetchLock = new Object(); - public FetchInvDescHandler(IInventoryService invService, ILibraryService libService, IScene s) + public FetchInvDescHandler(IInventoryService invService, ILibraryService libService, IScene s) { m_InventoryService = invService; m_LibraryService = libService; m_Scene = s; } - + public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { //m_log.DebugFormat("[XXX]: FetchInventoryDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request); @@ -72,14 +72,14 @@ namespace OpenSim.Capabilities.Handlers // correctly mark it as a uuid // request = request.Replace("00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000"); - + // another hack 1 results in a // System.ArgumentException: Object type System.Int32 cannot // be converted to target type: System.Boolean // request = request.Replace("fetch_folders0", "fetch_folders0"); request = request.Replace("fetch_folders1", "fetch_folders1"); - + Hashtable hash = new Hashtable(); try { @@ -90,9 +90,9 @@ namespace OpenSim.Capabilities.Handlers m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace); m_log.Error("Request: " + request); } - + ArrayList foldersrequested = (ArrayList)hash["folders"]; - + string response = ""; string bad_folders_response = ""; @@ -403,10 +403,7 @@ namespace OpenSim.Capabilities.Handlers return contents; } contents = fetchedContents; - InventoryFolderBase containingFolder = new InventoryFolderBase(); - containingFolder.ID = folderID; - containingFolder.Owner = agentID; - containingFolder = m_InventoryService.GetFolder(containingFolder); + InventoryFolderBase containingFolder = m_InventoryService.GetFolder(agentID, folderID); if (containingFolder != null) { @@ -416,7 +413,7 @@ namespace OpenSim.Capabilities.Handlers version = containingFolder.Version; - if (fetchItems) + if (fetchItems && containingFolder.Type != (short)FolderType.Trash) { List itemsToReturn = contents.Items; List originalItems = new List(itemsToReturn); @@ -429,7 +426,7 @@ namespace OpenSim.Capabilities.Handlers { if (item.AssetType == (int)AssetType.Link) { - InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID)); + InventoryItemBase linkedItem = m_InventoryService.GetItem(agentID, item.AssetID); // Take care of genuinely broken links where the target doesn't exist // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, @@ -441,6 +438,10 @@ namespace OpenSim.Capabilities.Handlers } // Now scan for folder links and insert the items they target and those links at the head of the return data + +/* dont send contents of LinkFolders. +from docs seems this was never a spec + foreach (InventoryItemBase item in originalItems) { if (item.AssetType == (int)AssetType.LinkFolder) @@ -471,6 +472,7 @@ namespace OpenSim.Capabilities.Handlers } } } +*/ } // foreach (InventoryItemBase item in contents.Items) @@ -514,7 +516,7 @@ namespace OpenSim.Capabilities.Handlers // } // } // } -// +// // foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend) // { // m_log.DebugFormat( @@ -654,10 +656,7 @@ namespace OpenSim.Capabilities.Handlers // Must fetch it individually else if (contents.FolderID == UUID.Zero) { - InventoryFolderBase containingFolder = new InventoryFolderBase(); - containingFolder.ID = freq.folder_id; - containingFolder.Owner = freq.owner_id; - containingFolder = m_InventoryService.GetFolder(containingFolder); + InventoryFolderBase containingFolder = m_InventoryService.GetFolder(freq.owner_id, freq.folder_id); if (containingFolder != null) { @@ -723,8 +722,8 @@ namespace OpenSim.Capabilities.Handlers if (item.AssetType == (int)AssetType.Link) itemIDs.Add(item.AssetID); - else if (item.AssetType == (int)AssetType.LinkFolder) - folderIDs.Add(item.AssetID); +// else if (item.AssetType == (int)AssetType.LinkFolder) +// folderIDs.Add(item.AssetID); } //m_log.DebugFormat("[XXX]: folder {0} has {1} links and {2} linkfolders", contents.FolderID, itemIDs.Count, folderIDs.Count); @@ -754,12 +753,9 @@ namespace OpenSim.Capabilities.Handlers m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: GetMultipleItems failed. Falling back to fetching inventory items one by one."); linked = new InventoryItemBase[itemIDs.Count]; int i = 0; - InventoryItemBase item = new InventoryItemBase(); - item.Owner = freq.owner_id; foreach (UUID id in itemIDs) { - item.ID = id; - linked[i++] = m_InventoryService.GetItem(item); + linked[i++] = m_InventoryService.GetItem(freq.owner_id, id); } } @@ -845,4 +841,4 @@ namespace OpenSim.Capabilities.Handlers public InventoryCollection Collection; public int Descendents; } -} \ No newline at end of file +} diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs index c904392..e239a90 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs @@ -64,27 +64,33 @@ namespace OpenSim.Capabilities.Handlers UUID[] itemIDs = new UUID[itemsRequested.Count]; int i = 0; + foreach (OSDMap osdItemId in itemsRequested) { itemIDs[i++] = osdItemId["item_id"].AsUUID(); } - InventoryItemBase[] items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs); + InventoryItemBase[] items = null; - if (items == null) + if (m_agentID != UUID.Zero) { - // OMG!!! One by one!!! This is fallback code, in case the backend isn't updated - m_log.WarnFormat("[FETCH INVENTORY HANDLER]: GetMultipleItems failed. Falling back to fetching inventory items one by one."); - items = new InventoryItemBase[itemsRequested.Count]; - i = 0; - InventoryItemBase item = new InventoryItemBase(); - item.Owner = m_agentID; - foreach (UUID id in itemIDs) + items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs); + + if (items == null) { - item.ID = id; - items[i++] = m_inventoryService.GetItem(item); + // OMG!!! One by one!!! This is fallback code, in case the backend isn't updated + m_log.WarnFormat("[FETCH INVENTORY HANDLER]: GetMultipleItems failed. Falling back to fetching inventory items one by one."); + items = new InventoryItemBase[itemsRequested.Count]; + foreach (UUID id in itemIDs) + items[i++] = m_inventoryService.GetItem(m_agentID, id); } } + else + { + items = new InventoryItemBase[itemsRequested.Count]; + foreach (UUID id in itemIDs) + items[i++] = m_inventoryService.GetItem(UUID.Zero, id); + } foreach (InventoryItemBase item in items) { @@ -93,7 +99,6 @@ namespace OpenSim.Capabilities.Handlers // We don't know the agent that this request belongs to so we'll use the agent id of the item // which will be the same for all items. llsdReply.agent_id = item.Owner; - llsdReply.items.Array.Add(ConvertInventoryItem(item)); } } @@ -114,7 +119,7 @@ namespace OpenSim.Capabilities.Handlers llsdItem.asset_id = invItem.AssetID; llsdItem.created_at = invItem.CreationDate; llsdItem.desc = invItem.Description; - llsdItem.flags = (int)invItem.Flags; + llsdItem.flags = ((int)invItem.Flags) & 0xff; llsdItem.item_id = invItem.ID; llsdItem.name = invItem.Name; llsdItem.parent_id = invItem.Folder; @@ -138,4 +143,4 @@ namespace OpenSim.Capabilities.Handlers return llsdItem; } } -} \ No newline at end of file +} diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2ServerConnector.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2ServerConnector.cs new file mode 100644 index 0000000..618f075 --- /dev/null +++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2ServerConnector.cs @@ -0,0 +1,71 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using Nini.Config; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; +using OpenMetaverse; + +namespace OpenSim.Capabilities.Handlers +{ + public class FetchInventory2ServerConnector : ServiceConnector + { + private IInventoryService m_InventoryService; + private string m_ConfigName = "CapsService"; + + public FetchInventory2ServerConnector(IConfigSource config, IHttpServer server, string configName) + : base(config, server, configName) + { + if (configName != String.Empty) + m_ConfigName = configName; + + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName)); + + string invService = serverConfig.GetString("InventoryService", String.Empty); + + if (invService == String.Empty) + throw new Exception("No InventoryService in config file"); + + Object[] args = new Object[] { config }; + m_InventoryService = ServerUtils.LoadPlugin(invService, args); + + if (m_InventoryService == null) + throw new Exception(String.Format("Failed to load InventoryService from {0}; config is {1}", invService, m_ConfigName)); + + FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService, UUID.Zero); + IRequestHandler reqHandler + = new RestStreamHandler( + "POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest, "FetchInventory", null); + server.AddStreamHandler(reqHandler); + } + } +} diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventory2HandlerTests.cs b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventory2HandlerTests.cs index 8af3c64..94c2c89 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventory2HandlerTests.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventory2HandlerTests.cs @@ -120,7 +120,7 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests string request = "itemsitem_id"; request += "10000000-0000-0000-0000-000000000001"; // Notecard 1 request += ""; - + string llsdresponse = handler.FetchInventoryRequest(request, "/FETCH", string.Empty, req, resp); Assert.That(llsdresponse != null, Is.True, "Incorrect null response"); diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs index 2d5531a..4143aa3 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs @@ -140,7 +140,7 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests string request = "foldersfetch_folders1fetch_items1folder_id"; request += m_rootFolderID; request += "owner_id00000000-0000-0000-0000-000000000000sort_order1"; - + string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp); Assert.That(llsdresponse != null, Is.True, "Incorrect null response"); @@ -203,7 +203,7 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests // Make sure that the note card link is included Assert.That(llsdresponse.Contains("Link to notecard"), Is.True, "Link to notecard is missing"); - + //Make sure the notecard item itself is included Assert.That(llsdresponse.Contains("Test Notecard 2"), Is.True, "Notecard 2 item (the source) is missing"); @@ -215,10 +215,11 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests // Make sure the folder link is included Assert.That(llsdresponse.Contains("Link to Objects folder"), Is.True, "Link to Objects folder is missing"); +/* contents of link folder are not supposed to be listed // Make sure the objects inside the Objects folder are included // Note: I'm not entirely sure this is needed, but that's what I found in the implementation Assert.That(llsdresponse.Contains("Some Object"), Is.True, "Some Object item (contents of the source) is missing"); - +*/ // Make sure that the source item is before the link item pos1 = llsdresponse.IndexOf("Some Object"); pos2 = llsdresponse.IndexOf("Link to Objects folder"); diff --git a/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesHandler.cs b/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesHandler.cs index 589602d..41cfdb6 100644 --- a/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesHandler.cs @@ -29,8 +29,6 @@ using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; -using System.Drawing; -using System.Drawing.Imaging; using System.Reflection; using System.IO; using System.Web; @@ -38,12 +36,7 @@ using log4net; using Nini.Config; using OpenMetaverse; using OpenMetaverse.StructuredData; -using OpenMetaverse.Imaging; -using OpenSim.Framework; -using OpenSim.Framework.Capabilities; -using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; -using OpenSim.Region.Framework.Interfaces; using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; using OSDMap = OpenMetaverse.StructuredData.OSDMap; @@ -55,7 +48,7 @@ namespace OpenSim.Capabilities.Handlers { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private IUserManagement m_UserManagement; + protected IUserManagement m_UserManagement; public GetDisplayNamesHandler(string path, IUserManagement umService, string name, string description) : base("GET", path, name, description) @@ -65,12 +58,11 @@ namespace OpenSim.Capabilities.Handlers protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - m_log.DebugFormat("[GET_DISPLAY_NAMES]: called {0}", httpRequest.Url.Query); +// m_log.DebugFormat("[GET_DISPLAY_NAMES]: called {0}", httpRequest.Url.Query); NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); string[] ids = query.GetValues("ids"); - if (m_UserManagement == null) { m_log.Error("[GET_DISPLAY_NAMES]: Cannot fetch display names without a user management component"); @@ -78,32 +70,39 @@ namespace OpenSim.Capabilities.Handlers return new byte[0]; } + Dictionary names = m_UserManagement.GetUsersNames(ids); + OSDMap osdReply = new OSDMap(); OSDArray agents = new OSDArray(); osdReply["agents"] = agents; - foreach (string id in ids) + foreach (KeyValuePair kvp in names) { - UUID uuid = UUID.Zero; - if (UUID.TryParse(id, out uuid)) - { - string name = m_UserManagement.GetUserName(uuid); - if (!string.IsNullOrEmpty(name)) - { - string[] parts = name.Split(new char[] {' '}); - OSDMap osdname = new OSDMap(); - osdname["display_name_next_update"] = OSD.FromDate(DateTime.MinValue); - osdname["display_name_expires"] = OSD.FromDate(DateTime.Now.AddMonths(1)); - osdname["display_name"] = OSD.FromString(name); - osdname["legacy_first_name"] = parts[0]; - osdname["legacy_last_name"] = parts[1]; - osdname["username"] = OSD.FromString(name); - osdname["id"] = OSD.FromUUID(uuid); - osdname["is_display_name_default"] = OSD.FromBoolean(true); + if (string.IsNullOrEmpty(kvp.Value)) + continue; + if(kvp.Key == UUID.Zero) + continue; - agents.Add(osdname); - } + string[] parts = kvp.Value.Split(new char[] {' '}); + OSDMap osdname = new OSDMap(); + if(parts[0] == "Unknown") + { + osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddHours(1)); + osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddHours(2)); } + else + { + osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddDays(8)); + osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddMonths(1)); + } + osdname["display_name"] = OSD.FromString(kvp.Value); + osdname["legacy_first_name"] = parts[0]; + osdname["legacy_last_name"] = parts[1]; + osdname["username"] = OSD.FromString(kvp.Value); + osdname["id"] = OSD.FromUUID(kvp.Key); + osdname["is_display_name_default"] = OSD.FromBoolean(true); + + agents.Add(osdname); } // Full content request @@ -113,8 +112,6 @@ namespace OpenSim.Capabilities.Handlers string reply = OSDParser.SerializeLLSDXmlString(osdReply); return System.Text.Encoding.UTF8.GetBytes(reply); - } - } -} \ No newline at end of file +} diff --git a/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesServerConnector.cs b/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesServerConnector.cs index d42de56..32da1c2 100644 --- a/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesServerConnector.cs @@ -62,8 +62,6 @@ namespace OpenSim.Capabilities.Handlers if (m_UserManagement == null) throw new Exception(String.Format("Failed to load UserManagement from {0}; config is {1}", umService, m_ConfigName)); - string rurl = serverConfig.GetString("GetTextureRedirectURL"); - server.AddStreamHandler( new GetDisplayNamesHandler("/CAPS/agents/", m_UserManagement, "GetDisplayNames", null)); } diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs index 6b67da1..a9b81f3 100644 --- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs @@ -25,224 +25,242 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Reflection; +using System.IO; +using System.Web; using log4net; +using Nini.Config; using OpenMetaverse; -using OpenMetaverse.Imaging; +using OpenMetaverse.StructuredData; using OpenSim.Framework; +using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Services.Interfaces; -using System; -using System.Collections.Specialized; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Reflection; -using System.Web; +using Caps = OpenSim.Framework.Capabilities.Caps; + + + namespace OpenSim.Capabilities.Handlers { - public class GetMeshHandler : BaseStreamHandler + public class GetMeshHandler { private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private IAssetService m_assetService; - // TODO: Change this to a config option - private string m_RedirectURL = null; + public const string DefaultFormat = "vnd.ll.mesh"; - public GetMeshHandler(string path, IAssetService assService, string name, string description, string redirectURL) - : base("GET", path, name, description) + public GetMeshHandler(IAssetService assService) { m_assetService = assService; - m_RedirectURL = redirectURL; - if (m_RedirectURL != null && !m_RedirectURL.EndsWith("/")) - m_RedirectURL += "/"; } - - protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + public Hashtable Handle(Hashtable request) { - // Try to parse the texture ID from the request URL - NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); - string textureStr = query.GetOne("mesh_id"); + Hashtable ret = new Hashtable(); + ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; + ret["content_type"] = "text/plain"; + ret["keepalive"] = false; + ret["reusecontext"] = false; + ret["int_bytes"] = 0; + ret["int_lod"] = 0; + string MeshStr = (string)request["mesh_id"]; + + + //m_log.DebugFormat("[GETMESH]: called {0}", MeshStr); if (m_assetService == null) { - m_log.Error("[GETMESH]: Cannot fetch mesh " + textureStr + " without an asset service"); - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service"); } UUID meshID; - if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out meshID)) + if (!String.IsNullOrEmpty(MeshStr) && UUID.TryParse(MeshStr, out meshID)) { - // OK, we have an array with preferred formats, possibly with only one entry - - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - AssetBase mesh; - - if (!String.IsNullOrEmpty(m_RedirectURL)) - { - // Only try to fetch locally cached meshes. Misses are redirected - mesh = m_assetService.GetCached(meshID.ToString()); + // m_log.DebugFormat("[GETMESH]: Received request for mesh id {0}", meshID); - if (mesh != null) - { - if (mesh.Type != (sbyte)AssetType.Mesh) - { - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - } - WriteMeshData(httpRequest, httpResponse, mesh); - } - else - { - string textureUrl = m_RedirectURL + "?mesh_id="+ meshID.ToString(); - m_log.Debug("[GETMESH]: Redirecting mesh request to " + textureUrl); - httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently; - httpResponse.RedirectLocation = textureUrl; - return null; - } - } - else // no redirect - { - // try the cache - mesh = m_assetService.GetCached(meshID.ToString()); - if (mesh == null) - { - // Fetch locally or remotely. Misses return a 404 - mesh = m_assetService.Get(meshID.ToString()); + ret = ProcessGetMesh(request, UUID.Zero, null); - if (mesh != null) - { - if (mesh.Type != (sbyte)AssetType.Mesh) - { - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return null; - } - WriteMeshData(httpRequest, httpResponse, mesh); - return null; - } - } - else // it was on the cache - { - if (mesh.Type != (sbyte)AssetType.Mesh) - { - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return null; - } - WriteMeshData(httpRequest, httpResponse, mesh); - return null; - } - } - // not found - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return null; } else { - m_log.Warn("[GETTEXTURE]: Failed to parse a mesh_id from GetMesh request: " + httpRequest.Url); + m_log.Warn("[GETMESH]: Failed to parse a mesh_id from GetMesh request: " + (string)request["uri"]); } - return null; - } - private void WriteMeshData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture) + return ret; + } + public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap) { - string range = request.Headers.GetOne("Range"); + Hashtable responsedata = new Hashtable(); + responsedata["int_response_code"] = 400; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Request wasn't what was expected"; + responsedata["reusecontext"] = false; + responsedata["int_lod"] = 0; + responsedata["int_bytes"] = 0; + + string meshStr = string.Empty; - if (!String.IsNullOrEmpty(range)) + if (request.ContainsKey("mesh_id")) + meshStr = request["mesh_id"].ToString(); + + UUID meshID = UUID.Zero; + if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID)) { - // Range request - int start, end; - if (TryParseRange(range, out start, out end)) + if (m_assetService == null) { - // Before clamping start make sure we can satisfy it in order to avoid - // sending back the last byte instead of an error status - if (start >= texture.Data.Length) - { - response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; - response.ContentType = texture.Metadata.ContentType; - } - else + responsedata["int_response_code"] = 404; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; + responsedata["reusecontext"] = false; + return responsedata; + } + + AssetBase mesh = m_assetService.Get(meshID.ToString()); + + if (mesh != null) + { + if (mesh.Type == (SByte)AssetType.Mesh) { - // Handle the case where no second range value was given. This is equivalent to requesting - // the rest of the entity. - if (end == -1) - end = int.MaxValue; - end = Utils.Clamp(end, 0, texture.Data.Length - 1); - start = Utils.Clamp(start, 0, end); - int len = end - start + 1; + Hashtable headers = new Hashtable(); + responsedata["headers"] = headers; + + string range = String.Empty; + + if (((Hashtable)request["headers"])["range"] != null) + range = (string)((Hashtable)request["headers"])["range"]; - if (0 == start && len == texture.Data.Length) + else if (((Hashtable)request["headers"])["Range"] != null) + range = (string)((Hashtable)request["headers"])["Range"]; + + if (!String.IsNullOrEmpty(range)) // Mesh Asset LOD // Physics { - response.StatusCode = (int)System.Net.HttpStatusCode.OK; + // Range request + int start, end; + if (TryParseRange(range, out start, out end)) + { + // Before clamping start make sure we can satisfy it in order to avoid + // sending back the last byte instead of an error status + if (start >= mesh.Data.Length) + { + responsedata["int_response_code"] = 404; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "This range doesnt exist."; + responsedata["reusecontext"] = false; + responsedata["int_lod"] = 3; + return responsedata; + } + else + { + end = Utils.Clamp(end, 0, mesh.Data.Length - 1); + start = Utils.Clamp(start, 0, end); + int len = end - start + 1; + + //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); + + if (start > 20000) + { + responsedata["int_lod"] = 3; + } + else if (start < 4097) + { + responsedata["int_lod"] = 1; + } + else + { + responsedata["int_lod"] = 2; + } + + + if (start == 0 && len == mesh.Data.Length) // well redudante maybe + { + responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK; + responsedata["bin_response_data"] = mesh.Data; + responsedata["int_bytes"] = mesh.Data.Length; + responsedata["reusecontext"] = false; + responsedata["int_lod"] = 3; + + } + else + { + responsedata["int_response_code"] = + (int)System.Net.HttpStatusCode.PartialContent; + headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, + mesh.Data.Length); + + byte[] d = new byte[len]; + Array.Copy(mesh.Data, start, d, 0, len); + responsedata["bin_response_data"] = d; + responsedata["int_bytes"] = len; + responsedata["reusecontext"] = false; + } + } + } + else + { + m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]); + responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); + responsedata["content_type"] = "application/vnd.ll.mesh"; + responsedata["int_response_code"] = 200; + responsedata["reusecontext"] = false; + responsedata["int_lod"] = 3; + } } else { - response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; - response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length)); + responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); + responsedata["content_type"] = "application/vnd.ll.mesh"; + responsedata["int_response_code"] = 200; + responsedata["reusecontext"] = false; + responsedata["int_lod"] = 3; } - - response.ContentLength = len; - response.ContentType = "application/vnd.ll.mesh"; - - response.Body.Write(texture.Data, start, len); + } + // Optionally add additional mesh types here + else + { + responsedata["int_response_code"] = 404; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; + responsedata["reusecontext"] = false; + responsedata["int_lod"] = 1; + return responsedata; } } else { - m_log.Warn("[GETMESH]: Malformed Range header: " + range); - response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest; + responsedata["int_response_code"] = 404; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; + responsedata["reusecontext"] = false; + responsedata["int_lod"] = 0; + return responsedata; } } - else - { - // Full content request - response.StatusCode = (int)System.Net.HttpStatusCode.OK; - response.ContentLength = texture.Data.Length; - response.ContentType = "application/vnd.ll.mesh"; - response.Body.Write(texture.Data, 0, texture.Data.Length); - } - } - /// - /// Parse a range header. - /// - /// - /// As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, - /// this obeys range headers with two values (e.g. 533-4165) and no second value (e.g. 533-). - /// Where there is no value, -1 is returned. - /// FIXME: Need to cover the case where only a second value is specified (e.g. -4165), probably by returning -1 - /// for start. - /// - /// - /// Start of the range. Undefined if this was not a number. - /// End of the range. Will be -1 if no end specified. Undefined if there was a raw string but this was not a number. + return responsedata; + } private bool TryParseRange(string header, out int start, out int end) { - start = end = 0; - if (header.StartsWith("bytes=")) { string[] rangeValues = header.Substring(6).Split('-'); - if (rangeValues.Length == 2) { - if (!Int32.TryParse(rangeValues[0], out start)) - return false; - - string rawEnd = rangeValues[1]; - - if (rawEnd == "") - { - end = -1; + if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end)) return true; - } - else if (Int32.TryParse(rawEnd, out end)) - { - return true; - } } } diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs index 19de3cf..b494aa4 100644 --- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs @@ -64,13 +64,15 @@ namespace OpenSim.Capabilities.Handlers string rurl = serverConfig.GetString("GetMeshRedirectURL"); - server.AddStreamHandler( - new GetTextureHandler("/CAPS/GetMesh/" /*+ UUID.Random() */, m_AssetService, "GetMesh", null, rurl)); - - rurl = serverConfig.GetString("GetMesh2RedirectURL"); - - server.AddStreamHandler( - new GetTextureHandler("/CAPS/GetMesh2/" /*+ UUID.Random() */, m_AssetService, "GetMesh2", null, rurl)); + GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); + IRequestHandler reqHandler + = new RestHTTPHandler( + "GET", + "/CAPS/" + UUID.Random(), + httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null), + "GetMesh", + null); + server.AddStreamHandler(reqHandler); ; } } } \ No newline at end of file diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index 828e943..e73cf9e 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -47,46 +47,43 @@ using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Capabilities.Handlers { - public class GetTextureHandler : BaseStreamHandler + public class GetTextureHandler { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private IAssetService m_assetService; public const string DefaultFormat = "x-j2c"; - // TODO: Change this to a config option - private string m_RedirectURL = null; - - public GetTextureHandler(string path, IAssetService assService, string name, string description, string redirectURL) - : base("GET", path, name, description) + public GetTextureHandler(IAssetService assService) { m_assetService = assService; - m_RedirectURL = redirectURL; - if (m_RedirectURL != null && !m_RedirectURL.EndsWith("/")) - m_RedirectURL += "/"; } - protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + public Hashtable Handle(Hashtable request) { - // Try to parse the texture ID from the request URL - NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); - string textureStr = query.GetOne("texture_id"); - string format = query.GetOne("format"); + Hashtable ret = new Hashtable(); + ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; + ret["content_type"] = "text/plain"; + ret["keepalive"] = false; + ret["reusecontext"] = false; + ret["int_bytes"] = 0; + string textureStr = (string)request["texture_id"]; + string format = (string)request["format"]; //m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr); if (m_assetService == null) { m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; } UUID textureID; if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID)) { // m_log.DebugFormat("[GETTEXTURE]: Received request for texture id {0}", textureID); - + string[] formats; if (!string.IsNullOrEmpty(format)) { @@ -94,41 +91,52 @@ namespace OpenSim.Capabilities.Handlers } else { - formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept")); + formats = new string[1] { DefaultFormat }; // default + if (((Hashtable)request["headers"])["Accept"] != null) + formats = WebUtil.GetPreferredImageTypes((string)((Hashtable)request["headers"])["Accept"]); if (formats.Length == 0) formats = new string[1] { DefaultFormat }; // default } // OK, we have an array with preferred formats, possibly with only one entry - - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + bool foundtexture = false; foreach (string f in formats) { - if (FetchTexture(httpRequest, httpResponse, textureID, f)) + foundtexture = FetchTexture(request, ret, textureID, f); + if (foundtexture) break; } + if (!foundtexture) + { + ret["int_response_code"] = 404; + ret["error_status_text"] = "not found"; + ret["str_response_string"] = "not found"; + ret["content_type"] = "text/plain"; + ret["keepalive"] = false; + ret["reusecontext"] = false; + ret["int_bytes"] = 0; + } } else { - m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url); + m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + (string)request["uri"]); } // m_log.DebugFormat( // "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}", // textureID, httpResponse.StatusCode, httpResponse.ContentLength); - - return null; + return ret; } /// - /// + /// /// /// /// /// /// /// False for "caller try another codec"; true otherwise - private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format) + private bool FetchTexture(Hashtable request, Hashtable response, UUID textureID, string format) { // m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format); AssetBase texture; @@ -137,86 +145,70 @@ namespace OpenSim.Capabilities.Handlers if (format != DefaultFormat) fullID = fullID + "-" + format; - if (!String.IsNullOrEmpty(m_RedirectURL)) + // try the cache + texture = m_assetService.GetCached(fullID); + + if (texture == null) { - // Only try to fetch locally cached textures. Misses are redirected - texture = m_assetService.GetCached(fullID); + //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache"); + + // Fetch locally or remotely. Misses return a 404 + texture = m_assetService.Get(textureID.ToString()); if (texture != null) { if (texture.Type != (sbyte)AssetType.Texture) + return true; + + if (format == DefaultFormat) { - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + WriteTextureData(request, response, texture, format); + return true; + } + else + { + AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID); + newTexture.Data = ConvertTextureData(texture, format); + if (newTexture.Data.Length == 0) + return false; // !!! Caller try another codec, please! + + newTexture.Flags = AssetFlags.Collectable; + newTexture.Temporary = true; + newTexture.Local = true; + m_assetService.Store(newTexture); + WriteTextureData(request, response, newTexture, format); return true; } - WriteTextureData(httpRequest, httpResponse, texture, format); - } - else - { - string textureUrl = m_RedirectURL + "?texture_id="+ textureID.ToString(); - m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl); - httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently; - httpResponse.RedirectLocation = textureUrl; - return true; } - } - else // no redirect - { - // try the cache - texture = m_assetService.GetCached(fullID); + } + else // it was on the cache + { + //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); + WriteTextureData(request, response, texture, format); + return true; + } - if (texture == null) - { -// m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache"); - - // Fetch locally or remotely. Misses return a 404 - texture = m_assetService.Get(textureID.ToString()); + //response = new Hashtable(); - if (texture != null) - { - if (texture.Type != (sbyte)AssetType.Texture) - { - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return true; - } - if (format == DefaultFormat) - { - WriteTextureData(httpRequest, httpResponse, texture, format); - return true; - } - else - { - AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID); - newTexture.Data = ConvertTextureData(texture, format); - if (newTexture.Data.Length == 0) - return false; // !!! Caller try another codec, please! - - newTexture.Flags = AssetFlags.Collectable; - newTexture.Temporary = true; - newTexture.Local = true; - m_assetService.Store(newTexture); - WriteTextureData(httpRequest, httpResponse, newTexture, format); - return true; - } - } - } - else // it was on the cache - { -// m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); - WriteTextureData(httpRequest, httpResponse, texture, format); - return true; - } - } + //WriteTextureData(request,response,null,format); // not found -// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return true; + //m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); + return false; } - private void WriteTextureData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture, string format) + private void WriteTextureData(Hashtable request, Hashtable response, AssetBase texture, string format) { - string range = request.Headers.GetOne("Range"); + Hashtable headers = new Hashtable(); + response["headers"] = headers; + + string range = String.Empty; + + if (((Hashtable)request["headers"])["range"] != null) + range = (string)((Hashtable)request["headers"])["range"]; + + else if (((Hashtable)request["headers"])["Range"] != null) + range = (string)((Hashtable)request["headers"])["Range"]; if (!String.IsNullOrEmpty(range)) // JP2's only { @@ -244,10 +236,8 @@ namespace OpenSim.Capabilities.Handlers // However, if we return PartialContent (or OK) instead, the viewer will display that resolution. // response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; -// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length)); -// response.StatusCode = (int)System.Net.HttpStatusCode.OK; - response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; - response.ContentType = texture.Metadata.ContentType; + // viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters + response["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; } else { @@ -262,41 +252,46 @@ namespace OpenSim.Capabilities.Handlers // m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); - // Always return PartialContent, even if the range covered the entire data length - // We were accidentally sending back 404 before in this situation - // https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the - // entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this. - // - // We also do not want to send back OK even if the whole range was satisfiable since this causes - // HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality. -// if (end > maxEnd) -// response.StatusCode = (int)System.Net.HttpStatusCode.OK; -// else - response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; - - response.ContentLength = len; - response.ContentType = texture.Metadata.ContentType; - response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length)); - - response.Body.Write(texture.Data, start, len); + response["content-type"] = texture.Metadata.ContentType; + + if (start == 0 && len == texture.Data.Length) // well redudante maybe + { + response["int_response_code"] = (int)System.Net.HttpStatusCode.OK; + response["bin_response_data"] = texture.Data; + response["int_bytes"] = texture.Data.Length; + } + else + { + response["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent; + headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length); + + byte[] d = new byte[len]; + Array.Copy(texture.Data, start, d, 0, len); + response["bin_response_data"] = d; + response["int_bytes"] = len; + } +// response.Body.Write(texture.Data, start, len); } } else { m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range); - response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest; + response["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest; } } else // JP2's or other formats { // Full content request - response.StatusCode = (int)System.Net.HttpStatusCode.OK; - response.ContentLength = texture.Data.Length; + response["int_response_code"] = (int)System.Net.HttpStatusCode.OK; if (format == DefaultFormat) - response.ContentType = texture.Metadata.ContentType; + response["content_type"] = texture.Metadata.ContentType; else - response.ContentType = "image/" + format; - response.Body.Write(texture.Data, 0, texture.Data.Length); + response["content_type"] = "image/" + format; + + response["bin_response_data"] = texture.Data; + response["int_bytes"] = texture.Data.Length; + +// response.Body.Write(texture.Data, 0, texture.Data.Length); } // if (response.StatusCode < 200 || response.StatusCode > 299) @@ -359,36 +354,35 @@ namespace OpenSim.Capabilities.Handlers byte[] data = new byte[0]; MemoryStream imgstream = new MemoryStream(); - Bitmap mTexture = new Bitmap(1, 1); - ManagedImage managedImage; - Image image = (Image)mTexture; + Bitmap mTexture = null; + ManagedImage managedImage = null; + Image image = null; try { // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data - imgstream = new MemoryStream(); - // Decode image to System.Drawing.Image - if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image)) + if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image) && image != null) { // Save to bitmap mTexture = new Bitmap(image); - EncoderParameters myEncoderParameters = new EncoderParameters(); - myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L); - - // Save bitmap to stream - ImageCodecInfo codec = GetEncoderInfo("image/" + format); - if (codec != null) + using(EncoderParameters myEncoderParameters = new EncoderParameters()) { - mTexture.Save(imgstream, codec, myEncoderParameters); + myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,95L); + + // Save bitmap to stream + ImageCodecInfo codec = GetEncoderInfo("image/" + format); + if (codec != null) + { + mTexture.Save(imgstream, codec, myEncoderParameters); // Write the stream to a byte array for output - data = imgstream.ToArray(); + data = imgstream.ToArray(); + } + else + m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format); } - else - m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format); - } } catch (Exception e) @@ -405,11 +399,10 @@ namespace OpenSim.Capabilities.Handlers if (image != null) image.Dispose(); + if(managedImage != null) + managedImage.Clear(); if (imgstream != null) - { - imgstream.Close(); imgstream.Dispose(); - } } return data; @@ -428,4 +421,4 @@ namespace OpenSim.Capabilities.Handlers return null; } } -} \ No newline at end of file +} diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureRobustHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureRobustHandler.cs new file mode 100644 index 0000000..0685c5e --- /dev/null +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureRobustHandler.cs @@ -0,0 +1,394 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Drawing; +using System.Drawing.Imaging; +using System.Reflection; +using System.IO; +using System.Web; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenMetaverse.Imaging; +using OpenSim.Framework; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Services.Interfaces; +using Caps = OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Capabilities.Handlers +{ + public class GetTextureRobustHandler : BaseStreamHandler + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private IAssetService m_assetService; + + public const string DefaultFormat = "x-j2c"; + + // TODO: Change this to a config option + private string m_RedirectURL = null; + + public GetTextureRobustHandler(string path, IAssetService assService, string name, string description, string redirectURL) + : base("GET", path, name, description) + { + m_assetService = assService; + m_RedirectURL = redirectURL; + if (m_RedirectURL != null && !m_RedirectURL.EndsWith("/")) + m_RedirectURL += "/"; + } + + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + { + // Try to parse the texture ID from the request URL + NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); + string textureStr = query.GetOne("texture_id"); + string format = query.GetOne("format"); + + //m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr); + + if (m_assetService == null) + { + m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + return null; + } + + UUID textureID; + if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID)) + { +// m_log.DebugFormat("[GETTEXTURE]: Received request for texture id {0}", textureID); + + string[] formats; + if (!string.IsNullOrEmpty(format)) + { + formats = new string[1] { format.ToLower() }; + } + else + { + formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept")); + if (formats.Length == 0) + formats = new string[1] { DefaultFormat }; // default + + } + // OK, we have an array with preferred formats, possibly with only one entry + + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + foreach (string f in formats) + { + if (FetchTexture(httpRequest, httpResponse, textureID, f)) + break; + } + } + else + { + m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url); + } + +// m_log.DebugFormat( +// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}", +// textureID, httpResponse.StatusCode, httpResponse.ContentLength); + + return null; + } + + /// + /// + /// + /// + /// + /// + /// + /// False for "caller try another codec"; true otherwise + private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format) + { + // m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format); + AssetBase texture; + + if(!String.IsNullOrEmpty(m_RedirectURL)) + { + string textureUrl = m_RedirectURL + "?texture_id=" + textureID.ToString(); + m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl); + httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently; + httpResponse.RedirectLocation = textureUrl; + return true; + } + else // no redirect + { + texture = m_assetService.Get(textureID.ToString()); + if(texture != null) + { + if(texture.Type != (sbyte)AssetType.Texture) + { + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + return true; + } + if(format == DefaultFormat) + { + WriteTextureData(httpRequest, httpResponse, texture, format); + return true; + } + else + { + AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID); + newTexture.Data = ConvertTextureData(texture, format); + if(newTexture.Data.Length == 0) + return false; // !!! Caller try another codec, please! + + newTexture.Flags = AssetFlags.Collectable; + newTexture.Temporary = true; + newTexture.Local = true; + WriteTextureData(httpRequest, httpResponse, newTexture, format); + return true; + } + } + } + + // not found + // m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + return true; + } + + private void WriteTextureData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture, string format) + { + string range = request.Headers.GetOne("Range"); + + if (!String.IsNullOrEmpty(range)) // JP2's only + { + // Range request + int start, end; + if (TryParseRange(range, out start, out end)) + { + // Before clamping start make sure we can satisfy it in order to avoid + // sending back the last byte instead of an error status + if (start >= texture.Data.Length) + { +// m_log.DebugFormat( +// "[GETTEXTURE]: Client requested range for texture {0} starting at {1} but texture has end of {2}", +// texture.ID, start, texture.Data.Length); + + // Stricly speaking, as per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, we should be sending back + // Requested Range Not Satisfiable (416) here. However, it appears that at least recent implementations + // of the Linden Lab viewer (3.2.1 and 3.3.4 and probably earlier), a viewer that has previously + // received a very small texture may attempt to fetch bytes from the server past the + // range of data that it received originally. Whether this happens appears to depend on whether + // the viewer's estimation of how large a request it needs to make for certain discard levels + // (http://wiki.secondlife.com/wiki/Image_System#Discard_Level_and_Mip_Mapping), chiefly discard + // level 2. If this estimate is greater than the total texture size, returning a RequestedRangeNotSatisfiable + // here will cause the viewer to treat the texture as bad and never display the full resolution + // However, if we return PartialContent (or OK) instead, the viewer will display that resolution. + +// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; +// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length)); +// response.StatusCode = (int)System.Net.HttpStatusCode.OK; + response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; + response.ContentType = texture.Metadata.ContentType; + } + else + { + // Handle the case where no second range value was given. This is equivalent to requesting + // the rest of the entity. + if (end == -1) + end = int.MaxValue; + + end = Utils.Clamp(end, 0, texture.Data.Length - 1); + start = Utils.Clamp(start, 0, end); + int len = end - start + 1; + +// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); + + // Always return PartialContent, even if the range covered the entire data length + // We were accidentally sending back 404 before in this situation + // https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the + // entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this. + // + // We also do not want to send back OK even if the whole range was satisfiable since this causes + // HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality. +// if (end > maxEnd) +// response.StatusCode = (int)System.Net.HttpStatusCode.OK; +// else + response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; + + response.ContentLength = len; + response.ContentType = texture.Metadata.ContentType; + response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length)); + + response.Body.Write(texture.Data, start, len); + } + } + else + { + m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range); + response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest; + } + } + else // JP2's or other formats + { + // Full content request + response.StatusCode = (int)System.Net.HttpStatusCode.OK; + response.ContentLength = texture.Data.Length; + if (format == DefaultFormat) + response.ContentType = texture.Metadata.ContentType; + else + response.ContentType = "image/" + format; + response.Body.Write(texture.Data, 0, texture.Data.Length); + } + +// if (response.StatusCode < 200 || response.StatusCode > 299) +// m_log.WarnFormat( +// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})", +// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length); +// else +// m_log.DebugFormat( +// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})", +// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length); + } + + /// + /// Parse a range header. + /// + /// + /// As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, + /// this obeys range headers with two values (e.g. 533-4165) and no second value (e.g. 533-). + /// Where there is no value, -1 is returned. + /// FIXME: Need to cover the case where only a second value is specified (e.g. -4165), probably by returning -1 + /// for start. + /// + /// + /// Start of the range. Undefined if this was not a number. + /// End of the range. Will be -1 if no end specified. Undefined if there was a raw string but this was not a number. + private bool TryParseRange(string header, out int start, out int end) + { + start = end = 0; + + if (header.StartsWith("bytes=")) + { + string[] rangeValues = header.Substring(6).Split('-'); + + if (rangeValues.Length == 2) + { + if (!Int32.TryParse(rangeValues[0], out start)) + return false; + + string rawEnd = rangeValues[1]; + + if (rawEnd == "") + { + end = -1; + return true; + } + else if (Int32.TryParse(rawEnd, out end)) + { + return true; + } + } + } + + start = end = 0; + return false; + } + + private byte[] ConvertTextureData(AssetBase texture, string format) + { + m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format); + byte[] data = new byte[0]; + + MemoryStream imgstream = new MemoryStream(); + Bitmap mTexture = null; + ManagedImage managedImage = null; + Image image = null; + + try + { + // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data + // Decode image to System.Drawing.Image + if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image) && image != null) + { + // Save to bitmap + mTexture = new Bitmap(image); + + using(EncoderParameters myEncoderParameters = new EncoderParameters()) + { + myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,95L); + + // Save bitmap to stream + ImageCodecInfo codec = GetEncoderInfo("image/" + format); + if (codec != null) + { + mTexture.Save(imgstream, codec, myEncoderParameters); + // Write the stream to a byte array for output + data = imgstream.ToArray(); + } + else + m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format); + } + } + } + catch (Exception e) + { + m_log.WarnFormat("[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID, format, e.Message); + } + finally + { + // Reclaim memory, these are unmanaged resources + // If we encountered an exception, one or more of these will be null + if (mTexture != null) + mTexture.Dispose(); + + if (image != null) + image.Dispose(); + + if(managedImage != null) + managedImage.Clear(); + + if (imgstream != null) + imgstream.Dispose(); + } + + return data; + } + + // From msdn + private static ImageCodecInfo GetEncoderInfo(String mimeType) + { + ImageCodecInfo[] encoders; + encoders = ImageCodecInfo.GetImageEncoders(); + for (int j = 0; j < encoders.Length; ++j) + { + if (encoders[j].MimeType == mimeType) + return encoders[j]; + } + return null; + } + } +} diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs index fa0b228..479cebb 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs @@ -33,6 +33,7 @@ using OpenSim.Framework.Servers.HttpServer; using OpenSim.Server.Handlers.Base; using OpenMetaverse; + namespace OpenSim.Capabilities.Handlers { public class GetTextureServerConnector : ServiceConnector @@ -65,7 +66,8 @@ namespace OpenSim.Capabilities.Handlers string rurl = serverConfig.GetString("GetTextureRedirectURL"); ; server.AddStreamHandler( - new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null, rurl)); + new GetTextureRobustHandler("/CAPS/GetTexture/", m_AssetService, "GetTexture", null, rurl)); } } -} \ No newline at end of file +} + diff --git a/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs index e5d9618..61aa689 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs @@ -38,6 +38,7 @@ using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Scenes; using OpenSim.Tests.Common; +/* namespace OpenSim.Capabilities.Handlers.GetTexture.Tests { [TestFixture] @@ -59,4 +60,5 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests Assert.That(resp.StatusCode, Is.EqualTo((int)System.Net.HttpStatusCode.NotFound)); } } -} \ No newline at end of file +} +*/ diff --git a/OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs b/OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs index 1a6d04f..387b3de 100644 --- a/OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs +++ b/OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs @@ -2,7 +2,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("OpenSim.Capabilities.Handlers")] @@ -14,8 +14,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] @@ -25,9 +25,9 @@ using System.Runtime.InteropServices; // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("0.8.3.*")] +[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] diff --git a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs index 8849a59..48274c1 100644 --- a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs @@ -26,23 +26,12 @@ */ using System; -using System.Collections; -using System.Collections.Specialized; -using System.Drawing; -using System.Drawing.Imaging; using System.Reflection; -using System.IO; -using System.Web; using log4net; -using Nini.Config; using OpenMetaverse; -using OpenMetaverse.StructuredData; -using OpenMetaverse.Imaging; using OpenSim.Framework; using OpenSim.Framework.Capabilities; -using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; -using OpenSim.Region.Framework.Interfaces; using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; @@ -50,17 +39,16 @@ namespace OpenSim.Capabilities.Handlers { public class UploadBakedTextureHandler { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Caps m_HostCapsObj; private IAssetService m_assetService; - private bool m_persistBakedTextures; - public UploadBakedTextureHandler(Caps caps, IAssetService assetService, bool persistBakedTextures) + public UploadBakedTextureHandler(Caps caps, IAssetService assetService) { m_HostCapsObj = caps; m_assetService = assetService; - m_persistBakedTextures = persistBakedTextures; } /// @@ -81,7 +69,7 @@ namespace OpenSim.Capabilities.Handlers string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); BakedTextureUploader uploader = - new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener); + new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_HostCapsObj.AgentID); uploader.OnUpLoad += BakedTextureUploaded; m_HostCapsObj.HttpListener.AddStreamHandler( @@ -117,13 +105,13 @@ namespace OpenSim.Capabilities.Handlers /// private void BakedTextureUploaded(UUID assetID, byte[] data) { -// m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString()); + m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString()); AssetBase asset; asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString()); asset.Data = data; asset.Temporary = true; - asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are + asset.Local = true; m_assetService.Store(asset); } } @@ -137,12 +125,14 @@ namespace OpenSim.Capabilities.Handlers private string uploaderPath = String.Empty; private UUID newAssetID; private IHttpServer httpListener; + private UUID AgentId = UUID.Zero; - public BakedTextureUploader(string path, IHttpServer httpServer) + public BakedTextureUploader(string path, IHttpServer httpServer, UUID uUID) { newAssetID = UUID.Random(); uploaderPath = path; httpListener = httpServer; + AgentId = uUID; // m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID); } diff --git a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs index 10ea8ee..fd484ba 100644 --- a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs @@ -67,7 +67,7 @@ namespace OpenSim.Capabilities.Handlers server.AddStreamHandler(new RestStreamHandler( "POST", "/CAPS/UploadBakedTexture/", - new UploadBakedTextureHandler(caps, m_AssetService, true).UploadBakedTexture, + new UploadBakedTextureHandler(caps, m_AssetService).UploadBakedTexture, "UploadBakedTexture", "Upload Baked Texture Capability")); diff --git a/OpenSim/Capabilities/LLSD.cs b/OpenSim/Capabilities/LLSD.cs index c59cede..fc41113 100644 --- a/OpenSim/Capabilities/LLSD.cs +++ b/OpenSim/Capabilities/LLSD.cs @@ -83,6 +83,8 @@ namespace OpenSim.Framework.Capabilities { using (XmlTextReader reader = new XmlTextReader(st)) { + reader.ProhibitDtd = true; + reader.Read(); SkipWS(reader); @@ -566,7 +568,7 @@ namespace OpenSim.Framework.Capabilities endPos = FindEnd(llsd, 1); if (Double.TryParse(llsd.Substring(1, endPos - 1), NumberStyles.Float, - Utils.EnUsCulture.NumberFormat, out value)) + Culture.NumberFormatInfo, out value)) return value; else throw new LLSDParseException("Failed to parse double value type"); diff --git a/OpenSim/Capabilities/LLSDAssetUploadComplete.cs b/OpenSim/Capabilities/LLSDAssetUploadComplete.cs index ab6cee5..476cf6e 100644 --- a/OpenSim/Capabilities/LLSDAssetUploadComplete.cs +++ b/OpenSim/Capabilities/LLSDAssetUploadComplete.cs @@ -30,13 +30,20 @@ using OpenMetaverse; namespace OpenSim.Framework.Capabilities { + [LLSDType("MAP")] public class LLSDAssetUploadComplete { public string new_asset = String.Empty; public UUID new_inventory_item = UUID.Zero; +// public UUID new_texture_folder_id = UUID.Zero; public string state = String.Empty; + public LLSDAssetUploadError error = null; //public bool success = false; + public int new_next_owner_mask = 0; + public int new_group_mask = 0; + public int new_everyone_mask = 0; + public int inventory_item_flags = 0; public LLSDAssetUploadComplete() { diff --git a/OpenSim/Capabilities/LLSDAssetUploadRequest.cs b/OpenSim/Capabilities/LLSDAssetUploadRequest.cs index 6e66f0a..6779cc1 100644 --- a/OpenSim/Capabilities/LLSDAssetUploadRequest.cs +++ b/OpenSim/Capabilities/LLSDAssetUploadRequest.cs @@ -31,14 +31,27 @@ using OpenMetaverse; namespace OpenSim.Framework.Capabilities { [OSDMap] + public class LLSDAssetResource + { + public OSDArray instance_list = new OSDArray(); + public OSDArray texture_list = new OSDArray(); + public OSDArray mesh_list = new OSDArray(); + public string metric = String.Empty; + } + + [OSDMap] public class LLSDAssetUploadRequest { public string asset_type = String.Empty; public string description = String.Empty; public UUID folder_id = UUID.Zero; + public UUID texture_folder_id = UUID.Zero; + public int next_owner_mask = 0; + public int group_mask = 0; + public int everyone_mask = 0; public string inventory_type = String.Empty; public string name = String.Empty; - + public LLSDAssetResource asset_resources = new LLSDAssetResource(); public LLSDAssetUploadRequest() { } diff --git a/OpenSim/Capabilities/LLSDAssetUploadResponse.cs b/OpenSim/Capabilities/LLSDAssetUploadResponse.cs index 0d6f7f9..97491e3 100644 --- a/OpenSim/Capabilities/LLSDAssetUploadResponse.cs +++ b/OpenSim/Capabilities/LLSDAssetUploadResponse.cs @@ -26,20 +26,51 @@ */ using System; +using OpenMetaverse; namespace OpenSim.Framework.Capabilities { [OSDMap] + public class LLSDAssetUploadError + { + public string message = String.Empty; + public UUID identifier = UUID.Zero; + } + + [OSDMap] + public class LLSDAssetUploadResponsePricebrkDown + { + public int mesh_streaming; + public int mesh_physics; + public int mesh_instance; + public int texture; + public int model; + } + + [OSDMap] + public class LLSDAssetUploadResponseData + { + public double resource_cost; + public double model_streaming_cost; + public double simulation_cost; + public double physics_cost; + public LLSDAssetUploadResponsePricebrkDown upload_price_breakdown = new LLSDAssetUploadResponsePricebrkDown(); + } + + [OSDMap] public class LLSDAssetUploadResponse { public string uploader = String.Empty; public string state = String.Empty; - + public int upload_price = 0; + public LLSDAssetUploadResponseData data = null; + public LLSDAssetUploadError error = null; public LLSDAssetUploadResponse() { } } + [OSDMap] public class LLSDNewFileAngentInventoryVariablePriceReplyResponse { @@ -47,7 +78,7 @@ namespace OpenSim.Framework.Capabilities public string state; public int upload_price; public string rsvp; - + public LLSDNewFileAngentInventoryVariablePriceReplyResponse() { state = "confirm_upload"; diff --git a/OpenSim/Capabilities/LLSDAvatarPicker.cs b/OpenSim/Capabilities/LLSDAvatarPicker.cs index d0b3f3a..12e892c 100644 --- a/OpenSim/Capabilities/LLSDAvatarPicker.cs +++ b/OpenSim/Capabilities/LLSDAvatarPicker.cs @@ -42,7 +42,7 @@ namespace OpenSim.Framework.Capabilities { public string username; public string display_name; - //'display_name_next_update':d"1970-01-01T00:00:00Z" + //'display_name_next_update':d"1970-01-01T00:00:00Z" public string legacy_first_name; public string legacy_last_name; public UUID id; diff --git a/OpenSim/Capabilities/LLSDHelpers.cs b/OpenSim/Capabilities/LLSDHelpers.cs index 8f1a40e..d582267 100644 --- a/OpenSim/Capabilities/LLSDHelpers.cs +++ b/OpenSim/Capabilities/LLSDHelpers.cs @@ -157,6 +157,11 @@ namespace OpenSim.Framework.Capabilities // the LLSD map/array types in the array need to be deserialised // but first we need to know the right class to deserialise them into. } + else if(enumerator.Value is Boolean && field.FieldType == typeof(int) ) + { + int i = (bool)enumerator.Value ? 1 : 0; + field.SetValue(obj, (object)i); + } else { field.SetValue(obj, enumerator.Value); diff --git a/OpenSim/Capabilities/LLSDInventoryItem.cs b/OpenSim/Capabilities/LLSDInventoryItem.cs index 958e807..460a215 100644 --- a/OpenSim/Capabilities/LLSDInventoryItem.cs +++ b/OpenSim/Capabilities/LLSDInventoryItem.cs @@ -87,12 +87,12 @@ namespace OpenSim.Framework.Capabilities [OSDMap] public class LLSDInventoryFolderContents { - public UUID agent_id; + public UUID agent_id; public int descendents; - public UUID folder_id; + public UUID folder_id; public OSDArray categories = new OSDArray(); public OSDArray items = new OSDArray(); - public UUID owner_id; + public UUID owner_id; public int version; } diff --git a/OpenSim/Capabilities/LLSDStreamHandler.cs b/OpenSim/Capabilities/LLSDStreamHandler.cs index 4fa1153..4f1b10a 100644 --- a/OpenSim/Capabilities/LLSDStreamHandler.cs +++ b/OpenSim/Capabilities/LLSDStreamHandler.cs @@ -61,6 +61,9 @@ namespace OpenSim.Framework.Capabilities // OpenMetaverse.StructuredData.LLSDParser.DeserializeXml(new XmlTextReader(request)); Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(request); + if(hash == null) + return new byte[0]; + TRequest llsdRequest = new TRequest(); LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest); diff --git a/OpenSim/Capabilities/Properties/AssemblyInfo.cs b/OpenSim/Capabilities/Properties/AssemblyInfo.cs index f8a9dae..72a5240 100644 --- a/OpenSim/Capabilities/Properties/AssemblyInfo.cs +++ b/OpenSim/Capabilities/Properties/AssemblyInfo.cs @@ -2,7 +2,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("OpenSim.Capabilities")] @@ -14,8 +14,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] @@ -25,7 +25,7 @@ using System.Runtime.InteropServices; // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // diff --git a/OpenSim/ConsoleClient/ConsoleClient.cs b/OpenSim/ConsoleClient/ConsoleClient.cs index 7c003ea..c395cd7 100644 --- a/OpenSim/ConsoleClient/ConsoleClient.cs +++ b/OpenSim/ConsoleClient/ConsoleClient.cs @@ -110,6 +110,7 @@ namespace OpenSim.ConsoleClient public static void LoginReply(string requestUrl, string requestData, string replyData) { XmlDocument doc = new XmlDocument(); + doc.XmlResolver=null; doc.LoadXml(replyData); @@ -169,6 +170,7 @@ namespace OpenSim.ConsoleClient public static void ReadResponses(string requestUrl, string requestData, string replyData) { XmlDocument doc = new XmlDocument(); + doc.XmlResolver=null; doc.LoadXml(replyData); @@ -178,7 +180,7 @@ namespace OpenSim.ConsoleClient Requester.MakeRequest(requestUrl, requestData, ReadResponses); return; } - + List lines = new List(); foreach (XmlNode part in rootNodeL[0].ChildNodes) @@ -202,7 +204,7 @@ namespace OpenSim.ConsoleClient string[] parts = l.Split(new char[] {':'}, 3); if (parts.Length != 3) continue; - + if (parts[2].StartsWith("+++") || parts[2].StartsWith("-++")) prompt = parts[2]; else diff --git a/OpenSim/ConsoleClient/Properties/AssemblyInfo.cs b/OpenSim/ConsoleClient/Properties/AssemblyInfo.cs index 9c0c784..87bff14 100644 --- a/OpenSim/ConsoleClient/Properties/AssemblyInfo.cs +++ b/OpenSim/ConsoleClient/Properties/AssemblyInfo.cs @@ -2,7 +2,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("OpenSim.ConsoleClient")] @@ -14,8 +14,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] @@ -25,7 +25,7 @@ using System.Runtime.InteropServices; // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // diff --git a/OpenSim/Data/AssetDataBase.cs b/OpenSim/Data/AssetDataBase.cs index 1bb432c..9593a25 100644 --- a/OpenSim/Data/AssetDataBase.cs +++ b/OpenSim/Data/AssetDataBase.cs @@ -37,7 +37,7 @@ namespace OpenSim.Data public abstract class AssetDataBase : IAssetDataPlugin { public abstract AssetBase GetAsset(UUID uuid); - public abstract void StoreAsset(AssetBase asset); + public abstract bool StoreAsset(AssetBase asset); public abstract bool[] AssetsExist(UUID[] uuids); public abstract List FetchAssetMetadataSet(int start, int count); diff --git a/OpenSim/Data/DBGuids.cs b/OpenSim/Data/DBGuids.cs index ad1c19c..1a2bf41 100644 --- a/OpenSim/Data/DBGuids.cs +++ b/OpenSim/Data/DBGuids.cs @@ -38,7 +38,7 @@ namespace OpenSim.Data /// This function converts a value returned from the database in one of the /// supported formats into a UUID. This function is not actually DBMS-specific right /// now - /// + /// /// /// /// diff --git a/OpenSim/Data/IAssetData.cs b/OpenSim/Data/IAssetData.cs index a41e310..febab5d 100644 --- a/OpenSim/Data/IAssetData.cs +++ b/OpenSim/Data/IAssetData.cs @@ -34,7 +34,7 @@ namespace OpenSim.Data public interface IAssetDataPlugin : IPlugin { AssetBase GetAsset(UUID uuid); - void StoreAsset(AssetBase asset); + bool StoreAsset(AssetBase asset); bool[] AssetsExist(UUID[] uuids); List FetchAssetMetadataSet(int start, int count); void Initialise(string connect); diff --git a/OpenSim/Data/IAvatarData.cs b/OpenSim/Data/IAvatarData.cs index 0a18e21..b3f12c1 100644 --- a/OpenSim/Data/IAvatarData.cs +++ b/OpenSim/Data/IAvatarData.cs @@ -39,7 +39,7 @@ namespace OpenSim.Data public Dictionary Data; } - public interface IAvatarData + public interface IAvatarData { AvatarBaseData[] Get(string field, string val); bool Store(AvatarBaseData data); diff --git a/OpenSim/Data/IEstateDataStore.cs b/OpenSim/Data/IEstateDataStore.cs index f9070ea..6b30db2 100644 --- a/OpenSim/Data/IEstateDataStore.cs +++ b/OpenSim/Data/IEstateDataStore.cs @@ -46,14 +46,14 @@ namespace OpenSim.Data /// If true, then an estate is created if one is not found. /// EstateSettings LoadEstateSettings(UUID regionID, bool create); - + /// /// Load estate settings for an estate ID. /// /// /// EstateSettings LoadEstateSettings(int estateID); - + /// /// Create a new estate. /// @@ -67,7 +67,7 @@ namespace OpenSim.Data /// /// An empty list if no estates were found. List LoadEstateSettingsAll(); - + /// /// Store estate settings. /// @@ -75,7 +75,7 @@ namespace OpenSim.Data /// This is also called by EstateSettings.Save() /// void StoreEstateSettings(EstateSettings es); - + /// /// Get estate IDs. /// @@ -88,13 +88,13 @@ namespace OpenSim.Data /// /// An empty list if no estates were found. List GetEstatesByOwner(UUID ownerID); - + /// /// Get the IDs of all estates. /// /// An empty list if no estates were found. List GetEstatesAll(); - + /// /// Link a region to an estate. /// @@ -102,14 +102,14 @@ namespace OpenSim.Data /// /// true if the link succeeded, false otherwise bool LinkRegion(UUID regionID, int estateID); - + /// /// Get the UUIDs of all the regions in an estate. /// /// /// List GetRegions(int estateID); - + /// /// Delete an estate /// diff --git a/OpenSim/Data/IGridUserData.cs b/OpenSim/Data/IGridUserData.cs index 9afa477..1b2ea87 100644 --- a/OpenSim/Data/IGridUserData.cs +++ b/OpenSim/Data/IGridUserData.cs @@ -47,7 +47,7 @@ namespace OpenSim.Data /// /// An interface for connecting to the user grid datastore /// - public interface IGridUserData + public interface IGridUserData { GridUserData Get(string userID); GridUserData[] GetAll(string query); diff --git a/OpenSim/Data/IGroupsData.cs b/OpenSim/Data/IGroupsData.cs index c11e649..bd059e0 100644 --- a/OpenSim/Data/IGroupsData.cs +++ b/OpenSim/Data/IGroupsData.cs @@ -81,7 +81,7 @@ namespace OpenSim.Data } - public interface IGroupsData + public interface IGroupsData { // groups table bool StoreGroup(GroupData data); diff --git a/OpenSim/Data/IHGTravelingData.cs b/OpenSim/Data/IHGTravelingData.cs index 452af7b..5e4894e 100644 --- a/OpenSim/Data/IHGTravelingData.cs +++ b/OpenSim/Data/IHGTravelingData.cs @@ -48,7 +48,7 @@ namespace OpenSim.Data /// /// An interface for connecting to the user grid datastore /// - public interface IHGTravelingData + public interface IHGTravelingData { HGTravelingData Get(UUID sessionID); HGTravelingData[] GetSessions(UUID userID); diff --git a/OpenSim/Data/IMuteListData.cs b/OpenSim/Data/IMuteListData.cs new file mode 100644 index 0000000..b0235b2 --- /dev/null +++ b/OpenSim/Data/IMuteListData.cs @@ -0,0 +1,44 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Data +{ + /// + /// An interface for connecting to the Mute List datastore + /// + public interface IMuteListData + { + bool Store(MuteData data); + MuteData[] Get(UUID agentID); + bool Delete(UUID agentID, UUID muteID, string muteName); + } +} diff --git a/OpenSim/Data/IOfflineIMData.cs b/OpenSim/Data/IOfflineIMData.cs index 58501a3..a0f4d69 100644 --- a/OpenSim/Data/IOfflineIMData.cs +++ b/OpenSim/Data/IOfflineIMData.cs @@ -39,7 +39,7 @@ namespace OpenSim.Data } - public interface IOfflineIMData + public interface IOfflineIMData { OfflineIMData[] Get(string field, string val); long GetCount(string field, string key); diff --git a/OpenSim/Data/IPresenceData.cs b/OpenSim/Data/IPresenceData.cs index 9ec48b0..4086245 100644 --- a/OpenSim/Data/IPresenceData.cs +++ b/OpenSim/Data/IPresenceData.cs @@ -44,7 +44,7 @@ namespace OpenSim.Data /// /// An interface for connecting to the presence datastore /// - public interface IPresenceData + public interface IPresenceData { bool Store(PresenceData data); diff --git a/OpenSim/Data/IProfilesData.cs b/OpenSim/Data/IProfilesData.cs index 7fb075d..a4a32a9 100644 --- a/OpenSim/Data/IProfilesData.cs +++ b/OpenSim/Data/IProfilesData.cs @@ -48,7 +48,7 @@ namespace OpenSim.Data bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result); bool UpdateAvatarInterests(UserProfileProperties up, ref string result); bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result); - bool UpdateUserPreferences(ref UserPreferences pref, ref string result); + bool UpdateUserPreferences(ref UserPreferences pref, ref string result); bool GetUserPreferences(ref UserPreferences pref, ref string result); bool GetUserAppData(ref UserAppData props, ref string result); bool SetUserAppData(UserAppData props, ref string result); diff --git a/OpenSim/Data/IRegionData.cs b/OpenSim/Data/IRegionData.cs index ca9b327..c8e38a4 100644 --- a/OpenSim/Data/IRegionData.cs +++ b/OpenSim/Data/IRegionData.cs @@ -67,7 +67,7 @@ namespace OpenSim.Data /// /// An interface for connecting to the authentication datastore /// - public interface IRegionData + public interface IRegionData { RegionData Get(UUID regionID, UUID ScopeID); List Get(string regionName, UUID ScopeID); diff --git a/OpenSim/Data/IUserAccountData.cs b/OpenSim/Data/IUserAccountData.cs index 906ba6c..bc7eda7 100644 --- a/OpenSim/Data/IUserAccountData.cs +++ b/OpenSim/Data/IUserAccountData.cs @@ -50,5 +50,6 @@ namespace OpenSim.Data bool Store(UserAccountData data); bool Delete(string field, string val); UserAccountData[] GetUsers(UUID scopeID, string query); + UserAccountData[] GetUsersWhere(UUID scopeID, string where); } } diff --git a/OpenSim/Data/IXGroupData.cs b/OpenSim/Data/IXGroupData.cs index e5821ef..82073fe 100644 --- a/OpenSim/Data/IXGroupData.cs +++ b/OpenSim/Data/IXGroupData.cs @@ -38,12 +38,12 @@ namespace OpenSim.Data public UUID ownerRoleID; public string name; public string charter; - public bool showInList; - public UUID insigniaID; + public bool showInList; + public UUID insigniaID; public int membershipFee; public bool openEnrollment; public bool allowPublish; - public bool maturePublish; + public bool maturePublish; public UUID founderID; public ulong everyonePowers; public ulong ownersPowers; diff --git a/OpenSim/Data/Migration.cs b/OpenSim/Data/Migration.cs index d606470..e54bf55 100644 --- a/OpenSim/Data/Migration.cs +++ b/OpenSim/Data/Migration.cs @@ -80,10 +80,10 @@ namespace OpenSim.Data /// Have the parameterless constructor just so we can specify it as a generic parameter with the new() constraint. /// Currently this is only used in the tests. A Migration instance created this way must be then - /// initialized with Initialize(). Regular creation should be through the parameterized constructors. + /// initialized with Initialize(). Regular creation should be through the parameterized constructors. /// public Migration() - { + { } public Migration(DbConnection conn, Assembly assem, string subtype, string type) @@ -91,7 +91,7 @@ namespace OpenSim.Data Initialize(conn, assem, type, subtype); } - public Migration(DbConnection conn, Assembly assem, string type) + public Migration(DbConnection conn, Assembly assem, string type) { Initialize(conn, assem, type, ""); } @@ -191,7 +191,7 @@ namespace OpenSim.Data int newversion = kvp.Key; // we need to up the command timeout to infinite as we might be doing long migrations. - /* [AlexRa 01-May-10]: We can't always just run any SQL in a single batch (= ExecuteNonQuery()). Things like + /* [AlexRa 01-May-10]: We can't always just run any SQL in a single batch (= ExecuteNonQuery()). Things like * stored proc definitions might have to be sent to the server each in a separate batch. * This is certainly so for MS SQL; not sure how the MySQL connector sorts out the mess * with 'delimiter @@'/'delimiter ;' around procs. So each "script" this code executes now is not @@ -276,7 +276,7 @@ namespace OpenSim.Data private delegate void FlushProc(); /// Scans for migration resources in either old-style "scattered" (one file per version) - /// or new-style "integrated" format (single file with ":VERSION nnn" sections). + /// or new-style "integrated" format (single file with ":VERSION nnn" sections). /// In the new-style migrations it also recognizes ':GO' separators for parts of the SQL script /// that must be sent to the server separately. The old-style migrations are loaded each in one piece /// and don't support the ':GO' feature. @@ -301,12 +301,12 @@ namespace OpenSim.Data { /* The filename should be '.migrations[.NNN]' where NNN * is the last version number defined in the file. If the '.NNN' part is recognized, the code can skip - * the file without looking inside if we have a higher version already. Without the suffix we read + * the file without looking inside if we have a higher version already. Without the suffix we read * the file anyway and use the version numbers inside. Any unrecognized suffix (such as '.sql') * is valid but ignored. - * - * NOTE that we expect only one 'merged' migration file. If there are several, we take the last one. - * If you are numbering them, leave only the latest one in the project or at least make sure they numbered + * + * NOTE that we expect only one 'merged' migration file. If there are several, we take the last one. + * If you are numbering them, leave only the latest one in the project or at least make sure they numbered * to come up in the correct order (e.g. 'SomeStore.migrations.001' rather than 'SomeStore.migrations.1') */ @@ -351,7 +351,7 @@ namespace OpenSim.Data if (sLine.Trim().Equals(":GO", StringComparison.InvariantCultureIgnoreCase)) { if (sb.Length == 0) continue; - if (nVersion > after) + if (nVersion > after) script.Add(sb.ToString()); sb.Length = 0; continue; @@ -405,10 +405,10 @@ scan_old_style: } } } - - if (migrations.Count < 1) + + if (migrations.Count < 1) m_log.DebugFormat("[MIGRATIONS]: {0} data tables already up to date at revision {1}", _type, after); - + return migrations; } } diff --git a/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs b/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs index ed0ab98..17f1374 100644 --- a/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs +++ b/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs index 5d8da17..8569c90 100644 --- a/OpenSim/Data/MySQL/MySQLAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLAssetData.cs @@ -75,6 +75,7 @@ namespace OpenSim.Data.MySQL dbcon.Open(); Migration m = new Migration(dbcon, Assembly, "AssetStore"); m.Update(); + dbcon.Close(); } } @@ -144,6 +145,7 @@ namespace OpenSim.Data.MySQL string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e); } } + dbcon.Close(); } return asset; @@ -154,65 +156,62 @@ namespace OpenSim.Data.MySQL /// /// Asset UUID to create /// On failure : Throw an exception and attempt to reconnect to database - override public void StoreAsset(AssetBase asset) + override public bool StoreAsset(AssetBase asset) { + string assetName = asset.Name; + if (asset.Name.Length > AssetBase.MAX_ASSET_NAME) + { + assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME); + m_log.WarnFormat( + "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", + asset.Name, asset.ID, asset.Name.Length, assetName.Length); + } + + string assetDescription = asset.Description; + if (asset.Description.Length > AssetBase.MAX_ASSET_DESC) + { + assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC); + m_log.WarnFormat( + "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", + asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); + } + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); - using (MySqlCommand cmd = new MySqlCommand( "replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" + "VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)", dbcon)) { - string assetName = asset.Name; - if (asset.Name.Length > AssetBase.MAX_ASSET_NAME) - { - assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME); - m_log.WarnFormat( - "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", - asset.Name, asset.ID, asset.Name.Length, assetName.Length); - } - - string assetDescription = asset.Description; - if (asset.Description.Length > AssetBase.MAX_ASSET_DESC) - { - assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC); - m_log.WarnFormat( - "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", - asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); - } - try { - using (cmd) - { - // create unix epoch time - int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); - cmd.Parameters.AddWithValue("?id", asset.ID); - cmd.Parameters.AddWithValue("?name", assetName); - cmd.Parameters.AddWithValue("?description", assetDescription); - cmd.Parameters.AddWithValue("?assetType", asset.Type); - cmd.Parameters.AddWithValue("?local", asset.Local); - cmd.Parameters.AddWithValue("?temporary", asset.Temporary); - cmd.Parameters.AddWithValue("?create_time", now); - cmd.Parameters.AddWithValue("?access_time", now); - cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID); - cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags); - cmd.Parameters.AddWithValue("?data", asset.Data); - cmd.ExecuteNonQuery(); - } + // create unix epoch time + int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); + cmd.Parameters.AddWithValue("?id", asset.ID); + cmd.Parameters.AddWithValue("?name", assetName); + cmd.Parameters.AddWithValue("?description", assetDescription); + cmd.Parameters.AddWithValue("?assetType", asset.Type); + cmd.Parameters.AddWithValue("?local", asset.Local); + cmd.Parameters.AddWithValue("?temporary", asset.Temporary); + cmd.Parameters.AddWithValue("?create_time", now); + cmd.Parameters.AddWithValue("?access_time", now); + cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID); + cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags); + cmd.Parameters.AddWithValue("?data", asset.Data); + cmd.ExecuteNonQuery(); + dbcon.Close(); + return true; } catch (Exception e) { - m_log.Error( - string.Format( - "[ASSET DB]: MySQL failure creating asset {0} with name {1}. Exception ", - asset.FullID, asset.Name) - , e); + m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}", + asset.FullID, asset.Name, e.Message); + dbcon.Close(); + return false; } - } + } } } @@ -227,24 +226,22 @@ namespace OpenSim.Data.MySQL { try { - using (cmd) - { - // create unix epoch time - int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); - cmd.Parameters.AddWithValue("?id", asset.ID); - cmd.Parameters.AddWithValue("?access_time", now); - cmd.ExecuteNonQuery(); - } + // create unix epoch time + int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); + cmd.Parameters.AddWithValue("?id", asset.ID); + cmd.Parameters.AddWithValue("?access_time", now); + cmd.ExecuteNonQuery(); } catch (Exception e) { m_log.Error( string.Format( - "[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ", - asset.FullID, asset.Name), + "[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ", + asset.FullID, asset.Name), e); } } + dbcon.Close(); } } @@ -277,6 +274,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } bool[] results = new bool[uuids.Length]; @@ -336,11 +334,12 @@ namespace OpenSim.Data.MySQL { m_log.Error( string.Format( - "[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ", - start, count), + "[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ", + start, count), e); } } + dbcon.Close(); } return retList; @@ -357,6 +356,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?id", id); cmd.ExecuteNonQuery(); } + dbcon.Close(); } return true; @@ -364,4 +364,4 @@ namespace OpenSim.Data.MySQL #endregion } -} \ No newline at end of file +} diff --git a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs index 7627497..fef582e 100644 --- a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs +++ b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs @@ -59,6 +59,7 @@ namespace OpenSim.Data.MySQL dbcon.Open(); Migration m = new Migration(dbcon, Assembly, "AuthStore"); m.Update(); + dbcon.Close(); } } @@ -76,27 +77,30 @@ namespace OpenSim.Data.MySQL { cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); - IDataReader result = cmd.ExecuteReader(); - - if (result.Read()) + using(IDataReader result = cmd.ExecuteReader()) { - ret.PrincipalID = principalID; - - CheckColumnNames(result); - - foreach (string s in m_ColumnNames) + if(result.Read()) { - if (s == "UUID") - continue; - - ret.Data[s] = result[s].ToString(); + ret.PrincipalID = principalID; + + CheckColumnNames(result); + + foreach(string s in m_ColumnNames) + { + if(s == "UUID") + continue; + + ret.Data[s] = result[s].ToString(); + } + + dbcon.Close(); + return ret; + } + else + { + dbcon.Close(); + return null; } - - return ret; - } - else - { - return null; } } } @@ -132,25 +136,25 @@ namespace OpenSim.Data.MySQL if (!first) update += ", "; update += "`" + field + "` = ?"+field; - + first = false; - + cmd.Parameters.AddWithValue("?"+field, data.Data[field]); } - + update += " where UUID = ?principalID"; - + cmd.CommandText = update; cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString()); - + if (ExecuteNonQuery(cmd) < 1) { string insert = "insert into `" + m_Realm + "` (`UUID`, `" + String.Join("`, `", fields) + "`) values (?principalID, ?" + String.Join(", ?", fields) + ")"; - + cmd.CommandText = insert; - + if (ExecuteNonQuery(cmd) < 1) return false; } @@ -166,7 +170,7 @@ namespace OpenSim.Data.MySQL { cmd.Parameters.AddWithValue("?"+item, value); cmd.Parameters.AddWithValue("?UUID", principalID.ToString()); - + if (ExecuteNonQuery(cmd) > 0) return true; } @@ -186,7 +190,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); cmd.Parameters.AddWithValue("?token", token); cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString()); - + if (ExecuteNonQuery(cmd) > 0) return true; } diff --git a/OpenSim/Data/MySQL/MySQLAvatarData.cs b/OpenSim/Data/MySQL/MySQLAvatarData.cs index 6a2f5d8..63e8020 100644 --- a/OpenSim/Data/MySQL/MySQLAvatarData.cs +++ b/OpenSim/Data/MySQL/MySQLAvatarData.cs @@ -57,7 +57,7 @@ namespace OpenSim.Data.MySQL cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = ?PrincipalID and `Name` = ?Name", m_Realm); cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); cmd.Parameters.AddWithValue("?Name", name); - + if (ExecuteNonQuery(cmd) > 0) return true; } diff --git a/OpenSim/Data/MySQL/MySQLEstateData.cs b/OpenSim/Data/MySQL/MySQLEstateData.cs index fe1487b..eeedf02 100644 --- a/OpenSim/Data/MySQL/MySQLEstateData.cs +++ b/OpenSim/Data/MySQL/MySQLEstateData.cs @@ -82,6 +82,7 @@ namespace OpenSim.Data.MySQL Migration m = new Migration(dbcon, Assembly, "EstateStore"); m.Update(); + dbcon.Close(); Type t = typeof(EstateSettings); m_Fields = t.GetFields(BindingFlags.NonPublic | @@ -143,7 +144,6 @@ namespace OpenSim.Data.MySQL using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); - cmd.Connection = dbcon; bool found = false; @@ -171,6 +171,8 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); + cmd.Connection = null; if (!found && create) { @@ -231,6 +233,7 @@ namespace OpenSim.Data.MySQL es.Save(); } + dbcon.Close(); } } @@ -263,6 +266,7 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } SaveBanList(es); @@ -300,6 +304,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } @@ -329,6 +334,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.Clear(); } } + dbcon.Close(); } } @@ -358,6 +364,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.Clear(); } } + dbcon.Close(); } } @@ -383,6 +390,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } return uuids.ToArray(); @@ -403,19 +411,19 @@ namespace OpenSim.Data.MySQL return e; } } - + public List LoadEstateSettingsAll() { - List allEstateSettings = new List(); - + List allEstateSettings = new List(); + List allEstateIds = GetEstatesAll(); - + foreach (int estateId in allEstateIds) allEstateSettings.Add(LoadEstateSettings(estateId)); - + return allEstateSettings; } - + public List GetEstatesAll() { List result = new List(); @@ -437,11 +445,10 @@ namespace OpenSim.Data.MySQL reader.Close(); } } - dbcon.Close(); } - return result; + return result; } public List GetEstates(string search) @@ -466,7 +473,6 @@ namespace OpenSim.Data.MySQL reader.Close(); } } - dbcon.Close(); } diff --git a/OpenSim/Data/MySQL/MySQLFSAssetData.cs b/OpenSim/Data/MySQL/MySQLFSAssetData.cs index 19e23b5..6c48607 100644 --- a/OpenSim/Data/MySQL/MySQLFSAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLFSAssetData.cs @@ -41,10 +41,8 @@ namespace OpenSim.Data.MySQL { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - protected MySqlConnection m_Connection = null; protected string m_ConnectionString; protected string m_Table; - protected Object m_connLock = new Object(); /// /// Number of days that must pass before we update the access time on an asset when it has been fetched @@ -56,7 +54,7 @@ namespace OpenSim.Data.MySQL { get { return GetType().Assembly; } } - + public MySQLFSAssetData() { } @@ -75,10 +73,13 @@ namespace OpenSim.Data.MySQL try { - OpenDatabase(); - - Migration m = new Migration(m_Connection, Assembly, "FSAssetStore"); - m.Update(); + using (MySqlConnection conn = new MySqlConnection(m_ConnectionString)) + { + conn.Open(); + Migration m = new Migration(conn, Assembly, "FSAssetStore"); + m.Update(); + conn.Close(); + } } catch (MySqlException e) { @@ -100,70 +101,37 @@ namespace OpenSim.Data.MySQL #endregion - private bool OpenDatabase() + private bool ExecuteNonQuery(MySqlCommand cmd) { - try - { - m_Connection = new MySqlConnection(m_ConnectionString); - - m_Connection.Open(); - } - catch (MySqlException e) + using (MySqlConnection conn = new MySqlConnection(m_ConnectionString)) { - m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}", - e.Message.ToString()); - - return false; - } - - return true; - } - - private IDataReader ExecuteReader(MySqlCommand c) - { - IDataReader r = null; - MySqlConnection connection = (MySqlConnection) ((ICloneable)m_Connection).Clone(); - connection.Open(); - c.Connection = connection; - - r = c.ExecuteReader(); - - return r; - } - - private void ExecuteNonQuery(MySqlCommand c) - { - lock (m_connLock) - { - bool errorSeen = false; - - while (true) + try { - try - { - c.ExecuteNonQuery(); - } - catch (MySqlException) - { - System.Threading.Thread.Sleep(500); - - m_Connection.Close(); - m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone(); - m_Connection.Open(); - c.Connection = m_Connection; - - if (!errorSeen) - { - errorSeen = true; - continue; - } - m_log.ErrorFormat("[FSASSETS] MySQL command: {0}", c.CommandText); - throw; - } + conn.Open(); + } + catch (MySqlException e) + { + m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString()); + return false; + } - break; + cmd.Connection = conn; + try + { + cmd.ExecuteNonQuery(); + } + catch (MySqlException e) + { + cmd.Connection = null; + conn.Close(); + m_log.ErrorFormat("[FSASSETS]: Query {0} failed with {1}", cmd.CommandText, e.ToString()); + return false; } + conn.Close(); + cmd.Connection = null; } + + return true; } #region IFSAssetDataPlugin Members @@ -172,63 +140,79 @@ namespace OpenSim.Data.MySQL { hash = String.Empty; - MySqlCommand cmd = new MySqlCommand(); - - cmd.CommandText = String.Format("select id, name, description, type, hash, create_time, access_time, asset_flags from {0} where id = ?id", m_Table); - cmd.Parameters.AddWithValue("?id", id); - - IDataReader reader = ExecuteReader(cmd); - - if (!reader.Read()) - { - reader.Close(); - FreeCommand(cmd); - return null; - } - AssetMetadata meta = new AssetMetadata(); - hash = reader["hash"].ToString(); + using (MySqlConnection conn = new MySqlConnection(m_ConnectionString)) + { + try + { + conn.Open(); + } + catch (MySqlException e) + { + m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString()); + return null; + } - meta.ID = id; - meta.FullID = new UUID(id); + using (MySqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = String.Format("select id, name, description, type, hash, create_time, asset_flags, access_time from {0} where id = ?id", m_Table); + cmd.Parameters.AddWithValue("?id", id); - meta.Name = reader["name"].ToString(); - meta.Description = reader["description"].ToString(); - meta.Type = (sbyte)Convert.ToInt32(reader["type"]); - meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type); - meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"])); - meta.Flags = (AssetFlags)Convert.ToInt32(reader["asset_flags"]); + using (IDataReader reader = cmd.ExecuteReader()) + { + if (!reader.Read()) + return null; - int AccessTime = Convert.ToInt32(reader["access_time"]); + hash = reader["hash"].ToString(); - reader.Close(); + meta.ID = id; + meta.FullID = new UUID(id); - UpdateAccessTime(AccessTime, cmd); + meta.Name = reader["name"].ToString(); + meta.Description = reader["description"].ToString(); + meta.Type = (sbyte)Convert.ToInt32(reader["type"]); + meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type); + meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"])); + meta.Flags = (AssetFlags)Convert.ToInt32(reader["asset_flags"]); - FreeCommand(cmd); + int AccessTime = Convert.ToInt32(reader["access_time"]); + UpdateAccessTime(id, AccessTime); + } + } + conn.Close(); + } return meta; } - private void UpdateAccessTime(int AccessTime, MySqlCommand cmd) + private void UpdateAccessTime(string AssetID, int AccessTime) { // Reduce DB work by only updating access time if asset hasn't recently been accessed // 0 By Default, Config option is "DaysBetweenAccessTimeUpdates" if (DaysBetweenAccessTimeUpdates > 0 && (DateTime.UtcNow - Utils.UnixTimeToDateTime(AccessTime)).TotalDays < DaysBetweenAccessTimeUpdates) return; - cmd.CommandText = String.Format("UPDATE {0} SET `access_time` = UNIX_TIMESTAMP() WHERE `id` = ?id", m_Table); - - cmd.ExecuteNonQuery(); - } + using (MySqlConnection conn = new MySqlConnection(m_ConnectionString)) + { + try + { + conn.Open(); + } + catch (MySqlException e) + { + m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString()); + return; + } - protected void FreeCommand(MySqlCommand cmd) - { - MySqlConnection c = cmd.Connection; - cmd.Dispose(); - c.Close(); - c.Dispose(); + using (MySqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = String.Format("UPDATE {0} SET `access_time` = UNIX_TIMESTAMP() WHERE `id` = ?id", m_Table); + cmd.Parameters.AddWithValue("?id", AssetID); + cmd.ExecuteNonQuery(); + } + conn.Close(); + } } public bool Store(AssetMetadata meta, string hash) @@ -238,37 +222,41 @@ namespace OpenSim.Data.MySQL string oldhash; AssetMetadata existingAsset = Get(meta.ID, out oldhash); - MySqlCommand cmd = m_Connection.CreateCommand(); - - cmd.Parameters.AddWithValue("?id", meta.ID); - cmd.Parameters.AddWithValue("?name", meta.Name); - cmd.Parameters.AddWithValue("?description", meta.Description); - cmd.Parameters.AddWithValue("?type", meta.Type.ToString()); - cmd.Parameters.AddWithValue("?hash", hash); - cmd.Parameters.AddWithValue("?asset_flags", meta.Flags); - - if (existingAsset == null) + using (MySqlCommand cmd = new MySqlCommand()) { - cmd.CommandText = String.Format("insert into {0} (id, name, description, type, hash, asset_flags, create_time, access_time) values ( ?id, ?name, ?description, ?type, ?hash, ?asset_flags, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())", m_Table); + cmd.Parameters.AddWithValue("?id", meta.ID); + cmd.Parameters.AddWithValue("?name", meta.Name); + cmd.Parameters.AddWithValue("?description", meta.Description); +// cmd.Parameters.AddWithValue("?type", meta.Type.ToString()); + cmd.Parameters.AddWithValue("?type", meta.Type); + cmd.Parameters.AddWithValue("?hash", hash); + cmd.Parameters.AddWithValue("?asset_flags", meta.Flags); + + if (existingAsset == null) + { + cmd.CommandText = String.Format("insert into {0} (id, name, description, type, hash, asset_flags, create_time, access_time) values ( ?id, ?name, ?description, ?type, ?hash, ?asset_flags, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())", m_Table); - ExecuteNonQuery(cmd); + ExecuteNonQuery(cmd); - cmd.Dispose(); + return true; + } - return true; - } + //cmd.CommandText = String.Format("update {0} set hash = ?hash, access_time = UNIX_TIMESTAMP() where id = ?id", m_Table); - //cmd.CommandText = String.Format("update {0} set hash = ?hash, access_time = UNIX_TIMESTAMP() where id = ?id", m_Table); + //ExecuteNonQuery(cmd); - //ExecuteNonQuery(cmd); + } - cmd.Dispose(); - return false; +// return false; + // if the asset already exits + // assume it was already correctly stored + // or regions will keep retry. + return true; } catch(Exception e) { m_log.Error("[FSAssets] Failed to store asset with ID " + meta.ID); - m_log.Error(e.ToString()); + m_log.Error(e.ToString()); return false; } } @@ -283,26 +271,43 @@ namespace OpenSim.Data.MySQL if (uuids.Length == 0) return new bool[0]; + bool[] results = new bool[uuids.Length]; + for (int i = 0; i < uuids.Length; i++) + results[i] = false; + HashSet exists = new HashSet(); string ids = "'" + string.Join("','", uuids) + "'"; string sql = string.Format("select id from {1} where id in ({0})", ids, m_Table); - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using (MySqlConnection conn = new MySqlConnection(m_ConnectionString)) { - cmd.CommandText = sql; + try + { + conn.Open(); + } + catch (MySqlException e) + { + m_log.ErrorFormat("[FSASSETS]: Failed to open database: {0}", e.ToString()); + return results; + } - using (MySqlDataReader dbReader = cmd.ExecuteReader()) + using (MySqlCommand cmd = conn.CreateCommand()) { - while (dbReader.Read()) + cmd.CommandText = sql; + + using (MySqlDataReader dbReader = cmd.ExecuteReader()) { - UUID id = DBGuid.FromDB(dbReader["ID"]); - exists.Add(id); + while (dbReader.Read()) + { + UUID id = DBGuid.FromDB(dbReader["ID"]); + exists.Add(id); + } } } + conn.Close(); } - bool[] results = new bool[uuids.Length]; for (int i = 0; i < uuids.Length; i++) results[i] = exists.Contains(uuids[i]); return results; @@ -310,27 +315,43 @@ namespace OpenSim.Data.MySQL public int Count() { - MySqlCommand cmd = m_Connection.CreateCommand(); + int count = 0; - cmd.CommandText = String.Format("select count(*) as count from {0}", m_Table); - - IDataReader reader = ExecuteReader(cmd); + using (MySqlConnection conn = new MySqlConnection(m_ConnectionString)) + { + try + { + conn.Open(); + } + catch (MySqlException e) + { + m_log.ErrorFormat("[FSASSETS]: Failed to open database: {0}", e.ToString()); + return 0; + } - reader.Read(); + using(MySqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = String.Format("select count(*) as count from {0}",m_Table); - int count = Convert.ToInt32(reader["count"]); + using (IDataReader reader = cmd.ExecuteReader()) + { + reader.Read(); - reader.Close(); - FreeCommand(cmd); + count = Convert.ToInt32(reader["count"]); + } + } + conn.Close(); + } return count; } public bool Delete(string id) { - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using(MySqlCommand cmd = new MySqlCommand()) { - cmd.CommandText = String.Format("delete from {0} where id = ?id", m_Table); + + cmd.CommandText = String.Format("delete from {0} where id = ?id",m_Table); cmd.Parameters.AddWithValue("?id", id); @@ -342,70 +363,68 @@ namespace OpenSim.Data.MySQL public void Import(string conn, string table, int start, int count, bool force, FSStoreDelegate store) { - MySqlConnection importConn; - - try - { - importConn = new MySqlConnection(conn); + int imported = 0; - importConn.Open(); - } - catch (MySqlException e) + using (MySqlConnection importConn = new MySqlConnection(conn)) { - m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}", - e.Message.ToString()); - - return; - } + try + { + importConn.Open(); + } + catch (MySqlException e) + { + m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}", + e.Message.ToString()); - int imported = 0; + return; + } - MySqlCommand cmd = importConn.CreateCommand(); + using (MySqlCommand cmd = importConn.CreateCommand()) + { + string limit = String.Empty; + if (count != -1) + { + limit = String.Format(" limit {0},{1}", start, count); + } - string limit = String.Empty; - if (count != -1) - { - limit = String.Format(" limit {0},{1}", start, count); - } - - cmd.CommandText = String.Format("select * from {0}{1}", table, limit); + cmd.CommandText = String.Format("select * from {0}{1}", table, limit); - MainConsole.Instance.Output("Querying database"); - IDataReader reader = cmd.ExecuteReader(); + MainConsole.Instance.Output("Querying database"); + using (IDataReader reader = cmd.ExecuteReader()) + { + MainConsole.Instance.Output("Reading data"); - MainConsole.Instance.Output("Reading data"); + while (reader.Read()) + { + if ((imported % 100) == 0) + { + MainConsole.Instance.Output(String.Format("{0} assets imported so far", imported)); + } - while (reader.Read()) - { - if ((imported % 100) == 0) - { - MainConsole.Instance.Output(String.Format("{0} assets imported so far", imported)); - } - - AssetBase asset = new AssetBase(); - AssetMetadata meta = new AssetMetadata(); + AssetBase asset = new AssetBase(); + AssetMetadata meta = new AssetMetadata(); - meta.ID = reader["id"].ToString(); - meta.FullID = new UUID(meta.ID); + meta.ID = reader["id"].ToString(); + meta.FullID = new UUID(meta.ID); - meta.Name = reader["name"].ToString(); - meta.Description = reader["description"].ToString(); - meta.Type = (sbyte)Convert.ToInt32(reader["assetType"]); - meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type); - meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"])); + meta.Name = reader["name"].ToString(); + meta.Description = reader["description"].ToString(); + meta.Type = (sbyte)Convert.ToInt32(reader["assetType"]); + meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type); + meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"])); - asset.Metadata = meta; - asset.Data = (byte[])reader["data"]; + asset.Metadata = meta; + asset.Data = (byte[])reader["data"]; - store(asset, force); + store(asset, force); - imported++; + imported++; + } + } + } + importConn.Close(); } - reader.Close(); - cmd.Dispose(); - importConn.Close(); - MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported)); } diff --git a/OpenSim/Data/MySQL/MySQLFramework.cs b/OpenSim/Data/MySQL/MySQLFramework.cs index 5820a90..98106f0 100644 --- a/OpenSim/Data/MySQL/MySQLFramework.cs +++ b/OpenSim/Data/MySQL/MySQLFramework.cs @@ -36,7 +36,7 @@ using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL { /// - /// A database interface class to a user profile storage system + /// Common code for a number of database modules /// public class MySqlFramework { @@ -44,30 +44,78 @@ namespace OpenSim.Data.MySQL log4net.LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - protected string m_connectionString; + protected string m_connectionString = String.Empty; + protected MySqlTransaction m_trans = null; + // Constructor using a connection string. Instances constructed + // this way will open a new connection for each call. protected MySqlFramework(string connectionString) { m_connectionString = connectionString; } + // Constructor using a connection object. Instances constructed + // this way will use the connection object and never create + // new connections. + protected MySqlFramework(MySqlTransaction trans) + { + m_trans = trans; + } + + ////////////////////////////////////////////////////////////// + // + // All non queries are funneled through one connection + // to increase performance a little + // protected int ExecuteNonQuery(MySqlCommand cmd) { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + if (m_trans == null) + { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + int ret = ExecuteNonQueryWithConnection(cmd, dbcon); + dbcon.Close(); + return ret; + } + } + else + { + return ExecuteNonQueryWithTransaction(cmd, m_trans); + } + } + + private int ExecuteNonQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans) + { + cmd.Transaction = trans; + return ExecuteNonQueryWithConnection(cmd, trans.Connection); + } + + private int ExecuteNonQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon) + { + try { - dbcon.Open(); cmd.Connection = dbcon; try { - return cmd.ExecuteNonQuery(); + int ret = cmd.ExecuteNonQuery(); + cmd.Connection = null; + return ret; } catch (Exception e) { m_log.Error(e.Message, e); + m_log.Error(Environment.StackTrace.ToString()); + cmd.Connection = null; return 0; } } + catch (Exception e) + { + m_log.Error(e.Message, e); + return 0; + } } } -} \ No newline at end of file +} diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index 35fa89f..9bd3c0c 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -40,7 +40,7 @@ namespace OpenSim.Data.MySQL public class MySQLGenericTableHandler : MySqlFramework where T: class, new() { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + protected Dictionary m_Fields = new Dictionary(); @@ -53,14 +53,27 @@ namespace OpenSim.Data.MySQL get { return GetType().Assembly; } } + public MySQLGenericTableHandler(MySqlTransaction trans, + string realm, string storeName) : base(trans) + { + m_Realm = realm; + + CommonConstruct(storeName); + } + public MySQLGenericTableHandler(string connectionString, string realm, string storeName) : base(connectionString) { m_Realm = realm; - m_connectionString = connectionString; - + + CommonConstruct(storeName); + } + + protected void CommonConstruct(string storeName) + { if (storeName != String.Empty) { + // We always use a new connection for any Migrations using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); @@ -111,6 +124,11 @@ namespace OpenSim.Data.MySQL public virtual T[] Get(string[] fields, string[] keys) { + return Get(fields, keys, String.Empty); + } + + public virtual T[] Get(string[] fields, string[] keys, string options) + { if (fields.Length != keys.Length) return new T[0]; @@ -126,81 +144,107 @@ namespace OpenSim.Data.MySQL string where = String.Join(" and ", terms.ToArray()); - string query = String.Format("select * from {0} where {1}", - m_Realm, where); + string query = String.Format("select * from {0} where {1} {2}", + m_Realm, where, options); cmd.CommandText = query; - + return DoQuery(cmd); } } protected T[] DoQuery(MySqlCommand cmd) { + if (m_trans == null) + { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + T[] ret = DoQueryWithConnection(cmd, dbcon); + dbcon.Close(); + return ret; + } + } + else + { + return DoQueryWithTransaction(cmd, m_trans); + } + } + + protected T[] DoQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans) + { + cmd.Transaction = trans; + + return DoQueryWithConnection(cmd, trans.Connection); + } + + protected T[] DoQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon) + { List result = new List(); - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + cmd.Connection = dbcon; + + using (IDataReader reader = cmd.ExecuteReader()) { - dbcon.Open(); - cmd.Connection = dbcon; + if (reader == null) + return new T[0]; - using (IDataReader reader = cmd.ExecuteReader()) - { - if (reader == null) - return new T[0]; + CheckColumnNames(reader); - CheckColumnNames(reader); + while (reader.Read()) + { + T row = new T(); - while (reader.Read()) + foreach (string name in m_Fields.Keys) { - T row = new T(); - - foreach (string name in m_Fields.Keys) + if (reader[name] is DBNull) + { + continue; + } + if (m_Fields[name].FieldType == typeof(bool)) + { + int v = Convert.ToInt32(reader[name]); + m_Fields[name].SetValue(row, v != 0 ? true : false); + } + else if (m_Fields[name].FieldType == typeof(UUID)) { - if (reader[name] is DBNull) - { - continue; - } - if (m_Fields[name].FieldType == typeof(bool)) - { - int v = Convert.ToInt32(reader[name]); - m_Fields[name].SetValue(row, v != 0 ? true : false); - } - else if (m_Fields[name].FieldType == typeof(UUID)) - { - m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name])); - } - else if (m_Fields[name].FieldType == typeof(int)) - { - int v = Convert.ToInt32(reader[name]); - m_Fields[name].SetValue(row, v); - } - else - { - m_Fields[name].SetValue(row, reader[name]); - } + m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name])); } - - if (m_DataField != null) + else if (m_Fields[name].FieldType == typeof(int)) { - Dictionary data = - new Dictionary(); + int v = Convert.ToInt32(reader[name]); + m_Fields[name].SetValue(row, v); + } + else if (m_Fields[name].FieldType == typeof(uint)) + { + uint v = Convert.ToUInt32(reader[name]); + m_Fields[name].SetValue(row, v); + } + else + { + m_Fields[name].SetValue(row, reader[name]); + } + } - foreach (string col in m_ColumnNames) - { - data[col] = reader[col].ToString(); - if (data[col] == null) - data[col] = String.Empty; - } + if (m_DataField != null) + { + Dictionary data = + new Dictionary(); - m_DataField.SetValue(row, data); + foreach (string col in m_ColumnNames) + { + data[col] = reader[col].ToString(); + if (data[col] == null) + data[col] = String.Empty; } - result.Add(row); + m_DataField.SetValue(row, data); } + + result.Add(row); } } - + cmd.Connection = null; return result.ToArray(); } @@ -210,9 +254,9 @@ namespace OpenSim.Data.MySQL { string query = String.Format("select * from {0} where {1}", m_Realm, where); - + cmd.CommandText = query; - + return DoQuery(cmd); } } @@ -231,16 +275,16 @@ namespace OpenSim.Data.MySQL { names.Add(fi.Name); values.Add("?" + fi.Name); - + // Temporarily return more information about what field is unexpectedly null for - // http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the + // http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the // InventoryTransferModule or we may be required to substitute a DBNull here. if (fi.GetValue(row) == null) throw new NullReferenceException( string.Format( - "[MYSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null", + "[MYSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null", fi.Name, row)); - + cmd.Parameters.AddWithValue(fi.Name, fi.GetValue(row).ToString()); } @@ -352,14 +396,26 @@ namespace OpenSim.Data.MySQL public object DoQueryScalar(MySqlCommand cmd) { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + if (m_trans == null) { - dbcon.Open(); - cmd.Connection = dbcon; + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + cmd.Connection = dbcon; + + Object ret = cmd.ExecuteScalar(); + cmd.Connection = null; + dbcon.Close(); + return ret; + } + } + else + { + cmd.Connection = m_trans.Connection; + cmd.Transaction = m_trans; return cmd.ExecuteScalar(); } } - } -} \ No newline at end of file +} diff --git a/OpenSim/Data/MySQL/MySQLGroupsData.cs b/OpenSim/Data/MySQL/MySQLGroupsData.cs index afa499e..4e73ee7 100644 --- a/OpenSim/Data/MySQL/MySQLGroupsData.cs +++ b/OpenSim/Data/MySQL/MySQLGroupsData.cs @@ -133,10 +133,10 @@ namespace OpenSim.Data.MySQL public bool DeleteMember(UUID groupID, string pricipalID) { - return m_Membership.Delete(new string[] { "GroupID", "PrincipalID" }, + return m_Membership.Delete(new string[] { "GroupID", "PrincipalID" }, new string[] { groupID.ToString(), pricipalID }); } - + public int MemberCount(UUID groupID) { return (int)m_Membership.GetCount("GroupID", groupID.ToString()); @@ -168,7 +168,7 @@ namespace OpenSim.Data.MySQL public bool DeleteRole(UUID groupID, UUID roleID) { - return m_Roles.Delete(new string[] { "GroupID", "RoleID" }, + return m_Roles.Delete(new string[] { "GroupID", "RoleID" }, new string[] { groupID.ToString(), roleID.ToString() }); } @@ -360,7 +360,7 @@ namespace OpenSim.Data.MySQL get { return GetType().Assembly; } } - public MySqlGroupsGroupsHandler(string connectionString, string realm, string store) + public MySqlGroupsGroupsHandler(string connectionString, string realm, string store) : base(connectionString, realm, store) { } @@ -375,7 +375,7 @@ namespace OpenSim.Data.MySQL get { return GetType().Assembly; } } - public MySqlGroupsMembershipHandler(string connectionString, string realm) + public MySqlGroupsMembershipHandler(string connectionString, string realm) : base(connectionString, realm, string.Empty) { } @@ -390,7 +390,7 @@ namespace OpenSim.Data.MySQL get { return GetType().Assembly; } } - public MySqlGroupsRolesHandler(string connectionString, string realm) + public MySqlGroupsRolesHandler(string connectionString, string realm) : base(connectionString, realm, string.Empty) { } @@ -405,7 +405,7 @@ namespace OpenSim.Data.MySQL get { return GetType().Assembly; } } - public MySqlGroupsRoleMembershipHandler(string connectionString, string realm) + public MySqlGroupsRoleMembershipHandler(string connectionString, string realm) : base(connectionString, realm, string.Empty) { } @@ -420,7 +420,7 @@ namespace OpenSim.Data.MySQL get { return GetType().Assembly; } } - public MySqlGroupsInvitesHandler(string connectionString, string realm) + public MySqlGroupsInvitesHandler(string connectionString, string realm) : base(connectionString, realm, string.Empty) { } @@ -431,8 +431,7 @@ namespace OpenSim.Data.MySQL using (MySqlCommand cmd = new MySqlCommand()) { - cmd.CommandText = String.Format("delete from {0} where TMStamp < ?tstamp", m_Realm); - cmd.Parameters.AddWithValue("?tstamp", now - 14 * 24 * 60 * 60); // > 2 weeks old + cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 WEEK", m_Realm); ExecuteNonQuery(cmd); } @@ -448,7 +447,7 @@ namespace OpenSim.Data.MySQL get { return GetType().Assembly; } } - public MySqlGroupsNoticesHandler(string connectionString, string realm) + public MySqlGroupsNoticesHandler(string connectionString, string realm) : base(connectionString, realm, string.Empty) { } @@ -476,7 +475,7 @@ namespace OpenSim.Data.MySQL get { return GetType().Assembly; } } - public MySqlGroupsPrincipalsHandler(string connectionString, string realm) + public MySqlGroupsPrincipalsHandler(string connectionString, string realm) : base(connectionString, realm, string.Empty) { } diff --git a/OpenSim/Data/MySQL/MySQLInventoryData.cs b/OpenSim/Data/MySQL/MySQLInventoryData.cs index e9b10f3..cc787cc 100644 --- a/OpenSim/Data/MySQL/MySQLInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLInventoryData.cs @@ -78,6 +78,7 @@ namespace OpenSim.Data.MySQL dbcon.Open(); Migration m = new Migration(dbcon, assem, "InventoryStore"); m.Update(); + dbcon.Close(); } } @@ -130,6 +131,7 @@ namespace OpenSim.Data.MySQL items.Add(item); } + dbcon.Close(); return items; } } @@ -170,6 +172,7 @@ namespace OpenSim.Data.MySQL while (reader.Read()) items.Add(readInventoryFolder(reader)); + dbcon.Close(); return items; } } @@ -221,6 +224,7 @@ namespace OpenSim.Data.MySQL if (items.Count > 0) rootFolder = items[0]; + dbcon.Close(); return rootFolder; } } @@ -261,6 +265,7 @@ namespace OpenSim.Data.MySQL while (reader.Read()) items.Add(readInventoryFolder(reader)); + dbcon.Close(); return items; } } @@ -288,7 +293,7 @@ namespace OpenSim.Data.MySQL // TODO: this is to handle a case where NULLs creep in there, which we are not sure is endemic to the system, or legacy. It would be nice to live fix these. // (DBGuid.FromDB() reads db NULLs as well, returns UUID.Zero) item.CreatorId = reader["creatorID"].ToString(); - + // Be a bit safer in parsing these because the // database doesn't enforce them to be not null, and // the inventory still works if these are weird in the @@ -352,6 +357,7 @@ namespace OpenSim.Data.MySQL if (reader.Read()) item = readInventoryItem(reader); + dbcon.Close(); return item; } } @@ -417,6 +423,7 @@ namespace OpenSim.Data.MySQL if (reader.Read()) folder = readInventoryFolder(reader); + dbcon.Close(); return folder; } } @@ -453,7 +460,7 @@ namespace OpenSim.Data.MySQL itemName = item.Name.Substring(0, 64); m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length + " to " + itemName.Length + " characters on add item"); } - + string itemDesc = item.Description; if (item.Description.Length > 128) { @@ -490,10 +497,10 @@ namespace OpenSim.Data.MySQL result.Parameters.AddWithValue("?groupID", item.GroupID); result.Parameters.AddWithValue("?groupOwned", item.GroupOwned); result.Parameters.AddWithValue("?flags", item.Flags); - + lock (m_dbLock) result.ExecuteNonQuery(); - + result.Dispose(); } @@ -504,6 +511,7 @@ namespace OpenSim.Data.MySQL lock (m_dbLock) result.ExecuteNonQuery(); } + dbcon.Close(); } } catch (MySqlException e) @@ -540,6 +548,7 @@ namespace OpenSim.Data.MySQL lock (m_dbLock) cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (MySqlException e) @@ -600,6 +609,7 @@ namespace OpenSim.Data.MySQL m_log.Error(e.ToString()); } } + dbcon.Close(); } } @@ -630,7 +640,7 @@ namespace OpenSim.Data.MySQL { cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString()); cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString()); - + try { lock (m_dbLock) @@ -643,6 +653,7 @@ namespace OpenSim.Data.MySQL m_log.Error(e.ToString()); } } + dbcon.Close(); } } @@ -806,6 +817,7 @@ namespace OpenSim.Data.MySQL lock (m_dbLock) cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (MySqlException e) @@ -833,6 +845,7 @@ namespace OpenSim.Data.MySQL lock (m_dbLock) cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (MySqlException e) @@ -860,7 +873,7 @@ namespace OpenSim.Data.MySQL deleteOneFolder(folderID); deleteItemsInFolder(folderID); } - + public List fetchActiveGestures(UUID avatarID) { lock (m_dbLock) @@ -886,6 +899,7 @@ namespace OpenSim.Data.MySQL if (item != null) list.Add(item); } + dbcon.Close(); return list; } } diff --git a/OpenSim/Data/MySQL/MySQLMigrations.cs b/OpenSim/Data/MySQL/MySQLMigrations.cs index 81a0e83..2043dae 100644 --- a/OpenSim/Data/MySQL/MySQLMigrations.cs +++ b/OpenSim/Data/MySQL/MySQLMigrations.cs @@ -39,16 +39,16 @@ namespace OpenSim.Data.MySQL { /// This is a MySQL-customized migration processor. The only difference is in how /// it executes SQL scripts (using MySqlScript instead of MyCommand) - /// + /// /// public class MySqlMigration : Migration { public MySqlMigration() : base() - { + { } - public MySqlMigration(DbConnection conn, Assembly assem, string subtype, string type) : + public MySqlMigration(DbConnection conn, Assembly assem, string subtype, string type) : base(conn, assem, subtype, type) { } diff --git a/OpenSim/Data/MySQL/MySQLMuteListData.cs b/OpenSim/Data/MySQL/MySQLMuteListData.cs new file mode 100644 index 0000000..a5935a3 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLMuteListData.cs @@ -0,0 +1,67 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using OpenMetaverse; +using OpenSim.Framework; +using MySql.Data.MySqlClient; + +namespace OpenSim.Data.MySQL +{ + public class MySqlMuteListData : MySQLGenericTableHandler, IMuteListData + { + public MySqlMuteListData(string connectionString) + : base(connectionString, "MuteList", "MuteListStore") + { + } + + public MuteData[] Get(UUID agentID) + { + MuteData[] data = base.Get("AgentID", agentID.ToString()); + return data; + } + + public bool Delete(UUID agentID, UUID muteID, string muteName) + { + string cmnd ="delete from MuteList where AgentID = ?AgentID and MuteID = ?MuteID and MuteName = ?MuteName"; + + using (MySqlCommand cmd = new MySqlCommand(cmnd)) + { + cmd.Parameters.AddWithValue("?AgentID", agentID.ToString()); + cmd.Parameters.AddWithValue("?MuteID", muteID.ToString()); + cmd.Parameters.AddWithValue("?MuteName", muteName); + + if (ExecuteNonQuery(cmd) > 0) + return true; + return false; + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Data/MySQL/MySQLOfflineIMData.cs b/OpenSim/Data/MySQL/MySQLOfflineIMData.cs index bafd204..7608858 100644 --- a/OpenSim/Data/MySQL/MySQLOfflineIMData.cs +++ b/OpenSim/Data/MySQL/MySQLOfflineIMData.cs @@ -50,7 +50,7 @@ namespace OpenSim.Data.MySQL using (MySqlCommand cmd = new MySqlCommand()) { cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 WEEK", m_Realm); - + ExecuteNonQuery(cmd); } diff --git a/OpenSim/Data/MySQL/MySQLPresenceData.cs b/OpenSim/Data/MySQL/MySQLPresenceData.cs index 3f90639..70aca5f 100644 --- a/OpenSim/Data/MySQL/MySQLPresenceData.cs +++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs @@ -66,9 +66,9 @@ namespace OpenSim.Data.MySQL using (MySqlCommand cmd = new MySqlCommand()) { cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm); - + cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); - + ExecuteNonQuery(cmd); } } @@ -85,10 +85,10 @@ namespace OpenSim.Data.MySQL using (MySqlCommand cmd = new MySqlCommand()) { cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm); - + cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString()); cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); - + if (ExecuteNonQuery(cmd) == 0) return false; } diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index 2ad7590..46df421 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -60,6 +60,7 @@ namespace OpenSim.Data.MySQL dbcon.Open(); Migration m = new Migration(dbcon, Assembly, "GridStore"); m.Update(); + dbcon.Close(); } } @@ -82,6 +83,7 @@ namespace OpenSim.Data.MySQL public RegionData Get(int posX, int posY, UUID scopeID) { +/* fixed size regions string command = "select * from `"+m_Realm+"` where locX = ?posX and locY = ?posY"; if (scopeID != UUID.Zero) command += " and ScopeID = ?scopeID"; @@ -98,6 +100,45 @@ namespace OpenSim.Data.MySQL return ret[0]; } +*/ + // extend database search for maximum region size area + string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY"; + if (scopeID != UUID.Zero) + command += " and ScopeID = ?scopeID"; + + int startX = posX - (int)Constants.MaximumRegionSize; + int startY = posY - (int)Constants.MaximumRegionSize; + int endX = posX; + int endY = posY; + + List ret; + using (MySqlCommand cmd = new MySqlCommand(command)) + { + cmd.Parameters.AddWithValue("?startX", startX.ToString()); + cmd.Parameters.AddWithValue("?startY", startY.ToString()); + cmd.Parameters.AddWithValue("?endX", endX.ToString()); + cmd.Parameters.AddWithValue("?endY", endY.ToString()); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + + ret = RunCommand(cmd); + } + + if (ret.Count == 0) + return null; + + // find the first that contains pos + RegionData rg = null; + foreach (RegionData r in ret) + { + if (posX >= r.posX && posX < r.posX + r.sizeX + && posY >= r.posY && posY < r.posY + r.sizeY) + { + rg = r; + break; + } + } + + return rg; } public RegionData Get(UUID regionID, UUID scopeID) @@ -121,6 +162,7 @@ namespace OpenSim.Data.MySQL public List Get(int startX, int startY, int endX, int endY, UUID scopeID) { +/* fix size regions string command = "select * from `"+m_Realm+"` where locX between ?startX and ?endX and locY between ?startY and ?endY"; if (scopeID != UUID.Zero) command += " and ScopeID = ?scopeID"; @@ -135,6 +177,38 @@ namespace OpenSim.Data.MySQL return RunCommand(cmd); } + */ + string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY"; + if (scopeID != UUID.Zero) + command += " and ScopeID = ?scopeID"; + + int qstartX = startX - (int)Constants.MaximumRegionSize; + int qstartY = startY - (int)Constants.MaximumRegionSize; + + List dbret; + using (MySqlCommand cmd = new MySqlCommand(command)) + { + cmd.Parameters.AddWithValue("?startX", qstartX.ToString()); + cmd.Parameters.AddWithValue("?startY", qstartY.ToString()); + cmd.Parameters.AddWithValue("?endX", endX.ToString()); + cmd.Parameters.AddWithValue("?endY", endY.ToString()); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + + dbret = RunCommand(cmd); + } + + List ret = new List(); + + if (dbret.Count == 0) + return ret; + + foreach (RegionData r in dbret) + { + if (r.posX + r.sizeX > startX && r.posX <= endX + && r.posY + r.sizeY > startY && r.posY <= endY) + ret.Add(r); + } + return ret; } public List RunCommand(MySqlCommand cmd) @@ -187,6 +261,8 @@ namespace OpenSim.Data.MySQL retList.Add(ret); } } + cmd.Connection = null; + dbcon.Close(); } return retList; @@ -337,7 +413,7 @@ namespace OpenSim.Data.MySQL using (MySqlCommand cmd = new MySqlCommand(command)) { cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); - + return RunCommand(cmd); } } diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index bb0ab75..e754522 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -55,7 +55,7 @@ namespace OpenSim.Data.MySQL /// /// This lock was being used to serialize database operations when the connection was shared, but this has /// been unnecessary for a long time after we switched to using MySQL's underlying connection pooling instead. - /// FIXME: However, the locks remain in many places since they are effectively providing a level of + /// FIXME: However, the locks remain in many places since they are effectively providing a level of /// transactionality. This should be replaced by more efficient database transactions which would not require /// unrelated operations to block each other or unrelated operations on the same tables from blocking each /// other. @@ -76,7 +76,7 @@ namespace OpenSim.Data.MySQL Initialise(connectionString); } - public void Initialise(string connectionString) + public virtual void Initialise(string connectionString) { m_connectionString = connectionString; @@ -88,6 +88,7 @@ namespace OpenSim.Data.MySQL // Migration m = new Migration(dbcon, Assembly, "RegionStore"); m.Update(); + dbcon.Close(); } } @@ -123,7 +124,7 @@ namespace OpenSim.Data.MySQL public void Dispose() {} - public void StoreObject(SceneObjectGroup obj, UUID regionUUID) + public virtual void StoreObject(SceneObjectGroup obj, UUID regionUUID) { uint flags = obj.RootPart.GetEffectiveObjectFlags(); @@ -167,7 +168,7 @@ namespace OpenSim.Data.MySQL "SitTargetOrientY, SitTargetOrientZ, " + "RegionUUID, CreatorID, " + "OwnerID, GroupID, " + - "LastOwnerID, SceneGroupID, " + + "LastOwnerID, RezzerID, SceneGroupID, " + "PayPrice, PayButton1, " + "PayButton2, PayButton3, " + "PayButton4, LoopedSound, " + @@ -183,10 +184,12 @@ namespace OpenSim.Data.MySQL "ParticleSystem, ClickAction, Material, " + "CollisionSound, CollisionSoundVolume, " + "PassTouches, " + - "LinkNumber, MediaURL, AttachedPosX, " + - "AttachedPosY, AttachedPosZ, KeyframeMotion, " + + "PassCollisions, " + + "LinkNumber, MediaURL, KeyframeMotion, AttachedPosX, " + + "AttachedPosY, AttachedPosZ, " + "PhysicsShapeType, Density, GravityModifier, " + - "Friction, Restitution, DynAttrs " + + "Friction, Restitution, Vehicle, PhysInertia, DynAttrs, " + + "RotationAxisLocks" + ") values (" + "?UUID, " + "?CreationDate, ?Name, ?Text, " + "?Description, ?SitName, ?TouchName, " + @@ -205,7 +208,7 @@ namespace OpenSim.Data.MySQL "?SitTargetOrientW, ?SitTargetOrientX, " + "?SitTargetOrientY, ?SitTargetOrientZ, " + "?RegionUUID, ?CreatorID, ?OwnerID, " + - "?GroupID, ?LastOwnerID, ?SceneGroupID, " + + "?GroupID, ?LastOwnerID, ?RezzerID, ?SceneGroupID, " + "?PayPrice, ?PayButton1, ?PayButton2, " + "?PayButton3, ?PayButton4, ?LoopedSound, " + "?LoopedSoundGain, ?TextureAnimation, " + @@ -218,11 +221,12 @@ namespace OpenSim.Data.MySQL "?SaleType, ?ColorR, ?ColorG, " + "?ColorB, ?ColorA, ?ParticleSystem, " + "?ClickAction, ?Material, ?CollisionSound, " + - "?CollisionSoundVolume, ?PassTouches, " + - "?LinkNumber, ?MediaURL, ?AttachedPosX, " + - "?AttachedPosY, ?AttachedPosZ, ?KeyframeMotion, " + + "?CollisionSoundVolume, ?PassTouches, ?PassCollisions, " + + "?LinkNumber, ?MediaURL, ?KeyframeMotion, ?AttachedPosX, " + + "?AttachedPosY, ?AttachedPosZ, " + "?PhysicsShapeType, ?Density, ?GravityModifier, " + - "?Friction, ?Restitution, ?DynAttrs)"; + "?Friction, ?Restitution, ?Vehicle, ?PhysInertia, ?DynAttrs," + + "?RotationAxisLocks)"; FillPrimCommand(cmd, prim, obj.UUID, regionUUID); @@ -258,14 +262,15 @@ namespace OpenSim.Data.MySQL ExecuteNonQuery(cmd); } } + dbcon.Close(); } } } - public void RemoveObject(UUID obj, UUID regionUUID) + public virtual void RemoveObject(UUID obj, UUID regionUUID) { // m_log.DebugFormat("[REGION DB]: Deleting scene object {0} from {1} in database", obj, regionUUID); - + List uuids = new List(); // Formerly, this used to check the region UUID. @@ -297,6 +302,7 @@ namespace OpenSim.Data.MySQL cmd.CommandText = "delete from prims where SceneGroupID= ?UUID"; ExecuteNonQuery(cmd); } + dbcon.Close(); } } @@ -317,7 +323,8 @@ namespace OpenSim.Data.MySQL /// the Item UUID private void RemoveItems(UUID uuid) { - lock (m_dbLock) + // locked by caller +// lock (m_dbLock) { using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { @@ -330,6 +337,7 @@ namespace OpenSim.Data.MySQL ExecuteNonQuery(cmd); } + dbcon.Close(); } } } @@ -368,6 +376,7 @@ namespace OpenSim.Data.MySQL ExecuteNonQuery(cmd); } + dbcon.Close(); } } } @@ -407,11 +416,12 @@ namespace OpenSim.Data.MySQL ExecuteNonQuery(cmd); } + dbcon.Close(); } } } - public List LoadObjects(UUID regionID) + public virtual List LoadObjects(UUID regionID) { const int ROWS_PER_QUERY = 5000; @@ -456,6 +466,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } @@ -505,7 +516,7 @@ namespace OpenSim.Data.MySQL #region Prim Inventory Loading // Instead of attempting to LoadItems on every prim, - // most of which probably have no items... get a + // most of which probably have no items... get a // list from DB of all prims which have items and // LoadItems only on those List primsWithInventory = new List(); @@ -531,6 +542,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } @@ -576,6 +588,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } prim.Inventory.RestoreInventoryItems(inventory); @@ -590,40 +603,102 @@ namespace OpenSim.Data.MySQL public void StoreTerrain(TerrainData terrData, UUID regionID) { - lock (m_dbLock) + Util.FireAndForget(delegate(object x) { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) - { - dbcon.Open(); + m_log.Info("[REGION DB]: Storing terrain"); - using (MySqlCommand cmd = dbcon.CreateCommand()) + int terrainDBRevision; + Array terrainDBblob; + terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); + + lock (m_dbLock) + { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID"; - cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + dbcon.Open(); - ExecuteNonQuery(cmd); + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID"; + cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); - int terrainDBRevision; - Array terrainDBblob; - terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); + using (MySqlCommand cmd2 = dbcon.CreateCommand()) + { + try + { + cmd2.CommandText = "insert into terrain (RegionUUID, " + + "Revision, Heightfield) values (?RegionUUID, " + + "?Revision, ?Heightfield)"; - m_log.InfoFormat("{0} Storing terrain. X={1}, Y={2}, rev={3}", - LogHeader, terrData.SizeX, terrData.SizeY, terrainDBRevision); + cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + cmd2.Parameters.AddWithValue("Revision", terrainDBRevision); + cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob); - cmd.CommandText = "insert into terrain (RegionUUID, Revision, Heightfield)" - + "values (?RegionUUID, ?Revision, ?Heightfield)"; + ExecuteNonQuery(cmd); + ExecuteNonQuery(cmd2); + } + catch (Exception e) + { + m_log.ErrorFormat(e.ToString()); + } + } + } + dbcon.Close(); + } + } + }); + } - cmd.Parameters.AddWithValue("Revision", terrainDBRevision); - cmd.Parameters.AddWithValue("Heightfield", terrainDBblob); + public void StoreBakedTerrain(TerrainData terrData, UUID regionID) + { + Util.FireAndForget(delegate(object x) + { + m_log.Info("[REGION DB]: Storing Baked terrain"); - ExecuteNonQuery(cmd); + int terrainDBRevision; + Array terrainDBblob; + terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); + + lock (m_dbLock) + { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "delete from bakedterrain where RegionUUID = ?RegionUUID"; + cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + + using (MySqlCommand cmd2 = dbcon.CreateCommand()) + { + try + { + cmd2.CommandText = "insert into bakedterrain (RegionUUID, " + + "Revision, Heightfield) values (?RegionUUID, " + + "?Revision, ?Heightfield)"; + + cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + cmd2.Parameters.AddWithValue("Revision", terrainDBRevision); + cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob); + + ExecuteNonQuery(cmd); + ExecuteNonQuery(cmd2); + } + catch (Exception e) + { + m_log.ErrorFormat(e.ToString()); + } + } + } + dbcon.Close(); } } - } + }); } // Legacy region loading - public double[,] LoadTerrain(UUID regionID) + public virtual double[,] LoadTerrain(UUID regionID) { double[,] ret = null; TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight); @@ -636,9 +711,12 @@ namespace OpenSim.Data.MySQL public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) { TerrainData terrData = null; + byte[] blob = null; + int rev = 0; lock (m_dbLock) { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); @@ -654,19 +732,64 @@ namespace OpenSim.Data.MySQL { while (reader.Read()) { - int rev = Convert.ToInt32(reader["Revision"]); - byte[] blob = (byte[])reader["Heightfield"]; - terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); + rev = Convert.ToInt32(reader["Revision"]); + if ((reader["Heightfield"] != DBNull.Value)) + { + blob = (byte[])reader["Heightfield"]; + } + } + } + } + dbcon.Close(); + } + } + + if(blob != null) + terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); + + return terrData; + } + + public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) + { + TerrainData terrData = null; + byte[] blob = null; + int rev = 0; + + lock (m_dbLock) + { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "select RegionUUID, Revision, Heightfield " + + "from bakedterrain where RegionUUID = ?RegionUUID "; + cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + + using (IDataReader reader = ExecuteReader(cmd)) + { + while (reader.Read()) + { + rev = Convert.ToInt32(reader["Revision"]); + if ((reader["Heightfield"] != DBNull.Value)) + { + blob = (byte[])reader["Heightfield"]; + } } } } + dbcon.Close(); } } + if(blob != null) + terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); return terrData; } - public void RemoveLandObject(UUID globalID) + public virtual void RemoveLandObject(UUID globalID) { lock (m_dbLock) { @@ -681,11 +804,12 @@ namespace OpenSim.Data.MySQL ExecuteNonQuery(cmd); } + dbcon.Close(); } } } - public void StoreLandObject(ILandObject parcel) + public virtual void StoreLandObject(ILandObject parcel) { lock (m_dbLock) { @@ -705,7 +829,8 @@ namespace OpenSim.Data.MySQL "UserLocationX, UserLocationY, UserLocationZ, " + "UserLookAtX, UserLookAtY, UserLookAtZ, " + "AuthbuyerID, OtherCleanTime, Dwell, MediaType, MediaDescription, " + - "MediaSize, MediaLoop, ObscureMusic, ObscureMedia) values (" + + "MediaSize, MediaLoop, ObscureMusic, ObscureMedia, " + + "SeeAVs, AnyAVSounds, GroupAVSounds) values (" + "?UUID, ?RegionUUID, " + "?LocalLandID, ?Bitmap, ?Name, ?Description, " + "?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " + @@ -716,7 +841,8 @@ namespace OpenSim.Data.MySQL "?UserLocationX, ?UserLocationY, ?UserLocationZ, " + "?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " + "?AuthbuyerID, ?OtherCleanTime, ?Dwell, ?MediaType, ?MediaDescription, "+ - "CONCAT(?MediaWidth, ',', ?MediaHeight), ?MediaLoop, ?ObscureMusic, ?ObscureMedia)"; + "CONCAT(?MediaWidth, ',', ?MediaHeight), ?MediaLoop, ?ObscureMusic, ?ObscureMedia, " + + "?SeeAVs, ?AnyAVSounds, ?GroupAVSounds)"; FillLandCommand(cmd, parcel.LandData, parcel.RegionUUID); @@ -738,11 +864,12 @@ namespace OpenSim.Data.MySQL cmd.Parameters.Clear(); } } + dbcon.Close(); } } } - public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) + public virtual RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) { RegionLightShareData nWP = new RegionLightShareData(); nWP.OnSave += StoreRegionWindlightSettings; @@ -759,90 +886,94 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString()); - IDataReader result = ExecuteReader(cmd); - if (!result.Read()) + using(IDataReader result = ExecuteReader(cmd)) { - //No result, so store our default windlight profile and return it - nWP.regionID = regionUUID; -// StoreRegionWindlightSettings(nWP); - return nWP; - } - else - { - nWP.regionID = DBGuid.FromDB(result["region_id"]); - nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); - nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); - nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); - nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); - nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); - nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); - nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); - nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); - nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); - nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); - nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); - nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); - nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); - nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); - nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); - nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); - nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); - UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture); - nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); - nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); - nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); - nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); - nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); - nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); - nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); - nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); - nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); - nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); - nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); - nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); - nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); - nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); - nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); - nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); - nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); - nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); - nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); - nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); - nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); - nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); - nWP.eastAngle = Convert.ToSingle(result["east_angle"]); - nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); - nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); - nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); - nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); - nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); - nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); - nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); - nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); - nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); - nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); - nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); - nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); - nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); - nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); - nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); - nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); - nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); - nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); - nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); - nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); - nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); - nWP.valid = true; + if(!result.Read()) + { + //No result, so store our default windlight profile and return it + nWP.regionID = regionUUID; + // StoreRegionWindlightSettings(nWP); + return nWP; + } + else + { + nWP.regionID = DBGuid.FromDB(result["region_id"]); + nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); + nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); + nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); + nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); + nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); + nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); + nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); + nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); + nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); + nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); + nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); + nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); + nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); + nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); + nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); + nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); + nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); + UUID.TryParse(result["normal_map_texture"].ToString(),out nWP.normalMapTexture); + nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); + nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); + nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); + nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); + nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); + nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); + nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); + nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); + nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); + nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); + nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); + nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); + nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); + nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); + nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); + nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); + nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); + nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); + nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); + nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); + nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); + nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); + nWP.eastAngle = Convert.ToSingle(result["east_angle"]); + nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); + nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); + nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); + nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); + nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); + nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); + nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); + nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); + nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); + nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); + nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); + nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); + nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); + nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); + nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); + nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); + nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); + nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); + nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); + nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); + nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); + nWP.valid = true; + } } } + dbcon.Close(); } return nWP; } - public RegionSettings LoadRegionSettings(UUID regionUUID) + public virtual RegionSettings LoadRegionSettings(UUID regionUUID) { RegionSettings rs = null; + bool needStore = false; lock (m_dbLock) { @@ -868,19 +999,23 @@ namespace OpenSim.Data.MySQL rs.RegionUUID = regionUUID; rs.OnSave += StoreRegionSettings; - StoreRegionSettings(rs); + needStore = true; } } } + dbcon.Close(); } } + if(needStore) + StoreRegionSettings(rs); + LoadSpawnPoints(rs); return rs; } - public void StoreRegionWindlightSettings(RegionLightShareData wl) + public virtual void StoreRegionWindlightSettings(RegionLightShareData wl) { using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { @@ -888,31 +1023,32 @@ namespace OpenSim.Data.MySQL using (MySqlCommand cmd = dbcon.CreateCommand()) { - cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, "; - cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, "; - cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, "; - cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, "; - cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, "; - cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, "; - cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, "; - cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, "; - cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, "; - cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, "; - cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, "; - cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, "; - cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, "; - cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, "; - cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, "; - cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, "; - cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, "; - cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, "; - cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, "; - cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, "; - cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, "; - cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, "; - cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, "; - cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, "; - cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)"; + cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, " + + "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, " + + "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, " + + "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, " + + "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, " + + "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, " + + "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, " + + "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, " + + "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, " + + "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, " + + "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, " + + "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, " + + "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, " + + "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, " + + "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, " + + "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, " + + "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, " + + "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, " + + "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, " + + "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, " + + "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, " + + "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, " + + "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, " + + "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, " + + "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)" + ; cmd.Parameters.AddWithValue("region_id", wl.regionID); cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X); @@ -977,13 +1113,14 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY); cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock); cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds); - + ExecuteNonQuery(cmd); } + dbcon.Close(); } } - public void RemoveRegionWindlightSettings(UUID regionID) + public virtual void RemoveRegionWindlightSettings(UUID regionID) { using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { @@ -995,6 +1132,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); ExecuteNonQuery(cmd); } + dbcon.Close(); } } @@ -1013,14 +1151,19 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); - IDataReader result = ExecuteReader(cmd); - if (!result.Read()) + using(IDataReader result = ExecuteReader(cmd)) { - return String.Empty; - } - else - { - return Convert.ToString(result["llsd_settings"]); + if(!result.Read()) + { + dbcon.Close(); + return String.Empty; + } + else + { + string ret = Convert.ToString(result["llsd_settings"]); + dbcon.Close(); + return ret; + } } } } @@ -1041,6 +1184,7 @@ namespace OpenSim.Data.MySQL ExecuteNonQuery(cmd); } + dbcon.Close(); } } @@ -1056,11 +1200,12 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); ExecuteNonQuery(cmd); } + dbcon.Close(); } } #endregion - public void StoreRegionSettings(RegionSettings rs) + public virtual void StoreRegionSettings(RegionSettings rs) { using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { @@ -1069,52 +1214,51 @@ namespace OpenSim.Data.MySQL using (MySqlCommand cmd = dbcon.CreateCommand()) { cmd.CommandText = "replace into regionsettings (regionUUID, " + - "block_terraform, block_fly, allow_damage, " + - "restrict_pushing, allow_land_resell, " + - "allow_land_join_divide, block_show_in_search, " + - "agent_limit, object_bonus, maturity, " + - "disable_scripts, disable_collisions, " + - "disable_physics, terrain_texture_1, " + - "terrain_texture_2, terrain_texture_3, " + - "terrain_texture_4, elevation_1_nw, " + - "elevation_2_nw, elevation_1_ne, " + - "elevation_2_ne, elevation_1_se, " + - "elevation_2_se, elevation_1_sw, " + - "elevation_2_sw, water_height, " + - "terrain_raise_limit, terrain_lower_limit, " + - "use_estate_sun, fixed_sun, sun_position, " + - "covenant, covenant_datetime, Sandbox, sunvectorx, sunvectory, " + - "sunvectorz, loaded_creation_datetime, " + - "loaded_creation_id, map_tile_ID, " + - "TelehubObject, parcel_tile_ID) " + - "values (?RegionUUID, ?BlockTerraform, " + - "?BlockFly, ?AllowDamage, ?RestrictPushing, " + - "?AllowLandResell, ?AllowLandJoinDivide, " + - "?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " + - "?Maturity, ?DisableScripts, ?DisableCollisions, " + - "?DisablePhysics, ?TerrainTexture1, " + - "?TerrainTexture2, ?TerrainTexture3, " + - "?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " + - "?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " + - "?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " + - "?WaterHeight, ?TerrainRaiseLimit, " + - "?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " + - "?SunPosition, ?Covenant, ?CovenantChangedDateTime, ?Sandbox, " + - "?SunVectorX, ?SunVectorY, ?SunVectorZ, " + - "?LoadedCreationDateTime, ?LoadedCreationID, " + - "?TerrainImageID, " + - "?TelehubObject, ?ParcelImageID)"; + "block_terraform, block_fly, allow_damage, " + + "restrict_pushing, allow_land_resell, " + + "allow_land_join_divide, block_show_in_search, " + + "agent_limit, object_bonus, maturity, " + + "disable_scripts, disable_collisions, " + + "disable_physics, terrain_texture_1, " + + "terrain_texture_2, terrain_texture_3, " + + "terrain_texture_4, elevation_1_nw, " + + "elevation_2_nw, elevation_1_ne, " + + "elevation_2_ne, elevation_1_se, " + + "elevation_2_se, elevation_1_sw, " + + "elevation_2_sw, water_height, " + + "terrain_raise_limit, terrain_lower_limit, " + + "use_estate_sun, fixed_sun, sun_position, " + + "covenant, covenant_datetime, Sandbox, sunvectorx, sunvectory, " + + "sunvectorz, loaded_creation_datetime, " + + "loaded_creation_id, map_tile_ID, block_search, casino, " + + "TelehubObject, parcel_tile_ID) " + + "values (?RegionUUID, ?BlockTerraform, " + + "?BlockFly, ?AllowDamage, ?RestrictPushing, " + + "?AllowLandResell, ?AllowLandJoinDivide, " + + "?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " + + "?Maturity, ?DisableScripts, ?DisableCollisions, " + + "?DisablePhysics, ?TerrainTexture1, " + + "?TerrainTexture2, ?TerrainTexture3, " + + "?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " + + "?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " + + "?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " + + "?WaterHeight, ?TerrainRaiseLimit, " + + "?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " + + "?SunPosition, ?Covenant, ?CovenantChangedDateTime, ?Sandbox, " + + "?SunVectorX, ?SunVectorY, ?SunVectorZ, " + + "?LoadedCreationDateTime, ?LoadedCreationID, " + + "?TerrainImageID, ?block_search, ?casino, " + + "?TelehubObject, ?ParcelImageID)"; FillRegionSettingsCommand(cmd, rs); - ExecuteNonQuery(cmd); } + dbcon.Close(); + SaveSpawnPoints(rs); } - - SaveSpawnPoints(rs); } - public List LoadLandObjects(UUID regionUUID) + public virtual List LoadLandObjects(UUID regionUUID) { List landData = new List(); @@ -1156,6 +1300,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } @@ -1170,12 +1315,16 @@ namespace OpenSim.Data.MySQL { SceneObjectPart prim = new SceneObjectPart(); - // depending on the MySQL connector version, CHAR(36) may be already converted to Guid! + // depending on the MySQL connector version, CHAR(36) may be already converted to Guid! prim.UUID = DBGuid.FromDB(row["UUID"]); prim.CreatorIdentification = (string)row["CreatorID"]; prim.OwnerID = DBGuid.FromDB(row["OwnerID"]); prim.GroupID = DBGuid.FromDB(row["GroupID"]); prim.LastOwnerID = DBGuid.FromDB(row["LastOwnerID"]); + if (row["RezzerID"] != DBNull.Value) + prim.RezzerID = DBGuid.FromDB(row["RezzerID"]); + else + prim.RezzerID = UUID.Zero; // explicit conversion of integers is required, which sort // of sucks. No idea if there is a shortcut here or not. @@ -1294,10 +1443,11 @@ namespace OpenSim.Data.MySQL prim.CollisionSound = DBGuid.FromDB(row["CollisionSound"]); prim.CollisionSoundVolume = (float)(double)row["CollisionSoundVolume"]; - + prim.PassTouches = ((sbyte)row["PassTouches"] != 0); + prim.PassCollisions = ((sbyte)row["PassCollisions"] != 0); prim.LinkNum = (int)row["LinkNumber"]; - + if (!(row["MediaURL"] is System.DBNull)) prim.MediaUrl = (string)row["MediaURL"]; @@ -1313,7 +1463,7 @@ namespace OpenSim.Data.MySQL if (!(row["DynAttrs"] is System.DBNull)) prim.DynAttrs = DAMap.FromXml((string)row["DynAttrs"]); else - prim.DynAttrs = new DAMap(); + prim.DynAttrs = new DAMap(); if (!(row["KeyframeMotion"] is DBNull)) { @@ -1333,7 +1483,22 @@ namespace OpenSim.Data.MySQL prim.GravityModifier = (float)(double)row["GravityModifier"]; prim.Friction = (float)(double)row["Friction"]; prim.Restitution = (float)(double)row["Restitution"]; - + prim.RotationAxisLocks = (byte)Convert.ToInt32(row["RotationAxisLocks"].ToString()); + + SOPVehicle vehicle = null; + + if (row["Vehicle"].ToString() != String.Empty) + { + vehicle = SOPVehicle.FromXml2(row["Vehicle"].ToString()); + if (vehicle != null) + prim.VehicleParams = vehicle; + } + + PhysicsInertiaData pdata = null; + if (row["PhysInertia"].ToString() != String.Empty) + pdata = PhysicsInertiaData.FromXml2(row["PhysInertia"].ToString()); + prim.PhysicsInertia = pdata; + return prim; } @@ -1344,32 +1509,40 @@ namespace OpenSim.Data.MySQL /// private static TaskInventoryItem BuildItem(IDataReader row) { - TaskInventoryItem taskItem = new TaskInventoryItem(); - - taskItem.ItemID = DBGuid.FromDB(row["itemID"]); - taskItem.ParentPartID = DBGuid.FromDB(row["primID"]); - taskItem.AssetID = DBGuid.FromDB(row["assetID"]); - taskItem.ParentID = DBGuid.FromDB(row["parentFolderID"]); - - taskItem.InvType = Convert.ToInt32(row["invType"]); - taskItem.Type = Convert.ToInt32(row["assetType"]); - - taskItem.Name = (String)row["name"]; - taskItem.Description = (String)row["description"]; - taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); - taskItem.CreatorIdentification = (String)row["creatorID"]; - taskItem.OwnerID = DBGuid.FromDB(row["ownerID"]); - taskItem.LastOwnerID = DBGuid.FromDB(row["lastOwnerID"]); - taskItem.GroupID = DBGuid.FromDB(row["groupID"]); - - taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]); - taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]); - taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]); - taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]); - taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]); - taskItem.Flags = Convert.ToUInt32(row["flags"]); - - return taskItem; + try + { + TaskInventoryItem taskItem = new TaskInventoryItem(); + + taskItem.ItemID = DBGuid.FromDB(row["itemID"]); + taskItem.ParentPartID = DBGuid.FromDB(row["primID"]); + taskItem.AssetID = DBGuid.FromDB(row["assetID"]); + taskItem.ParentID = DBGuid.FromDB(row["parentFolderID"]); + + taskItem.InvType = Convert.ToInt32(row["invType"]); + taskItem.Type = Convert.ToInt32(row["assetType"]); + + taskItem.Name = (String)row["name"]; + taskItem.Description = (String)row["description"]; + taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); + taskItem.CreatorIdentification = (String)row["creatorID"]; + taskItem.OwnerID = DBGuid.FromDB(row["ownerID"]); + taskItem.LastOwnerID = DBGuid.FromDB(row["lastOwnerID"]); + taskItem.GroupID = DBGuid.FromDB(row["groupID"]); + + taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]); + taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]); + taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]); + taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]); + taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]); + taskItem.Flags = Convert.ToUInt32(row["flags"]); + + return taskItem; + } + catch + { + m_log.ErrorFormat("[MYSQL DB]: Error reading task inventory: itemID was {0}, primID was {1}", row["itemID"].ToString(), row["primID"].ToString()); + throw; + } } private static RegionSettings BuildRegionSettings(IDataReader row) @@ -1417,16 +1590,19 @@ namespace OpenSim.Data.MySQL newSettings.Covenant = DBGuid.FromDB(row["covenant"]); newSettings.CovenantChangedDateTime = Convert.ToInt32(row["covenant_datetime"]); newSettings.LoadedCreationDateTime = Convert.ToInt32(row["loaded_creation_datetime"]); - + if (row["loaded_creation_id"] is DBNull) newSettings.LoadedCreationID = ""; - else + else newSettings.LoadedCreationID = (String) row["loaded_creation_id"]; newSettings.TerrainImageID = DBGuid.FromDB(row["map_tile_ID"]); newSettings.ParcelImageID = DBGuid.FromDB(row["parcel_tile_ID"]); newSettings.TelehubObject = DBGuid.FromDB(row["TelehubObject"]); + newSettings.GodBlockSearch = Convert.ToBoolean(row["block_search"]); + newSettings.Casino = Convert.ToBoolean(row["casino"]); + return newSettings; } @@ -1503,6 +1679,13 @@ namespace OpenSim.Data.MySQL newData.ParcelAccessList = new List(); + if (!(row["SeeAVs"] is System.DBNull)) + newData.SeeAVs = Convert.ToInt32(row["SeeAVs"]) != 0 ? true : false; + if (!(row["AnyAVSounds"] is System.DBNull)) + newData.AnyAVSounds = Convert.ToInt32(row["AnyAVSounds"]) != 0 ? true : false; + if (!(row["GroupAVSounds"] is System.DBNull)) + newData.GroupAVSounds = Convert.ToInt32(row["GroupAVSounds"]) != 0 ? true : false; + return newData; } @@ -1550,6 +1733,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("OwnerID", prim.OwnerID.ToString()); cmd.Parameters.AddWithValue("GroupID", prim.GroupID.ToString()); cmd.Parameters.AddWithValue("LastOwnerID", prim.LastOwnerID.ToString()); + cmd.Parameters.AddWithValue("RezzerID", prim.RezzerID.ToString()); cmd.Parameters.AddWithValue("OwnerMask", prim.OwnerMask); cmd.Parameters.AddWithValue("NextOwnerMask", prim.NextOwnerMask); cmd.Parameters.AddWithValue("GroupMask", prim.GroupMask); @@ -1654,6 +1838,11 @@ namespace OpenSim.Data.MySQL else cmd.Parameters.AddWithValue("PassTouches", 0); + if (prim.PassCollisions) + cmd.Parameters.AddWithValue("PassCollisions", 1); + else + cmd.Parameters.AddWithValue("PassCollisions", 0); + cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl); if (prim.AttachedPos != null) @@ -1668,6 +1857,16 @@ namespace OpenSim.Data.MySQL else cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]); + if (prim.PhysicsInertia != null) + cmd.Parameters.AddWithValue("PhysInertia", prim.PhysicsInertia.ToXml2()); + else + cmd.Parameters.AddWithValue("PhysInertia", String.Empty); + + if (prim.VehicleParams != null) + cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2()); + else + cmd.Parameters.AddWithValue("Vehicle", String.Empty); + if (prim.DynAttrs.CountNamespaces > 0) cmd.Parameters.AddWithValue("DynAttrs", prim.DynAttrs.ToXml()); else @@ -1678,6 +1877,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("GravityModifier", (double)prim.GravityModifier); cmd.Parameters.AddWithValue("Friction", (double)prim.Friction); cmd.Parameters.AddWithValue("Restitution", (double)prim.Restitution); + cmd.Parameters.AddWithValue("RotationAxisLocks", prim.RotationAxisLocks); } /// @@ -1756,6 +1956,8 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("LoadedCreationDateTime", settings.LoadedCreationDateTime); cmd.Parameters.AddWithValue("LoadedCreationID", settings.LoadedCreationID); cmd.Parameters.AddWithValue("TerrainImageID", settings.TerrainImageID); + cmd.Parameters.AddWithValue("block_search", settings.GodBlockSearch); + cmd.Parameters.AddWithValue("casino", settings.Casino); cmd.Parameters.AddWithValue("ParcelImageID", settings.ParcelImageID); cmd.Parameters.AddWithValue("TelehubObject", settings.TelehubObject); @@ -1813,6 +2015,10 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("MediaLoop", land.MediaLoop); cmd.Parameters.AddWithValue("ObscureMusic", land.ObscureMusic); cmd.Parameters.AddWithValue("ObscureMedia", land.ObscureMedia); + cmd.Parameters.AddWithValue("SeeAVs", land.SeeAVs ? 1 : 0); + cmd.Parameters.AddWithValue("AnyAVSounds", land.AnyAVSounds ? 1 : 0); + cmd.Parameters.AddWithValue("GroupAVSounds", land.GroupAVSounds ? 1 : 0); + } /// @@ -1869,7 +2075,7 @@ namespace OpenSim.Data.MySQL s.State = (byte)(int)row["State"]; s.LastAttachPoint = (byte)(int)row["LastAttachPoint"]; - + if (!(row["Media"] is System.DBNull)) s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]); @@ -1919,7 +2125,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml()); } - public void StorePrimInventory(UUID primID, ICollection items) + public virtual void StorePrimInventory(UUID primID, ICollection items) { lock (m_dbLock) { @@ -1949,20 +2155,53 @@ namespace OpenSim.Data.MySQL "?flags, ?itemID, ?primID, ?assetID, " + "?parentFolderID, ?creatorID, ?ownerID, " + "?groupID, ?lastOwnerID)"; - + foreach (TaskInventoryItem item in items) { cmd.Parameters.Clear(); - + FillItemCommand(cmd, item); - + ExecuteNonQuery(cmd); } } + dbcon.Close(); } } } + public UUID[] GetObjectIDs(UUID regionID) + { + List uuids = new List(); + + lock (m_dbLock) + { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "select UUID from prims where RegionUUID = ?RegionUUID and SceneGroupID = UUID"; + cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + + using (IDataReader reader = ExecuteReader(cmd)) + { + while (reader.Read()) + { + UUID id = new UUID(reader["UUID"].ToString()); + + uuids.Add(id); + } + } + } + dbcon.Close(); + } + } + + return uuids.ToArray(); + } + private void LoadSpawnPoints(RegionSettings rs) { rs.ClearSpawnPoints(); @@ -1992,6 +2231,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } } @@ -2026,6 +2266,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.Clear(); } } + dbcon.Close(); } } } @@ -2045,6 +2286,7 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } } @@ -2062,6 +2304,7 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } } @@ -2085,6 +2328,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } return ret; diff --git a/OpenSim/Data/MySQL/MySQLUserAccountData.cs b/OpenSim/Data/MySQL/MySQLUserAccountData.cs index e964295..59cfe70 100644 --- a/OpenSim/Data/MySQL/MySQLUserAccountData.cs +++ b/OpenSim/Data/MySQL/MySQLUserAccountData.cs @@ -46,17 +46,21 @@ namespace OpenSim.Data.MySQL { string[] words = query.Split(new char[] {' '}); + bool valid = false; + for (int i = 0 ; i < words.Length ; i++) { - if (words[i].Length < 3) - { - if (i != words.Length - 1) - Array.Copy(words, i + 1, words, i, words.Length - i - 1); - Array.Resize(ref words, words.Length - 1); - } + if (words[i].Length > 2) + valid = true; +// if (words[i].Length < 3) +// { +// if (i != words.Length - 1) +// Array.Copy(words, i + 1, words, i, words.Length - i - 1); +// Array.Resize(ref words, words.Length - 1); +// } } - if (words.Length == 0) + if ((!valid) || words.Length == 0) return new UserAccountData[0]; if (words.Length > 2) @@ -66,13 +70,13 @@ namespace OpenSim.Data.MySQL { if (words.Length == 1) { - cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search)", m_Realm); + cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search) and active=1", m_Realm); cmd.Parameters.AddWithValue("?search", "%" + words[0] + "%"); cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString()); } else { - cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst or LastName like ?searchLast)", m_Realm); + cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst and LastName like ?searchLast) and active=1", m_Realm); cmd.Parameters.AddWithValue("?searchFirst", "%" + words[0] + "%"); cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%"); cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString()); @@ -81,5 +85,21 @@ namespace OpenSim.Data.MySQL return DoQuery(cmd); } } + + public UserAccountData[] GetUsersWhere(UUID scopeID, string where) + { + using (MySqlCommand cmd = new MySqlCommand()) + { + if (scopeID != UUID.Zero) + { + where = "(ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (" + where + ")"; + cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString()); + } + + cmd.CommandText = String.Format("select * from {0} where " + where, m_Realm); + + return DoQuery(cmd); + } + } } -} \ No newline at end of file +} diff --git a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs index b35595d..16637c3 100644 --- a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs +++ b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs @@ -40,39 +40,40 @@ namespace OpenSim.Data.MySQL public class UserProfilesData: IProfilesData { static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + #region Properites string ConnectionString { get; set; } - + protected virtual Assembly Assembly { get { return GetType().Assembly; } } - + #endregion Properties - + #region class Member Functions public UserProfilesData(string connectionString) { ConnectionString = connectionString; Init(); } - + void Init() { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) { dbcon.Open(); - + Migration m = new Migration(dbcon, Assembly, "UserProfiles"); m.Update(); + dbcon.Close(); } } #endregion Member Functions - + #region Classifieds Queries /// /// Gets the classified records. @@ -86,10 +87,10 @@ namespace OpenSim.Data.MySQL public OSDArray GetClassifiedRecords(UUID creatorId) { OSDArray data = new OSDArray(); - + using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) { - string query = "SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = ?Id"; + const string query = "SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = ?Id"; dbcon.Open(); using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) { @@ -102,7 +103,7 @@ namespace OpenSim.Data.MySQL { OSDMap n = new OSDMap(); UUID Id = UUID.Zero; - + string Name = null; try { @@ -111,8 +112,7 @@ namespace OpenSim.Data.MySQL } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": UserAccount exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA] GetClassifiedRecords exception {0}", e.Message); } n.Add("classifieduuid", OSD.FromUUID(Id)); n.Add("name", OSD.FromString(Name)); @@ -121,73 +121,73 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } return data; } - + public bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result) { - string query = string.Empty; - - - query += "INSERT INTO classifieds ("; - query += "`classifieduuid`,"; - query += "`creatoruuid`,"; - query += "`creationdate`,"; - query += "`expirationdate`,"; - query += "`category`,"; - query += "`name`,"; - query += "`description`,"; - query += "`parceluuid`,"; - query += "`parentestate`,"; - query += "`snapshotuuid`,"; - query += "`simname`,"; - query += "`posglobal`,"; - query += "`parcelname`,"; - query += "`classifiedflags`,"; - query += "`priceforlisting`) "; - query += "VALUES ("; - query += "?ClassifiedId,"; - query += "?CreatorId,"; - query += "?CreatedDate,"; - query += "?ExpirationDate,"; - query += "?Category,"; - query += "?Name,"; - query += "?Description,"; - query += "?ParcelId,"; - query += "?ParentEstate,"; - query += "?SnapshotId,"; - query += "?SimName,"; - query += "?GlobalPos,"; - query += "?ParcelName,"; - query += "?Flags,"; - query += "?ListingPrice ) "; - query += "ON DUPLICATE KEY UPDATE "; - query += "category=?Category, "; - query += "expirationdate=?ExpirationDate, "; - query += "name=?Name, "; - query += "description=?Description, "; - query += "parentestate=?ParentEstate, "; - query += "posglobal=?GlobalPos, "; - query += "parcelname=?ParcelName, "; - query += "classifiedflags=?Flags, "; - query += "priceforlisting=?ListingPrice, "; - query += "snapshotuuid=?SnapshotId"; - + const string query = + "INSERT INTO classifieds (" + + "`classifieduuid`," + + "`creatoruuid`," + + "`creationdate`," + + "`expirationdate`," + + "`category`," + + "`name`," + + "`description`," + + "`parceluuid`," + + "`parentestate`," + + "`snapshotuuid`," + + "`simname`," + + "`posglobal`," + + "`parcelname`," + + "`classifiedflags`," + + "`priceforlisting`) " + + "VALUES (" + + "?ClassifiedId," + + "?CreatorId," + + "?CreatedDate," + + "?ExpirationDate," + + "?Category," + + "?Name," + + "?Description," + + "?ParcelId," + + "?ParentEstate," + + "?SnapshotId," + + "?SimName," + + "?GlobalPos," + + "?ParcelName," + + "?Flags," + + "?ListingPrice ) " + + "ON DUPLICATE KEY UPDATE " + + "category=?Category, " + + "expirationdate=?ExpirationDate, " + + "name=?Name, " + + "description=?Description, " + + "parentestate=?ParentEstate, " + + "posglobal=?GlobalPos, " + + "parcelname=?ParcelName, " + + "classifiedflags=?Flags, " + + "priceforlisting=?ListingPrice, " + + "snapshotuuid=?SnapshotId" + ; + if(string.IsNullOrEmpty(ad.ParcelName)) ad.ParcelName = "Unknown"; if(ad.ParcelId == null) ad.ParcelId = UUID.Zero; if(string.IsNullOrEmpty(ad.Description)) ad.Description = "No Description"; - + DateTime epoch = new DateTime(1970, 1, 1); DateTime now = DateTime.Now; TimeSpan epochnow = now - epoch; TimeSpan duration; DateTime expiration; TimeSpan epochexp; - + if(ad.Flags == 2) { duration = new TimeSpan(7,0,0,0); @@ -202,7 +202,7 @@ namespace OpenSim.Data.MySQL } ad.CreationDate = (int)epochnow.TotalSeconds; ad.ExpirationDate = (int)epochexp.TotalSeconds; - + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) @@ -225,57 +225,52 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?ParcelName", ad.ParcelName.ToString()); cmd.Parameters.AddWithValue("?Flags", ad.Flags.ToString()); cmd.Parameters.AddWithValue("?ListingPrice", ad.Price.ToString ()); - + cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": ClassifiedesUpdate exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: UpdateClassifiedRecord exception {0}", e.Message); result = e.Message; return false; } return true; } - + public bool DeleteClassifiedRecord(UUID recordId) { - string query = string.Empty; - - query += "DELETE FROM classifieds WHERE "; - query += "classifieduuid = ?recordId"; - + const string query = "DELETE FROM classifieds WHERE classifieduuid = ?recordId"; + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) { dbcon.Open(); - + using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) { cmd.Parameters.AddWithValue("?recordId", recordId.ToString()); cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": DeleteClassifiedRecord exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: DeleteClassifiedRecord exception {0}", e.Message); return false; } return true; } - + public bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result) { - string query = string.Empty; - - query += "SELECT * FROM classifieds WHERE "; - query += "classifieduuid = ?AdId"; - + + const string query = "SELECT * FROM classifieds WHERE classifieduuid = ?AdId"; + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) @@ -284,7 +279,7 @@ namespace OpenSim.Data.MySQL using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) { cmd.Parameters.AddWithValue("?AdId", ad.ClassifiedId.ToString()); - + using (MySqlDataReader reader = cmd.ExecuteReader()) { if(reader.Read ()) @@ -303,7 +298,7 @@ namespace OpenSim.Data.MySQL ad.SimName = reader.GetString("simname"); ad.GlobalPos = reader.GetString("posglobal"); ad.ParcelName = reader.GetString("parcelname"); - + } } } @@ -312,22 +307,19 @@ namespace OpenSim.Data.MySQL } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": GetPickInfo exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetClassifiedInfo exception {0}", e.Message); } return true; } #endregion Classifieds Queries - + #region Picks Queries public OSDArray GetAvatarPicks(UUID avatarId) { - string query = string.Empty; - - query += "SELECT `pickuuid`,`name` FROM userpicks WHERE "; - query += "creatoruuid = ?Id"; + const string query = "SELECT `pickuuid`,`name` FROM userpicks WHERE creatoruuid = ?Id"; + OSDArray data = new OSDArray(); - + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) @@ -336,7 +328,7 @@ namespace OpenSim.Data.MySQL using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) { cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); - + using (MySqlDataReader reader = cmd.ExecuteReader()) { if(reader.HasRows) @@ -344,7 +336,7 @@ namespace OpenSim.Data.MySQL while (reader.Read()) { OSDMap record = new OSDMap(); - + record.Add("pickuuid",OSD.FromString((string)reader["pickuuid"])); record.Add("name",OSD.FromString((string)reader["name"])); data.Add(record); @@ -352,25 +344,21 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": GetAvatarPicks exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarPicks exception {0}", e.Message); } return data; } - + public UserProfilePick GetPickInfo(UUID avatarId, UUID pickId) { - string query = string.Empty; UserProfilePick pick = new UserProfilePick(); - - query += "SELECT * FROM userpicks WHERE "; - query += "creatoruuid = ?CreatorId AND "; - query += "pickuuid = ?PickId"; - + const string query = "SELECT * FROM userpicks WHERE creatoruuid = ?CreatorId AND pickuuid = ?PickId"; + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) @@ -380,18 +368,18 @@ namespace OpenSim.Data.MySQL { cmd.Parameters.AddWithValue("?CreatorId", avatarId.ToString()); cmd.Parameters.AddWithValue("?PickId", pickId.ToString()); - + using (MySqlDataReader reader = cmd.ExecuteReader()) { if(reader.HasRows) { reader.Read(); - + string description = (string)reader["description"]; - + if (string.IsNullOrEmpty(description)) description = "No description given."; - + UUID.TryParse((string)reader["pickuuid"], out pick.PickId); UUID.TryParse((string)reader["creatoruuid"], out pick.CreatorId); UUID.TryParse((string)reader["parceluuid"], out pick.ParcelId); @@ -414,42 +402,41 @@ namespace OpenSim.Data.MySQL } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": GetPickInfo exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetPickInfo exception {0}", e.Message); } return pick; } - + public bool UpdatePicksRecord(UserProfilePick pick) - { - string query = string.Empty; - - query += "INSERT INTO userpicks VALUES ("; - query += "?PickId,"; - query += "?CreatorId,"; - query += "?TopPick,"; - query += "?ParcelId,"; - query += "?Name,"; - query += "?Desc,"; - query += "?SnapshotId,"; - query += "?User,"; - query += "?Original,"; - query += "?SimName,"; - query += "?GlobalPos,"; - query += "?SortOrder,"; - query += "?Enabled,"; - query += "?Gatekeeper)"; - query += "ON DUPLICATE KEY UPDATE "; - query += "parceluuid=?ParcelId,"; - query += "name=?Name,"; - query += "description=?Desc,"; - query += "user=?User,"; - query += "simname=?SimName,"; - query += "snapshotuuid=?SnapshotId,"; - query += "pickuuid=?PickId,"; - query += "posglobal=?GlobalPos,"; - query += "gatekeeper=?Gatekeeper"; - + { + const string query = + "INSERT INTO userpicks VALUES (" + + "?PickId," + + "?CreatorId," + + "?TopPick," + + "?ParcelId," + + "?Name," + + "?Desc," + + "?SnapshotId," + + "?User," + + "?Original," + + "?SimName," + + "?GlobalPos," + + "?SortOrder," + + "?Enabled," + + "?Gatekeeper)" + + "ON DUPLICATE KEY UPDATE " + + "parceluuid=?ParcelId," + + "name=?Name," + + "description=?Desc," + + "user=?User," + + "simname=?SimName," + + "snapshotuuid=?SnapshotId," + + "pickuuid=?PickId," + + "posglobal=?GlobalPos," + + "gatekeeper=?Gatekeeper" + ; + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) @@ -471,61 +458,53 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?Gatekeeper",pick.Gatekeeper); cmd.Parameters.AddWithValue("?SortOrder", pick.SortOrder.ToString ()); cmd.Parameters.AddWithValue("?Enabled", pick.Enabled.ToString()); - + cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": UpdateAvatarNotes exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: UpdatePicksRecord exception {0}", e.Message); return false; } return true; } - + public bool DeletePicksRecord(UUID pickId) { - string query = string.Empty; - - query += "DELETE FROM userpicks WHERE "; - query += "pickuuid = ?PickId"; - + string query = "DELETE FROM userpicks WHERE pickuuid = ?PickId"; + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) { dbcon.Open(); - + using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) { cmd.Parameters.AddWithValue("?PickId", pickId.ToString()); - + cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": DeleteUserPickRecord exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: DeletePicksRecord exception {0}", e.Message); return false; } return true; } #endregion Picks Queries - + #region Avatar Notes Queries public bool GetAvatarNotes(ref UserProfileNotes notes) { // WIP - string query = string.Empty; - - query += "SELECT `notes` FROM usernotes WHERE "; - query += "useruuid = ?Id AND "; - query += "targetuuid = ?TargetId"; - OSDArray data = new OSDArray(); - + const string query = "SELECT `notes` FROM usernotes WHERE useruuid = ?Id AND targetuuid = ?TargetId"; + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) @@ -535,7 +514,7 @@ namespace OpenSim.Data.MySQL { cmd.Parameters.AddWithValue("?Id", notes.UserId.ToString()); cmd.Parameters.AddWithValue("?TargetId", notes.TargetId.ToString()); - + using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { if(reader.HasRows) @@ -549,40 +528,39 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": GetAvatarNotes exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarNotes exception {0}", e.Message); } return true; } - + public bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result) - { - string query = string.Empty; + { + string query; bool remove; - + if(string.IsNullOrEmpty(note.Notes)) { remove = true; - query += "DELETE FROM usernotes WHERE "; - query += "useruuid=?UserId AND "; - query += "targetuuid=?TargetId"; + query = "DELETE FROM usernotes WHERE useruuid=?UserId AND targetuuid=?TargetId"; } else { remove = false; - query += "INSERT INTO usernotes VALUES ( "; - query += "?UserId,"; - query += "?TargetId,"; - query += "?Notes )"; - query += "ON DUPLICATE KEY "; - query += "UPDATE "; - query += "notes=?Notes"; + query = "INSERT INTO usernotes VALUES (" + + "?UserId," + + "?TargetId," + + "?Notes )" + + "ON DUPLICATE KEY " + + "UPDATE " + + "notes=?Notes" + ; } - + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) @@ -594,30 +572,27 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?Notes", note.Notes); cmd.Parameters.AddWithValue("?TargetId", note.TargetId.ToString ()); cmd.Parameters.AddWithValue("?UserId", note.UserId.ToString()); - + cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": UpdateAvatarNotes exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarNotes exception {0}", e.Message); return false; } return true; - + } #endregion Avatar Notes Queries - + #region Avatar Properties public bool GetAvatarProperties(ref UserProfileProperties props, ref string result) { - string query = string.Empty; - - query += "SELECT * FROM userprofile WHERE "; - query += "useruuid = ?Id"; - + string query = "SELECT * FROM userprofile WHERE useruuid = ?Id"; + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) @@ -626,11 +601,13 @@ namespace OpenSim.Data.MySQL using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) { cmd.Parameters.AddWithValue("?Id", props.UserId.ToString()); - + using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { if(reader.HasRows) { + m_log.DebugFormat("[PROFILES_DATA]" + + ": Getting data for {0}.", props.UserId); reader.Read(); props.WebUrl = (string)reader["profileURL"]; UUID.TryParse((string)reader["profileImage"], out props.ImageId); @@ -646,6 +623,9 @@ namespace OpenSim.Data.MySQL } else { + m_log.DebugFormat("[PROFILES_DATA]" + + ": No data for {0}", props.UserId); + props.WebUrl = string.Empty; props.ImageId = UUID.Zero; props.AboutText = string.Empty; @@ -660,35 +640,36 @@ namespace OpenSim.Data.MySQL props.PublishProfile = false; props.PublishMature = false; - query = "INSERT INTO userprofile ("; - query += "useruuid, "; - query += "profilePartner, "; - query += "profileAllowPublish, "; - query += "profileMaturePublish, "; - query += "profileURL, "; - query += "profileWantToMask, "; - query += "profileWantToText, "; - query += "profileSkillsMask, "; - query += "profileSkillsText, "; - query += "profileLanguages, "; - query += "profileImage, "; - query += "profileAboutText, "; - query += "profileFirstImage, "; - query += "profileFirstText) VALUES ("; - query += "?userId, "; - query += "?profilePartner, "; - query += "?profileAllowPublish, "; - query += "?profileMaturePublish, "; - query += "?profileURL, "; - query += "?profileWantToMask, "; - query += "?profileWantToText, "; - query += "?profileSkillsMask, "; - query += "?profileSkillsText, "; - query += "?profileLanguages, "; - query += "?profileImage, "; - query += "?profileAboutText, "; - query += "?profileFirstImage, "; - query += "?profileFirstText)"; + query = "INSERT INTO userprofile (" + + "useruuid, " + + "profilePartner, " + + "profileAllowPublish, " + + "profileMaturePublish, " + + "profileURL, " + + "profileWantToMask, " + + "profileWantToText, " + + "profileSkillsMask, " + + "profileSkillsText, " + + "profileLanguages, " + + "profileImage, " + + "profileAboutText, " + + "profileFirstImage, " + + "profileFirstText) VALUES (" + + "?userId, " + + "?profilePartner, " + + "?profileAllowPublish, " + + "?profileMaturePublish, " + + "?profileURL, " + + "?profileWantToMask, " + + "?profileWantToText, " + + "?profileSkillsMask, " + + "?profileSkillsText, " + + "?profileLanguages, " + + "?profileImage, " + + "?profileAboutText, " + + "?profileFirstImage, " + + "?profileFirstText)" + ; dbcon.Close(); dbcon.Open(); @@ -715,30 +696,25 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": Requst properties exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarProperties exception {0}", e.Message); result = e.Message; return false; } return true; } - + public bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result) - { - string query = string.Empty; - - query += "UPDATE userprofile SET "; - query += "profileURL=?profileURL, "; - query += "profileImage=?image, "; - query += "profileAboutText=?abouttext,"; - query += "profileFirstImage=?firstlifeimage,"; - query += "profileFirstText=?firstlifetext "; - query += "WHERE useruuid=?uuid"; - + { + const string query = "UPDATE userprofile SET profileURL=?profileURL," + + "profileImage=?image, profileAboutText=?abouttext," + + "profileFirstImage=?firstlifeimage, profileFirstText=?firstlifetext " + + "WHERE useruuid=?uuid"; + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) @@ -752,35 +728,33 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?firstlifeimage", props.FirstLifeImageId.ToString()); cmd.Parameters.AddWithValue("?firstlifetext", props.FirstLifeText); cmd.Parameters.AddWithValue("?uuid", props.UserId.ToString()); - + cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": AgentPropertiesUpdate exception {0}", e.Message); - + m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarProperties exception {0}", e.Message); + return false; } return true; } #endregion Avatar Properties - + #region Avatar Interests public bool UpdateAvatarInterests(UserProfileProperties up, ref string result) - { - string query = string.Empty; - - query += "UPDATE userprofile SET "; - query += "profileWantToMask=?WantMask, "; - query += "profileWantToText=?WantText,"; - query += "profileSkillsMask=?SkillsMask,"; - query += "profileSkillsText=?SkillsText, "; - query += "profileLanguages=?Languages "; - query += "WHERE useruuid=?uuid"; - + { + const string query = "UPDATE userprofile SET " + + "profileWantToMask=?WantMask, " + + "profileWantToText=?WantText," + + "profileSkillsMask=?SkillsMask," + + "profileSkillsText=?SkillsText, " + + "profileLanguages=?Languages " + + "WHERE useruuid=?uuid"; + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) @@ -794,15 +768,14 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?SkillsText", up.SkillsText); cmd.Parameters.AddWithValue("?Languages", up.Language); cmd.Parameters.AddWithValue("?uuid", up.UserId.ToString()); - + cmd.ExecuteNonQuery(); } } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": AgentInterestsUpdate exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarInterests exception {0}", e.Message); result = e.Message; return false; } @@ -813,21 +786,20 @@ namespace OpenSim.Data.MySQL public OSDArray GetUserImageAssets(UUID avatarId) { OSDArray data = new OSDArray(); - string query = "SELECT `snapshotuuid` FROM {0} WHERE `creatoruuid` = ?Id"; + const string queryA = "SELECT `snapshotuuid` FROM {0} WHERE `creatoruuid` = ?Id"; // Get classified image assets - - + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) { dbcon.Open(); - using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`classifieds`"), dbcon)) + using (MySqlCommand cmd = new MySqlCommand(string.Format (queryA,"`classifieds`"), dbcon)) { cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); - + using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { if(reader.HasRows) @@ -843,10 +815,10 @@ namespace OpenSim.Data.MySQL dbcon.Close(); dbcon.Open(); - using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`userpicks`"), dbcon)) + using (MySqlCommand cmd = new MySqlCommand(string.Format (queryA,"`userpicks`"), dbcon)) { cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); - + using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { if(reader.HasRows) @@ -858,16 +830,16 @@ namespace OpenSim.Data.MySQL } } } - + dbcon.Close(); dbcon.Open(); - query = "SELECT `profileImage`, `profileFirstImage` FROM `userprofile` WHERE `useruuid` = ?Id"; + const string queryB = "SELECT `profileImage`, `profileFirstImage` FROM `userprofile` WHERE `useruuid` = ?Id"; - using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`userpicks`"), dbcon)) + using (MySqlCommand cmd = new MySqlCommand(string.Format (queryB,"`userpicks`"), dbcon)) { cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); - + using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { if(reader.HasRows) @@ -880,27 +852,21 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": GetAvatarNotes exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetUserImageAssets exception {0}", e.Message); } return data; } - + #region User Preferences public bool GetUserPreferences(ref UserPreferences pref, ref string result) { - string query = string.Empty; - - query += "SELECT imviaemail,visible,email FROM "; - query += "usersettings WHERE "; - query += "useruuid = ?Id"; - - OSDArray data = new OSDArray(); - + const string query = "SELECT imviaemail,visible,email FROM usersettings WHERE useruuid = ?Id"; + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) @@ -909,10 +875,9 @@ namespace OpenSim.Data.MySQL using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) { cmd.Parameters.AddWithValue("?Id", pref.UserId.ToString()); - using (MySqlDataReader reader = cmd.ExecuteReader()) { - if(reader.HasRows) + if (reader.HasRows) { reader.Read(); bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail); @@ -923,13 +888,12 @@ namespace OpenSim.Data.MySQL { dbcon.Close(); dbcon.Open(); - - query = "INSERT INTO usersettings VALUES "; - query += "(?uuid,'false','false', ?Email)"; - using (MySqlCommand put = new MySqlCommand(query, dbcon)) + const string queryB = "INSERT INTO usersettings VALUES (?uuid,'false','false', ?Email)"; + + using (MySqlCommand put = new MySqlCommand(queryB, dbcon)) { - + put.Parameters.AddWithValue("?Email", pref.EMail); put.Parameters.AddWithValue("?uuid", pref.UserId.ToString()); @@ -938,28 +902,24 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": Get preferences exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetUserPreferences exception {0}", e.Message); result = e.Message; return false; } return true; } - + public bool UpdateUserPreferences(ref UserPreferences pref, ref string result) - { - string query = string.Empty; - - query += "UPDATE usersettings SET "; - query += "imviaemail=?ImViaEmail, "; - query += "visible=?Visible, "; - query += "email=?EMail "; - query += "WHERE useruuid=?uuid"; - + { + const string query = "UPDATE usersettings SET imviaemail=?ImViaEmail," + + "visible=?Visible, email=?EMail " + + "WHERE useruuid=?uuid"; + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) @@ -974,28 +934,24 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": UserPreferencesUpdate exception {0} {1}", e.Message, e.InnerException); + m_log.ErrorFormat("[PROFILES_DATA]: UpdateUserPreferences exception {0} {1}", e.Message, e.InnerException); result = e.Message; return false; } return true; } #endregion User Preferences - + #region Integration public bool GetUserAppData(ref UserAppData props, ref string result) { - string query = string.Empty; - - query += "SELECT * FROM `userdata` WHERE "; - query += "UserId = ?Id AND "; - query += "TagId = ?TagId"; - + const string query = "SELECT * FROM `userdata` WHERE UserId = ?Id AND TagId = ?TagId"; + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) @@ -1005,7 +961,7 @@ namespace OpenSim.Data.MySQL { cmd.Parameters.AddWithValue("?Id", props.UserId.ToString()); cmd.Parameters.AddWithValue ("?TagId", props.TagId.ToString()); - + using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { if(reader.HasRows) @@ -1016,13 +972,8 @@ namespace OpenSim.Data.MySQL } else { - query += "INSERT INTO userdata VALUES ( "; - query += "?UserId,"; - query += "?TagId,"; - query += "?DataKey,"; - query += "?DataVal) "; - - using (MySqlCommand put = new MySqlCommand(query, dbcon)) + const string queryB = "INSERT INTO userdata VALUES (?UserId, ?TagId, ?DataKey, ?DataVal)"; + using (MySqlCommand put = new MySqlCommand(queryB, dbcon)) { put.Parameters.AddWithValue("?UserId", props.UserId.ToString()); put.Parameters.AddWithValue("?TagId", props.TagId.ToString()); @@ -1034,12 +985,12 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": Requst application data exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetUserAppData exception {0}", e.Message); result = e.Message; return false; } @@ -1047,16 +998,9 @@ namespace OpenSim.Data.MySQL } public bool SetUserAppData(UserAppData props, ref string result) - { - string query = string.Empty; - - query += "UPDATE userdata SET "; - query += "TagId = ?TagId, "; - query += "DataKey = ?DataKey, "; - query += "DataVal = ?DataVal WHERE "; - query += "UserId = ?UserId AND "; - query += "TagId = ?TagId"; - + { + const string query = "UPDATE userdata SET TagId = ?TagId, DataKey = ?DataKey, DataVal = ?DataVal WHERE UserId = ?UserId AND TagId = ?TagId"; + try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) @@ -1071,12 +1015,12 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": SetUserData exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: SetUserAppData exception {0}", e.Message); return false; } return true; diff --git a/OpenSim/Data/MySQL/MySQLXAssetData.cs b/OpenSim/Data/MySQL/MySQLXAssetData.cs index af7e876..9f9c9cf 100644 --- a/OpenSim/Data/MySQL/MySQLXAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLXAssetData.cs @@ -97,6 +97,7 @@ namespace OpenSim.Data.MySQL dbcon.Open(); Migration m = new Migration(dbcon, Assembly, "XAssetStore"); m.Update(); + dbcon.Close(); } } @@ -130,6 +131,7 @@ namespace OpenSim.Data.MySQL // m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID); AssetBase asset = null; + int accessTime = 0; using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { @@ -140,7 +142,6 @@ namespace OpenSim.Data.MySQL dbcon)) { cmd.Parameters.AddWithValue("?ID", assetID.ToString()); - try { using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) @@ -159,23 +160,7 @@ namespace OpenSim.Data.MySQL asset.Temporary = Convert.ToBoolean(dbReader["Temporary"]); asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]); - - if (m_enableCompression) - { - using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress)) - { - MemoryStream outputStream = new MemoryStream(); - WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue); -// int compressedLength = asset.Data.Length; - asset.Data = outputStream.ToArray(); - -// m_log.DebugFormat( -// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}", -// asset.ID, asset.Name, asset.Data.Length, compressedLength); - } - } - - UpdateAccessTime(asset.Metadata, (int)dbReader["AccessTime"]); + accessTime = (int)dbReader["AccessTime"]; } } } @@ -184,9 +169,38 @@ namespace OpenSim.Data.MySQL m_log.Error(string.Format("[MYSQL XASSET DATA]: Failure fetching asset {0}", assetID), e); } } + dbcon.Close(); } - return asset; + if(asset == null) + return asset; + + if(accessTime > 0) + { + try + { + UpdateAccessTime(asset.Metadata, accessTime); + } + catch { } + } + + if (m_enableCompression && asset.Data != null) + { + using(MemoryStream ms = new MemoryStream(asset.Data)) + using(GZipStream decompressionStream = new GZipStream(ms, CompressionMode.Decompress)) + { + using(MemoryStream outputStream = new MemoryStream()) + { + decompressionStream.CopyTo(outputStream, int.MaxValue); +// int compressedLength = asset.Data.Length; + asset.Data = outputStream.ToArray(); + } +// m_log.DebugFormat( +// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}", +// asset.ID, asset.Name, asset.Data.Length, compressedLength); + } + } + return asset; } /// @@ -209,7 +223,7 @@ namespace OpenSim.Data.MySQL { assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME); m_log.WarnFormat( - "[XASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", + "[XASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", asset.Name, asset.ID, asset.Name.Length, assetName.Length); } @@ -218,7 +232,7 @@ namespace OpenSim.Data.MySQL { assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC); m_log.WarnFormat( - "[XASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", + "[XASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); } @@ -303,6 +317,7 @@ namespace OpenSim.Data.MySQL transaction.Commit(); } + dbcon.Close(); } } @@ -341,9 +356,10 @@ namespace OpenSim.Data.MySQL catch (Exception) { m_log.ErrorFormat( - "[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}", + "[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}", assetMetadata.ID, assetMetadata.Name); } + dbcon.Close(); } } @@ -440,38 +456,41 @@ namespace OpenSim.Data.MySQL using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); - MySqlCommand cmd = new MySqlCommand("SELECT Name, Description, AccessTime, AssetType, Temporary, ID, AssetFlags, CreatorID FROM XAssetsMeta LIMIT ?start, ?count", dbcon); - cmd.Parameters.AddWithValue("?start", start); - cmd.Parameters.AddWithValue("?count", count); - - try + using(MySqlCommand cmd = new MySqlCommand("SELECT Name, Description, AccessTime, AssetType, Temporary, ID, AssetFlags, CreatorID FROM XAssetsMeta LIMIT ?start, ?count",dbcon)) { - using (MySqlDataReader dbReader = cmd.ExecuteReader()) + cmd.Parameters.AddWithValue("?start",start); + cmd.Parameters.AddWithValue("?count", count); + + try { - while (dbReader.Read()) + using (MySqlDataReader dbReader = cmd.ExecuteReader()) { - AssetMetadata metadata = new AssetMetadata(); - metadata.Name = (string)dbReader["Name"]; - metadata.Description = (string)dbReader["Description"]; - metadata.Type = (sbyte)dbReader["AssetType"]; - metadata.Temporary = Convert.ToBoolean(dbReader["Temporary"]); // Not sure if this is correct. - metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]); - metadata.FullID = DBGuid.FromDB(dbReader["ID"]); - metadata.CreatorID = dbReader["CreatorID"].ToString(); + while (dbReader.Read()) + { + AssetMetadata metadata = new AssetMetadata(); + metadata.Name = (string)dbReader["Name"]; + metadata.Description = (string)dbReader["Description"]; + metadata.Type = (sbyte)dbReader["AssetType"]; + metadata.Temporary = Convert.ToBoolean(dbReader["Temporary"]); // Not sure if this is correct. + metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]); + metadata.FullID = DBGuid.FromDB(dbReader["ID"]); + metadata.CreatorID = dbReader["CreatorID"].ToString(); - // We'll ignore this for now - it appears unused! -// metadata.SHA1 = dbReader["hash"]); + // We'll ignore this for now - it appears unused! + // metadata.SHA1 = dbReader["hash"]); - UpdateAccessTime(metadata, (int)dbReader["AccessTime"]); + UpdateAccessTime(metadata, (int)dbReader["AccessTime"]); - retList.Add(metadata); + retList.Add(metadata); + } } } + catch (Exception e) + { + m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString()); + } } - catch (Exception e) - { - m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString()); - } + dbcon.Close(); } return retList; @@ -490,9 +509,9 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?ID", id); cmd.ExecuteNonQuery(); } - // TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we // keep a reference count (?) + dbcon.Close(); } return true; @@ -500,4 +519,4 @@ namespace OpenSim.Data.MySQL #endregion } -} \ No newline at end of file +} diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs index c74033e..5019994 100644 --- a/OpenSim/Data/MySQL/MySQLXInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs @@ -80,7 +80,7 @@ namespace OpenSim.Data.MySQL return m_Items.Store(item); } - + public bool DeleteFolders(string field, string val) { return m_Folders.Delete(field, val); @@ -193,7 +193,9 @@ namespace OpenSim.Data.MySQL { using (MySqlCommand cmd = new MySqlCommand()) { - cmd.CommandText = String.Format("select * from inventoryitems where avatarId = ?uuid and assetType = ?type and flags & 1", m_Realm); +// cmd.CommandText = String.Format("select * from inventoryitems where avatarId = ?uuid and assetType = ?type and flags & 1", m_Realm); + + cmd.CommandText = String.Format("select * from inventoryitems where avatarId = ?uuid and assetType = ?type and flags & 1"); cmd.Parameters.AddWithValue("?uuid", principalID.ToString()); cmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture); @@ -212,15 +214,18 @@ namespace OpenSim.Data.MySQL { cmd.Connection = dbcon; - cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID", m_Realm); +// cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID", m_Realm); + + cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID"); + cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); cmd.Parameters.AddWithValue("?AssetID", assetID.ToString()); - + using (IDataReader reader = cmd.ExecuteReader()) { int perms = 0; - + if (reader.Read()) { perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]); @@ -323,7 +328,6 @@ namespace OpenSim.Data.MySQL { return false; } - cmd.Dispose(); } dbcon.Close(); diff --git a/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs b/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs index b46d175..6507a37 100644 --- a/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs @@ -61,5 +61,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly : AssemblyVersion("0.8.2.*")] +[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] diff --git a/OpenSim/Data/MySQL/Resources/AgentPrefs.migrations b/OpenSim/Data/MySQL/Resources/AgentPrefs.migrations index e76db07..e496f72 100644 --- a/OpenSim/Data/MySQL/Resources/AgentPrefs.migrations +++ b/OpenSim/Data/MySQL/Resources/AgentPrefs.migrations @@ -13,6 +13,6 @@ CREATE TABLE `AgentPrefs` ( `PermNextOwner` INT(6) NOT NULL DEFAULT 532480, UNIQUE KEY `PrincipalID` (`PrincipalID`), PRIMARY KEY(`PrincipalID`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/AssetStore.migrations b/OpenSim/Data/MySQL/Resources/AssetStore.migrations index 52715fd..820799d 100644 --- a/OpenSim/Data/MySQL/Resources/AssetStore.migrations +++ b/OpenSim/Data/MySQL/Resources/AssetStore.migrations @@ -1,81 +1,21 @@ # ----------------- -:VERSION 1 +:VERSION 10 BEGIN; -CREATE TABLE `assets` ( - `id` binary(16) NOT NULL, +CREATE TABLE IF NOT EXISTS `assets` ( `name` varchar(64) NOT NULL, `description` varchar(64) NOT NULL, `assetType` tinyint(4) NOT NULL, - `invType` tinyint(4) NOT NULL, `local` tinyint(1) NOT NULL, `temporary` tinyint(1) NOT NULL, `data` longblob NOT NULL, + `id` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `create_time` int(11) DEFAULT '0', + `access_time` int(11) DEFAULT '0', + `asset_flags` int(11) NOT NULL DEFAULT '0', + `CreatorID` varchar(128) NOT NULL DEFAULT '', PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Rev. 1'; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; COMMIT; - -# ----------------- -:VERSION 2 - -BEGIN; - -ALTER TABLE assets change id oldid binary(16); -ALTER TABLE assets add id varchar(36) not null default ''; -UPDATE assets set id = concat(substr(hex(oldid),1,8),"-",substr(hex(oldid),9,4),"-",substr(hex(oldid),13,4),"-",substr(hex(oldid),17,4),"-",substr(hex(oldid),21,12)); -ALTER TABLE assets drop oldid; -ALTER TABLE assets add constraint primary key(id); - -COMMIT; - -# ----------------- -:VERSION 3 - -BEGIN; - -ALTER TABLE assets change id oldid varchar(36); -ALTER TABLE assets add id char(36) not null default '00000000-0000-0000-0000-000000000000'; -UPDATE assets set id = oldid; -ALTER TABLE assets drop oldid; -ALTER TABLE assets add constraint primary key(id); - -COMMIT; - -# ----------------- -:VERSION 4 - -BEGIN; - -ALTER TABLE assets drop InvType; - -COMMIT; - -# ----------------- -:VERSION 5 - -BEGIN; - -ALTER TABLE assets add create_time integer default 0; -ALTER TABLE assets add access_time integer default 0; - -COMMIT; - -# ----------------- -:VERSION 6 - -DELETE FROM assets WHERE id = 'dc4b9f0b-d008-45c6-96a4-01dd947ac621' - -:VERSION 7 - -ALTER TABLE assets ADD COLUMN asset_flags INTEGER NOT NULL DEFAULT 0; - -:VERSION 8 - -ALTER TABLE assets ADD COLUMN CreatorID varchar(128) NOT NULL DEFAULT ''; - -:VERSION 9 - -BEGIN; -COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/AuthStore.migrations b/OpenSim/Data/MySQL/Resources/AuthStore.migrations index 9450940..f00979f 100644 --- a/OpenSim/Data/MySQL/Resources/AuthStore.migrations +++ b/OpenSim/Data/MySQL/Resources/AuthStore.migrations @@ -1,16 +1,17 @@ -:VERSION 1 # ------------------------------- +:VERSION 4 # ------------------------------- begin; -CREATE TABLE `auth` ( +CREATE TABLE IF NOT EXISTS `auth` ( `UUID` char(36) NOT NULL, - `passwordHash` char(32) NOT NULL default '', - `passwordSalt` char(32) NOT NULL default '', - `webLoginKey` varchar(255) NOT NULL default '', - PRIMARY KEY (`UUID`) -) ENGINE=MyISAM; - -CREATE TABLE `tokens` ( + `passwordHash` char(32) NOT NULL DEFAULT '', + `passwordSalt` char(32) NOT NULL DEFAULT '', + `webLoginKey` varchar(255) NOT NULL DEFAULT '', + `accountType` varchar(32) NOT NULL DEFAULT 'UserAccount', + PRIMARY KEY (`UUID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tokens` ( `UUID` char(36) NOT NULL, `token` varchar(255) NOT NULL, `validity` datetime NOT NULL, @@ -18,22 +19,6 @@ CREATE TABLE `tokens` ( KEY `UUID` (`UUID`), KEY `token` (`token`), KEY `validity` (`validity`) -) ENGINE=MyISAM; - -commit; - -:VERSION 2 # ------------------------------- - -BEGIN; - -INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey) SELECT `UUID` AS UUID, `passwordHash` AS passwordHash, `passwordSalt` AS passwordSalt, `webLoginKey` AS webLoginKey FROM users; - -COMMIT; - -:VERSION 3 # ------------------------------- - -BEGIN; - -ALTER TABLE `auth` ADD COLUMN `accountType` VARCHAR(32) NOT NULL DEFAULT 'UserAccount'; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/Avatar.migrations b/OpenSim/Data/MySQL/Resources/Avatar.migrations index f7cf176..c5ec9ca 100644 --- a/OpenSim/Data/MySQL/Resources/Avatar.migrations +++ b/OpenSim/Data/MySQL/Resources/Avatar.migrations @@ -1,20 +1,13 @@ -:VERSION 1 +:VERSION 3 BEGIN; -CREATE TABLE Avatars ( - PrincipalID CHAR(36) NOT NULL, - Name VARCHAR(32) NOT NULL, - Value VARCHAR(255) NOT NULL DEFAULT '', - PRIMARY KEY(PrincipalID, Name), - KEY(PrincipalID)); - -COMMIT; - -:VERSION 2 - -BEGIN; - -alter table Avatars change column Value Value text; +CREATE TABLE IF NOT EXISTS `Avatars` ( + `PrincipalID` char(36) NOT NULL, + `Name` varchar(32) NOT NULL, + `Value` text, + PRIMARY KEY (`PrincipalID`,`Name`), + KEY `PrincipalID` (`PrincipalID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/EstateStore.migrations b/OpenSim/Data/MySQL/Resources/EstateStore.migrations index 9dfb77b..615af95 100644 --- a/OpenSim/Data/MySQL/Resources/EstateStore.migrations +++ b/OpenSim/Data/MySQL/Resources/EstateStore.migrations @@ -1,41 +1,29 @@ -:VERSION 13 - -# The estate migrations used to be in Region store -# here they will do nothing (bad) if the tables are already there, -# just update the store version. +:VERSION 34 BEGIN; -CREATE TABLE IF NOT EXISTS `estate_managers` ( - `EstateID` int(10) unsigned NOT NULL, - `uuid` char(36) NOT NULL, - KEY `EstateID` (`EstateID`) -) ENGINE=MyISAM; - CREATE TABLE IF NOT EXISTS `estate_groups` ( `EstateID` int(10) unsigned NOT NULL, `uuid` char(36) NOT NULL, KEY `EstateID` (`EstateID`) -) ENGINE=MyISAM; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE IF NOT EXISTS `estate_users` ( +CREATE TABLE IF NOT EXISTS `estate_managers` ( `EstateID` int(10) unsigned NOT NULL, `uuid` char(36) NOT NULL, KEY `EstateID` (`EstateID`) -) ENGINE=MyISAM; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE IF NOT EXISTS `estateban` ( - `EstateID` int(10) unsigned NOT NULL, - `bannedUUID` varchar(36) NOT NULL, - `bannedIp` varchar(16) NOT NULL, - `bannedIpHostMask` varchar(16) NOT NULL, - `bannedNameMask` varchar(64) default NULL, - KEY `estateban_EstateID` (`EstateID`) -) ENGINE=MyISAM; +CREATE TABLE IF NOT EXISTS `estate_map` ( + `RegionID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `EstateID` int(11) NOT NULL, + PRIMARY KEY (`RegionID`), + KEY `EstateID` (`EstateID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `estate_settings` ( - `EstateID` int(10) unsigned NOT NULL auto_increment, - `EstateName` varchar(64) default NULL, + `EstateID` int(10) unsigned NOT NULL AUTO_INCREMENT, + `EstateName` varchar(64) DEFAULT NULL, `AbuseEmailToEstateOwner` tinyint(4) NOT NULL, `DenyAnonymous` tinyint(4) NOT NULL, `ResetHomeOnTeleport` tinyint(4) NOT NULL, @@ -55,33 +43,29 @@ CREATE TABLE IF NOT EXISTS `estate_settings` ( `EstateSkipScripts` tinyint(4) NOT NULL, `BillableFactor` float NOT NULL, `PublicAccess` tinyint(4) NOT NULL, - `AbuseEmail` varchar(255) not null, - `EstateOwner` varchar(36) not null, - `DenyMinors` tinyint not null, - - PRIMARY KEY (`EstateID`) -) ENGINE=MyISAM AUTO_INCREMENT=100; + `AbuseEmail` varchar(255) NOT NULL, + `EstateOwner` varchar(36) NOT NULL, + `DenyMinors` tinyint(4) NOT NULL, + `AllowLandmark` tinyint(4) NOT NULL DEFAULT '1', + `AllowParcelChanges` tinyint(4) NOT NULL DEFAULT '1', + `AllowSetHome` tinyint(4) NOT NULL DEFAULT '1', + PRIMARY KEY (`EstateID`) +) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8; -CREATE TABLE IF NOT EXISTS `estate_map` ( - `RegionID` char(36) NOT NULL default '00000000-0000-0000-0000-000000000000', - `EstateID` int(11) NOT NULL, - PRIMARY KEY (`RegionID`), +CREATE TABLE IF NOT EXISTS `estate_users` ( + `EstateID` int(10) unsigned NOT NULL, + `uuid` char(36) NOT NULL, KEY `EstateID` (`EstateID`) -) ENGINE=MyISAM; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -COMMIT; - -:VERSION 32 #--------------------- (moved from RegionStore migr, just in case) - -BEGIN; -ALTER TABLE estate_settings AUTO_INCREMENT = 100; -COMMIT; - -:VERSION 33 #--------------------- +CREATE TABLE IF NOT EXISTS `estateban` ( + `EstateID` int(10) unsigned NOT NULL, + `bannedUUID` varchar(36) NOT NULL, + `bannedIp` varchar(16) NOT NULL, + `bannedIpHostMask` varchar(16) NOT NULL, + `bannedNameMask` varchar(64) DEFAULT NULL, + KEY `estateban_EstateID` (`EstateID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -BEGIN; -ALTER TABLE estate_settings ADD COLUMN `AllowLandmark` tinyint(4) NOT NULL default '1'; -ALTER TABLE estate_settings ADD COLUMN `AllowParcelChanges` tinyint(4) NOT NULL default '1'; -ALTER TABLE estate_settings ADD COLUMN `AllowSetHome` tinyint(4) NOT NULL default '1'; COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/FSAssetStore.migrations b/OpenSim/Data/MySQL/Resources/FSAssetStore.migrations index 4194af3..87d08c6 100644 --- a/OpenSim/Data/MySQL/Resources/FSAssetStore.migrations +++ b/OpenSim/Data/MySQL/Resources/FSAssetStore.migrations @@ -13,6 +13,6 @@ CREATE TABLE `fsassets` ( `access_time` int(11) NOT NULL DEFAULT '0', `asset_flags` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; COMMIT; \ No newline at end of file diff --git a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations index 5de0e35..6840f07 100644 --- a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations +++ b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations @@ -1,32 +1,14 @@ -:VERSION 1 # ------------------------- +:VERSION 4 # ------------------------- BEGIN; -CREATE TABLE `Friends` ( - `PrincipalID` CHAR(36) NOT NULL, - `Friend` VARCHAR(255) NOT NULL, - `Flags` VARCHAR(16) NOT NULL DEFAULT 0, - `Offered` VARCHAR(32) NOT NULL DEFAULT 0, - PRIMARY KEY(`PrincipalID`, `Friend`), - KEY(`PrincipalID`) -) ENGINE=MyISAM; - -COMMIT; - -:VERSION 2 # ------------------------- - -BEGIN; - -INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userfriends`; - -COMMIT; - -:VERSION 3 # ------------------------- - -BEGIN; - -ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; -ALTER TABLE `Friends` DROP PRIMARY KEY; -ALTER TABLE `Friends` ADD PRIMARY KEY(PrincipalID(36), Friend(36)); +CREATE TABLE IF NOT EXISTS `Friends` ( + `PrincipalID` varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `Friend` varchar(255) NOT NULL, + `Flags` varchar(16) NOT NULL DEFAULT '0', + `Offered` varchar(32) NOT NULL DEFAULT '0', + PRIMARY KEY (`PrincipalID`(36),`Friend`(36)), + KEY `PrincipalID` (`PrincipalID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/GridStore.migrations b/OpenSim/Data/MySQL/Resources/GridStore.migrations index 52ced24..e4c8fc3 100644 --- a/OpenSim/Data/MySQL/Resources/GridStore.migrations +++ b/OpenSim/Data/MySQL/Resources/GridStore.migrations @@ -1,109 +1,52 @@ -:VERSION 1 +:VERSION 10 BEGIN; -CREATE TABLE `regions` ( +CREATE TABLE IF NOT EXISTS `regions` ( `uuid` varchar(36) NOT NULL, `regionHandle` bigint(20) unsigned NOT NULL, - `regionName` varchar(32) default NULL, - `regionRecvKey` varchar(128) default NULL, - `regionSendKey` varchar(128) default NULL, - `regionSecret` varchar(128) default NULL, - `regionDataURI` varchar(255) default NULL, - `serverIP` varchar(64) default NULL, - `serverPort` int(10) unsigned default NULL, - `serverURI` varchar(255) default NULL, - `locX` int(10) unsigned default NULL, - `locY` int(10) unsigned default NULL, - `locZ` int(10) unsigned default NULL, - `eastOverrideHandle` bigint(20) unsigned default NULL, - `westOverrideHandle` bigint(20) unsigned default NULL, - `southOverrideHandle` bigint(20) unsigned default NULL, - `northOverrideHandle` bigint(20) unsigned default NULL, - `regionAssetURI` varchar(255) default NULL, - `regionAssetRecvKey` varchar(128) default NULL, - `regionAssetSendKey` varchar(128) default NULL, - `regionUserURI` varchar(255) default NULL, - `regionUserRecvKey` varchar(128) default NULL, - `regionUserSendKey` varchar(128) default NULL, `regionMapTexture` varchar(36) default NULL, - `serverHttpPort` int(10) default NULL, `serverRemotingPort` int(10) default NULL, - `owner_uuid` varchar(36) default '00000000-0000-0000-0000-000000000000' not null, - `originUUID` varchar(36), - PRIMARY KEY (`uuid`), + `regionName` varchar(128) DEFAULT NULL, + `regionRecvKey` varchar(128) DEFAULT NULL, + `regionSendKey` varchar(128) DEFAULT NULL, + `regionSecret` varchar(128) DEFAULT NULL, + `regionDataURI` varchar(255) DEFAULT NULL, + `serverIP` varchar(64) DEFAULT NULL, + `serverPort` int(10) unsigned DEFAULT NULL, + `serverURI` varchar(255) DEFAULT NULL, + `locX` int(10) unsigned DEFAULT NULL, + `locY` int(10) unsigned DEFAULT NULL, + `locZ` int(10) unsigned DEFAULT NULL, + `eastOverrideHandle` bigint(20) unsigned DEFAULT NULL, + `westOverrideHandle` bigint(20) unsigned DEFAULT NULL, + `southOverrideHandle` bigint(20) unsigned DEFAULT NULL, + `northOverrideHandle` bigint(20) unsigned DEFAULT NULL, + `regionAssetURI` varchar(255) DEFAULT NULL, + `regionAssetRecvKey` varchar(128) DEFAULT NULL, + `regionAssetSendKey` varchar(128) DEFAULT NULL, + `regionUserURI` varchar(255) DEFAULT NULL, + `regionUserRecvKey` varchar(128) DEFAULT NULL, + `regionUserSendKey` varchar(128) DEFAULT NULL, + `regionMapTexture` varchar(36) DEFAULT NULL, + `serverHttpPort` int(10) DEFAULT NULL, + `serverRemotingPort` int(10) DEFAULT NULL, + `owner_uuid` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `originUUID` varchar(36) DEFAULT NULL, + `access` int(10) unsigned DEFAULT '1', + `ScopeID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `sizeX` int(11) NOT NULL DEFAULT '0', + `sizeY` int(11) NOT NULL DEFAULT '0', + `flags` int(11) NOT NULL DEFAULT '0', + `last_seen` int(11) NOT NULL DEFAULT '0', + `PrincipalID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `Token` varchar(255) NOT NULL, + `parcelMapTexture` varchar(36) DEFAULT NULL, + PRIMARY KEY (`uuid`), KEY `regionName` (`regionName`), KEY `regionHandle` (`regionHandle`), - KEY `overrideHandles` (`eastOverrideHandle`,`westOverrideHandle`,`southOverrideHandle`,`northOverrideHandle`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -COMMIT; - -:VERSION 2 - -BEGIN; - -ALTER TABLE regions add column access integer unsigned default 1; - -COMMIT; - -:VERSION 3 - -BEGIN; - -ALTER TABLE regions add column ScopeID char(36) not null default '00000000-0000-0000-0000-000000000000'; - -create index ScopeID on regions(ScopeID); - -COMMIT; - -:VERSION 4 - -BEGIN; - -ALTER TABLE regions add column sizeX integer not null default 0; -ALTER TABLE regions add column sizeY integer not null default 0; - -COMMIT; - -:VERSION 5 - -BEGIN; - -ALTER TABLE `regions` ADD COLUMN `flags` integer NOT NULL DEFAULT 0; -CREATE INDEX flags ON regions(flags); - -COMMIT; - -:VERSION 6 - -BEGIN; - -ALTER TABLE `regions` ADD COLUMN `last_seen` integer NOT NULL DEFAULT 0; - -COMMIT; - -:VERSION 7 - -BEGIN; - -ALTER TABLE `regions` ADD COLUMN `PrincipalID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; -ALTER TABLE `regions` ADD COLUMN `Token` varchar(255) NOT NULL; - -COMMIT; - - -:VERSION 8 # ------------ - -BEGIN; - -alter table regions modify column regionName varchar(128) default NULL; - -COMMIT; - -:VERSION 9 # ------------ - -BEGIN; - -alter table regions add column `parcelMapTexture` varchar(36) default NULL; + KEY `overrideHandles` (`eastOverrideHandle`,`westOverrideHandle`,`southOverrideHandle`,`northOverrideHandle`), + KEY `ScopeID` (`ScopeID`), + KEY `flags` (`flags`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/GridUserStore.migrations b/OpenSim/Data/MySQL/Resources/GridUserStore.migrations index e2be27e..d08e096 100644 --- a/OpenSim/Data/MySQL/Resources/GridUserStore.migrations +++ b/OpenSim/Data/MySQL/Resources/GridUserStore.migrations @@ -14,7 +14,7 @@ CREATE TABLE `GridUser` ( `Login` CHAR(16) NOT NULL DEFAULT '0', `Logout` CHAR(16) NOT NULL DEFAULT '0', PRIMARY KEY (`UserID`) -) ENGINE=MyISAM; +) ENGINE=InnoDB; COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations b/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations index 06ca29d..b4e4422 100644 --- a/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations +++ b/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations @@ -12,7 +12,7 @@ CREATE TABLE `hg_traveling_data` ( `TMStamp` timestamp NOT NULL, PRIMARY KEY (`SessionID`), KEY (`UserID`) -) ENGINE=MyISAM; +) ENGINE=InnoDB; COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/IM_Store.migrations b/OpenSim/Data/MySQL/Resources/IM_Store.migrations index 79ead98..4f14826 100644 --- a/OpenSim/Data/MySQL/Resources/IM_Store.migrations +++ b/OpenSim/Data/MySQL/Resources/IM_Store.migrations @@ -1,42 +1,16 @@ -:VERSION 1 # -------------------------- +:VERSION 5 # -------------------------- BEGIN; -CREATE TABLE `im_offline` ( - `ID` MEDIUMINT NOT NULL AUTO_INCREMENT, - `PrincipalID` char(36) NOT NULL default '', +CREATE TABLE IF NOT EXISTS `im_offline` ( + `ID` mediumint(9) NOT NULL AUTO_INCREMENT, + `PrincipalID` char(36) NOT NULL DEFAULT '', + `FromID` char(36) NOT NULL DEFAULT '', `Message` text NOT NULL, - `TMStamp` timestamp NOT NULL, - PRIMARY KEY (`ID`), - KEY `PrincipalID` (`PrincipalID`) -) ENGINE=MyISAM; - -COMMIT; - -:VERSION 2 # -------------------------- - -BEGIN; - -INSERT INTO `im_offline` SELECT * from `diva_im_offline`; -DROP TABLE `diva_im_offline`; -DELETE FROM `migrations` WHERE name='diva_im_Store'; - -COMMIT; - -:VERSION 3 # -------------------------- - -BEGIN; - -ALTER TABLE `im_offline` - ADD `FromID` char(36) NOT NULL default '' AFTER `PrincipalID`, - ADD KEY `FromID` (`FromID`); - -COMMIT; - -:VERSION 4 # -------------------------- - -BEGIN; - -ALTER TABLE im_offline CONVERT TO CHARACTER SET utf8; + `TMStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`ID`), + KEY `PrincipalID` (`PrincipalID`), + KEY `FromID` (`FromID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/InventoryStore.migrations b/OpenSim/Data/MySQL/Resources/InventoryStore.migrations index ca2fe11..2d4384c 100644 --- a/OpenSim/Data/MySQL/Resources/InventoryStore.migrations +++ b/OpenSim/Data/MySQL/Resources/InventoryStore.migrations @@ -1,109 +1,42 @@ -:VERSION 1 # ------------ +:VERSION 7 # ------------ BEGIN; -CREATE TABLE `inventoryfolders` ( - `folderID` varchar(36) NOT NULL default '', - `agentID` varchar(36) default NULL, - `parentFolderID` varchar(36) default NULL, - `folderName` varchar(64) default NULL, - `type` smallint NOT NULL default 0, - `version` int NOT NULL default 0, - PRIMARY KEY (`folderID`), - KEY `owner` (`agentID`), - KEY `parent` (`parentFolderID`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -CREATE TABLE `inventoryitems` ( - `inventoryID` varchar(36) NOT NULL default '', - `assetID` varchar(36) default NULL, - `assetType` int(11) default NULL, - `parentFolderID` varchar(36) default NULL, - `avatarID` varchar(36) default NULL, - `inventoryName` varchar(64) default NULL, - `inventoryDescription` varchar(128) default NULL, - `inventoryNextPermissions` int(10) unsigned default NULL, - `inventoryCurrentPermissions` int(10) unsigned default NULL, - `invType` int(11) default NULL, - `creatorID` varchar(36) default NULL, - `inventoryBasePermissions` int(10) unsigned NOT NULL default 0, - `inventoryEveryOnePermissions` int(10) unsigned NOT NULL default 0, - `salePrice` int(11) NOT NULL default 0, - `saleType` tinyint(4) NOT NULL default 0, - `creationDate` int(11) NOT NULL default 0, - `groupID` varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000', - `groupOwned` tinyint(4) NOT NULL default 0, - `flags` int(11) unsigned NOT NULL default 0, - PRIMARY KEY (`inventoryID`), - KEY `owner` (`avatarID`), - KEY `folder` (`parentFolderID`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -COMMIT; - -:VERSION 2 # ------------ - -BEGIN; - -ALTER TABLE inventoryfolders change folderID folderIDold varchar(36); -ALTER TABLE inventoryfolders change agentID agentIDold varchar(36); -ALTER TABLE inventoryfolders change parentFolderID parentFolderIDold varchar(36); -ALTER TABLE inventoryfolders add folderID char(36) not null default '00000000-0000-0000-0000-000000000000'; -ALTER TABLE inventoryfolders add agentID char(36) default NULL; -ALTER TABLE inventoryfolders add parentFolderID char(36) default NULL; -UPDATE inventoryfolders set folderID = folderIDold, agentID = agentIDold, parentFolderID = parentFolderIDold; -ALTER TABLE inventoryfolders drop folderIDold; -ALTER TABLE inventoryfolders drop agentIDold; -ALTER TABLE inventoryfolders drop parentFolderIDold; -ALTER TABLE inventoryfolders add constraint primary key(folderID); -ALTER TABLE inventoryfolders add index inventoryfolders_agentid(agentID); -ALTER TABLE inventoryfolders add index inventoryfolders_parentFolderid(parentFolderID); - -ALTER TABLE inventoryitems change inventoryID inventoryIDold varchar(36); -ALTER TABLE inventoryitems change avatarID avatarIDold varchar(36); -ALTER TABLE inventoryitems change parentFolderID parentFolderIDold varchar(36); -ALTER TABLE inventoryitems add inventoryID char(36) not null default '00000000-0000-0000-0000-000000000000'; -ALTER TABLE inventoryitems add avatarID char(36) default NULL; -ALTER TABLE inventoryitems add parentFolderID char(36) default NULL; -UPDATE inventoryitems set inventoryID = inventoryIDold, avatarID = avatarIDold, parentFolderID = parentFolderIDold; -ALTER TABLE inventoryitems drop inventoryIDold; -ALTER TABLE inventoryitems drop avatarIDold; -ALTER TABLE inventoryitems drop parentFolderIDold; -ALTER TABLE inventoryitems add constraint primary key(inventoryID); -ALTER TABLE inventoryitems add index inventoryitems_avatarid(avatarID); -ALTER TABLE inventoryitems add index inventoryitems_parentFolderid(parentFolderID); - -COMMIT; - -:VERSION 3 # ------------ - -BEGIN; - -alter table inventoryitems add column inventoryGroupPermissions integer unsigned not null default 0; - -COMMIT; - -:VERSION 4 # ------------ - -BEGIN; - -update inventoryitems set creatorID = '00000000-0000-0000-0000-000000000000' where creatorID is NULL; -update inventoryitems set creatorID = '00000000-0000-0000-0000-000000000000' where creatorID = ''; -alter table inventoryitems modify column creatorID varchar(36) not NULL default '00000000-0000-0000-0000-000000000000'; - -COMMIT; - -:VERSION 5 # ------------ - -BEGIN; - -alter table inventoryitems modify column creatorID varchar(128) not NULL default '00000000-0000-0000-0000-000000000000'; - -COMMIT; - -:VERSION 6 # ------------ - -BEGIN; - -alter table inventoryitems modify column creatorID varchar(255) not NULL default '00000000-0000-0000-0000-000000000000'; +CREATE TABLE IF NOT EXISTS `inventoryitems` ( + `assetID` varchar(36) DEFAULT NULL, + `assetType` int(11) DEFAULT NULL, + `inventoryName` varchar(64) DEFAULT NULL, + `inventoryDescription` varchar(128) DEFAULT NULL, + `inventoryNextPermissions` int(10) unsigned DEFAULT NULL, + `inventoryCurrentPermissions` int(10) unsigned DEFAULT NULL, + `invType` int(11) DEFAULT NULL, + `creatorID` varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `inventoryBasePermissions` int(10) unsigned NOT NULL DEFAULT '0', + `inventoryEveryOnePermissions` int(10) unsigned NOT NULL DEFAULT '0', + `salePrice` int(11) NOT NULL DEFAULT '0', + `saleType` tinyint(4) NOT NULL DEFAULT '0', + `creationDate` int(11) NOT NULL DEFAULT '0', + `groupID` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `groupOwned` tinyint(4) NOT NULL DEFAULT '0', + `flags` int(11) unsigned NOT NULL DEFAULT '0', + `inventoryID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `avatarID` char(36) DEFAULT NULL, + `parentFolderID` char(36) DEFAULT NULL, + `inventoryGroupPermissions` int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`inventoryID`), + KEY `inventoryitems_avatarid` (`avatarID`), + KEY `inventoryitems_parentFolderid` (`parentFolderID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `inventoryfolders` ( + `folderName` varchar(64) DEFAULT NULL, + `type` smallint(6) NOT NULL DEFAULT '0', + `version` int(11) NOT NULL DEFAULT '0', + `folderID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `agentID` char(36) DEFAULT NULL, + `parentFolderID` char(36) DEFAULT NULL, + PRIMARY KEY (`folderID`), + KEY `inventoryfolders_agentid` (`agentID`), + KEY `inventoryfolders_parentFolderid` (`parentFolderID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/LogStore.migrations b/OpenSim/Data/MySQL/Resources/LogStore.migrations index b572411..9ac26ac 100644 --- a/OpenSim/Data/MySQL/Resources/LogStore.migrations +++ b/OpenSim/Data/MySQL/Resources/LogStore.migrations @@ -10,4 +10,4 @@ CREATE TABLE `logs` ( `priority` int(11) default NULL, `message` text, PRIMARY KEY (`logID`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/OpenSim/Data/MySQL/Resources/MuteListStore.migrations b/OpenSim/Data/MySQL/Resources/MuteListStore.migrations new file mode 100644 index 0000000..5bde63e --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/MuteListStore.migrations @@ -0,0 +1,16 @@ +:VERSION 1 + +BEGIN; + +CREATE TABLE `MuteList` ( + `AgentID` char(36) NOT NULL, + `MuteID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `MuteName` varchar(64) NOT NULL DEFAULT '', + `MuteType` int(11) NOT NULL DEFAULT '1', + `MuteFlags` int(11) NOT NULL DEFAULT '0', + `Stamp` int(11) NOT NULL, + UNIQUE KEY `AgentID_2` (`AgentID`,`MuteID`,`MuteName`), + KEY `AgentID` (`AgentID`) +); + +COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/Presence.migrations b/OpenSim/Data/MySQL/Resources/Presence.migrations index 6dc9384..50aa756 100644 --- a/OpenSim/Data/MySQL/Resources/Presence.migrations +++ b/OpenSim/Data/MySQL/Resources/Presence.migrations @@ -1,31 +1,16 @@ -:VERSION 1 # -------------------------- +:VERSION 4 # -------------------------- BEGIN; -CREATE TABLE `Presence` ( - `UserID` VARCHAR(255) NOT NULL, - `RegionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', - `SessionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', - `SecureSessionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000' -) ENGINE=MyISAM; - -CREATE UNIQUE INDEX SessionID ON Presence(SessionID); -CREATE INDEX UserID ON Presence(UserID); - -COMMIT; - -:VERSION 2 # -------------------------- - -BEGIN; - -ALTER TABLE `Presence` ADD COLUMN LastSeen timestamp; - -COMMIT; - -:VERSION 3 # -------------------------- - -BEGIN; - -CREATE INDEX RegionID ON Presence(RegionID); +CREATE TABLE IF NOT EXISTS `Presence` ( + `UserID` varchar(255) NOT NULL, + `RegionID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `SessionID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `SecureSessionID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `LastSeen` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY `SessionID` (`SessionID`), + KEY `UserID` (`UserID`), + KEY `RegionID` (`RegionID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations index 834d249..0577392 100644 --- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations @@ -1,354 +1,226 @@ -:VERSION 1 #--------------------- - -BEGIN; - -CREATE TABLE `prims` ( - `UUID` varchar(255) NOT NULL, - `RegionUUID` varchar(255) default NULL, - `ParentID` int(11) default NULL, - `CreationDate` int(11) default NULL, - `Name` varchar(255) default NULL, - `SceneGroupID` varchar(255) default NULL, - `Text` varchar(255) default NULL, - `Description` varchar(255) default NULL, - `SitName` varchar(255) default NULL, - `TouchName` varchar(255) default NULL, - `ObjectFlags` int(11) default NULL, - `CreatorID` varchar(255) default NULL, - `OwnerID` varchar(255) default NULL, - `GroupID` varchar(255) default NULL, - `LastOwnerID` varchar(255) default NULL, - `OwnerMask` int(11) default NULL, - `NextOwnerMask` int(11) default NULL, - `GroupMask` int(11) default NULL, - `EveryoneMask` int(11) default NULL, - `BaseMask` int(11) default NULL, - `PositionX` float default NULL, - `PositionY` float default NULL, - `PositionZ` float default NULL, - `GroupPositionX` float default NULL, - `GroupPositionY` float default NULL, - `GroupPositionZ` float default NULL, - `VelocityX` float default NULL, - `VelocityY` float default NULL, - `VelocityZ` float default NULL, - `AngularVelocityX` float default NULL, - `AngularVelocityY` float default NULL, - `AngularVelocityZ` float default NULL, - `AccelerationX` float default NULL, - `AccelerationY` float default NULL, - `AccelerationZ` float default NULL, - `RotationX` float default NULL, - `RotationY` float default NULL, - `RotationZ` float default NULL, - `RotationW` float default NULL, - `SitTargetOffsetX` float default NULL, - `SitTargetOffsetY` float default NULL, - `SitTargetOffsetZ` float default NULL, - `SitTargetOrientW` float default NULL, - `SitTargetOrientX` float default NULL, - `SitTargetOrientY` float default NULL, - `SitTargetOrientZ` float default NULL, - PRIMARY KEY (`UUID`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - -CREATE TABLE `primshapes` ( - `UUID` varchar(255) NOT NULL, - `Shape` int(11) default NULL, - `ScaleX` float default NULL, - `ScaleY` float default NULL, - `ScaleZ` float default NULL, - `PCode` int(11) default NULL, - `PathBegin` int(11) default NULL, - `PathEnd` int(11) default NULL, - `PathScaleX` int(11) default NULL, - `PathScaleY` int(11) default NULL, - `PathShearX` int(11) default NULL, - `PathShearY` int(11) default NULL, - `PathSkew` int(11) default NULL, - `PathCurve` int(11) default NULL, - `PathRadiusOffset` int(11) default NULL, - `PathRevolutions` int(11) default NULL, - `PathTaperX` int(11) default NULL, - `PathTaperY` int(11) default NULL, - `PathTwist` int(11) default NULL, - `PathTwistBegin` int(11) default NULL, - `ProfileBegin` int(11) default NULL, - `ProfileEnd` int(11) default NULL, - `ProfileCurve` int(11) default NULL, - `ProfileHollow` int(11) default NULL, - `State` int(11) default NULL, +:VERSION 51 #--------------------- + +BEGIN; + +CREATE TABLE IF NOT EXISTS `prims` ( + `CreationDate` int(11) DEFAULT NULL, + `Name` varchar(255) DEFAULT NULL, + `Text` varchar(255) DEFAULT NULL, + `Description` varchar(255) DEFAULT NULL, + `SitName` varchar(255) DEFAULT NULL, + `TouchName` varchar(255) DEFAULT NULL, + `ObjectFlags` int(11) DEFAULT NULL, + `OwnerMask` int(11) DEFAULT NULL, + `NextOwnerMask` int(11) DEFAULT NULL, + `GroupMask` int(11) DEFAULT NULL, + `EveryoneMask` int(11) DEFAULT NULL, + `BaseMask` int(11) DEFAULT NULL, + `PositionX` double DEFAULT NULL, + `PositionY` double DEFAULT NULL, + `PositionZ` double DEFAULT NULL, + `GroupPositionX` double DEFAULT NULL, + `GroupPositionY` double DEFAULT NULL, + `GroupPositionZ` double DEFAULT NULL, + `VelocityX` double DEFAULT NULL, + `VelocityY` double DEFAULT NULL, + `VelocityZ` double DEFAULT NULL, + `AngularVelocityX` double DEFAULT NULL, + `AngularVelocityY` double DEFAULT NULL, + `AngularVelocityZ` double DEFAULT NULL, + `AccelerationX` double DEFAULT NULL, + `AccelerationY` double DEFAULT NULL, + `AccelerationZ` double DEFAULT NULL, + `RotationX` double DEFAULT NULL, + `RotationY` double DEFAULT NULL, + `RotationZ` double DEFAULT NULL, + `RotationW` double DEFAULT NULL, + `SitTargetOffsetX` double DEFAULT NULL, + `SitTargetOffsetY` double DEFAULT NULL, + `SitTargetOffsetZ` double DEFAULT NULL, + `SitTargetOrientW` double DEFAULT NULL, + `SitTargetOrientX` double DEFAULT NULL, + `SitTargetOrientY` double DEFAULT NULL, + `SitTargetOrientZ` double DEFAULT NULL, + `UUID` char(36) NOT NULL DEFAULT '', + `RegionUUID` char(36) DEFAULT NULL, + `CreatorID` varchar(255) NOT NULL DEFAULT '', + `OwnerID` char(36) DEFAULT NULL, + `GroupID` char(36) DEFAULT NULL, + `LastOwnerID` char(36) DEFAULT NULL, + `SceneGroupID` char(36) DEFAULT NULL, + `PayPrice` int(11) NOT NULL DEFAULT '0', + `PayButton1` int(11) NOT NULL DEFAULT '0', + `PayButton2` int(11) NOT NULL DEFAULT '0', + `PayButton3` int(11) NOT NULL DEFAULT '0', + `PayButton4` int(11) NOT NULL DEFAULT '0', + `LoopedSound` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `LoopedSoundGain` double NOT NULL DEFAULT '0', + `TextureAnimation` blob, + `OmegaX` double NOT NULL DEFAULT '0', + `OmegaY` double NOT NULL DEFAULT '0', + `OmegaZ` double NOT NULL DEFAULT '0', + `CameraEyeOffsetX` double NOT NULL DEFAULT '0', + `CameraEyeOffsetY` double NOT NULL DEFAULT '0', + `CameraEyeOffsetZ` double NOT NULL DEFAULT '0', + `CameraAtOffsetX` double NOT NULL DEFAULT '0', + `CameraAtOffsetY` double NOT NULL DEFAULT '0', + `CameraAtOffsetZ` double NOT NULL DEFAULT '0', + `ForceMouselook` tinyint(4) NOT NULL DEFAULT '0', + `ScriptAccessPin` int(11) NOT NULL DEFAULT '0', + `AllowedDrop` tinyint(4) NOT NULL DEFAULT '0', + `DieAtEdge` tinyint(4) NOT NULL DEFAULT '0', + `SalePrice` int(11) NOT NULL DEFAULT '10', + `SaleType` tinyint(4) NOT NULL DEFAULT '0', + `ColorR` int(11) NOT NULL DEFAULT '0', + `ColorG` int(11) NOT NULL DEFAULT '0', + `ColorB` int(11) NOT NULL DEFAULT '0', + `ColorA` int(11) NOT NULL DEFAULT '0', + `ParticleSystem` blob, + `ClickAction` tinyint(4) NOT NULL DEFAULT '0', + `Material` tinyint(4) NOT NULL DEFAULT '3', + `CollisionSound` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `CollisionSoundVolume` double NOT NULL DEFAULT '0', + `LinkNumber` int(11) NOT NULL DEFAULT '0', + `PassTouches` tinyint(4) NOT NULL DEFAULT '0', + `MediaURL` varchar(255) DEFAULT NULL, + `DynAttrs` text, + `PhysicsShapeType` tinyint(4) NOT NULL DEFAULT '0', + `Density` double NOT NULL DEFAULT '1000', + `GravityModifier` double NOT NULL DEFAULT '1', + `Friction` double NOT NULL DEFAULT '0.6', + `Restitution` double NOT NULL DEFAULT '0.5', + `KeyframeMotion` blob, + `AttachedPosX` double DEFAULT '0', + `AttachedPosY` double DEFAULT '0', + `AttachedPosZ` double DEFAULT '0', + PRIMARY KEY (`UUID`), + KEY `prims_regionuuid` (`RegionUUID`), + KEY `prims_scenegroupid` (`SceneGroupID`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +CREATE TABLE IF NOT EXISTS `primshapes` ( + `Shape` int(11) DEFAULT NULL, + `ScaleX` double NOT NULL DEFAULT '0', + `ScaleY` double NOT NULL DEFAULT '0', + `ScaleZ` double NOT NULL DEFAULT '0', + `PCode` int(11) DEFAULT NULL, + `PathBegin` int(11) DEFAULT NULL, + `PathEnd` int(11) DEFAULT NULL, + `PathScaleX` int(11) DEFAULT NULL, + `PathScaleY` int(11) DEFAULT NULL, + `PathShearX` int(11) DEFAULT NULL, + `PathShearY` int(11) DEFAULT NULL, + `PathSkew` int(11) DEFAULT NULL, + `PathCurve` int(11) DEFAULT NULL, + `PathRadiusOffset` int(11) DEFAULT NULL, + `PathRevolutions` int(11) DEFAULT NULL, + `PathTaperX` int(11) DEFAULT NULL, + `PathTaperY` int(11) DEFAULT NULL, + `PathTwist` int(11) DEFAULT NULL, + `PathTwistBegin` int(11) DEFAULT NULL, + `ProfileBegin` int(11) DEFAULT NULL, + `ProfileEnd` int(11) DEFAULT NULL, + `ProfileCurve` int(11) DEFAULT NULL, + `ProfileHollow` int(11) DEFAULT NULL, + `State` int(11) DEFAULT NULL, `Texture` longblob, `ExtraParams` longblob, - PRIMARY KEY (`UUID`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - -CREATE TABLE `primitems` ( - `itemID` varchar(255) NOT NULL, - `primID` varchar(255) default NULL, - `assetID` varchar(255) default NULL, - `parentFolderID` varchar(255) default NULL, - `invType` int(11) default NULL, - `assetType` int(11) default NULL, - `name` varchar(255) default NULL, - `description` varchar(255) default NULL, - `creationDate` bigint(20) default NULL, - `creatorID` varchar(255) default NULL, - `ownerID` varchar(255) default NULL, - `lastOwnerID` varchar(255) default NULL, - `groupID` varchar(255) default NULL, - `nextPermissions` int(11) default NULL, - `currentPermissions` int(11) default NULL, - `basePermissions` int(11) default NULL, - `everyonePermissions` int(11) default NULL, - `groupPermissions` int(11) default NULL, - PRIMARY KEY (`itemID`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - -CREATE TABLE `terrain` ( - `RegionUUID` varchar(255) default NULL, - `Revision` int(11) default NULL, + `UUID` char(36) NOT NULL DEFAULT '', + `Media` text, + `LastAttachPoint` int(4) NOT NULL DEFAULT '0', + PRIMARY KEY (`UUID`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +CREATE TABLE IF NOT EXISTS `primitems` ( + `invType` int(11) DEFAULT NULL, + `assetType` int(11) DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `description` varchar(255) DEFAULT NULL, + `creationDate` bigint(20) DEFAULT NULL, + `nextPermissions` int(11) DEFAULT NULL, + `currentPermissions` int(11) DEFAULT NULL, + `basePermissions` int(11) DEFAULT NULL, + `everyonePermissions` int(11) DEFAULT NULL, + `groupPermissions` int(11) DEFAULT NULL, + `flags` int(11) NOT NULL DEFAULT '0', + `itemID` char(36) NOT NULL DEFAULT '', + `primID` char(36) DEFAULT NULL, + `assetID` char(36) DEFAULT NULL, + `parentFolderID` char(36) DEFAULT NULL, + `CreatorID` varchar(255) NOT NULL DEFAULT '', + `ownerID` char(36) DEFAULT NULL, + `groupID` char(36) DEFAULT NULL, + `lastOwnerID` char(36) DEFAULT NULL, + PRIMARY KEY (`itemID`), + KEY `primitems_primid` (`primID`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +CREATE TABLE IF NOT EXISTS `terrain` ( + `RegionUUID` varchar(255) DEFAULT NULL, + `Revision` int(11) DEFAULT NULL, `Heightfield` longblob -) ENGINE=MyISAM DEFAULT CHARSET=latin1; +) ENGINE=InnoDB DEFAULT CHARSET=latin1; -CREATE TABLE `land` ( +CREATE TABLE IF NOT EXISTS `land` ( `UUID` varchar(255) NOT NULL, - `RegionUUID` varchar(255) default NULL, - `LocalLandID` int(11) default NULL, + `RegionUUID` varchar(255) DEFAULT NULL, + `LocalLandID` int(11) DEFAULT NULL, `Bitmap` longblob, - `Name` varchar(255) default NULL, - `Description` varchar(255) default NULL, - `OwnerUUID` varchar(255) default NULL, - `IsGroupOwned` int(11) default NULL, - `Area` int(11) default NULL, - `AuctionID` int(11) default NULL, - `Category` int(11) default NULL, - `ClaimDate` int(11) default NULL, - `ClaimPrice` int(11) default NULL, - `GroupUUID` varchar(255) default NULL, - `SalePrice` int(11) default NULL, - `LandStatus` int(11) default NULL, - `LandFlags` int(11) default NULL, - `LandingType` int(11) default NULL, - `MediaAutoScale` int(11) default NULL, - `MediaTextureUUID` varchar(255) default NULL, - `MediaURL` varchar(255) default NULL, - `MusicURL` varchar(255) default NULL, - `PassHours` float default NULL, - `PassPrice` int(11) default NULL, - `SnapshotUUID` varchar(255) default NULL, - `UserLocationX` float default NULL, - `UserLocationY` float default NULL, - `UserLocationZ` float default NULL, - `UserLookAtX` float default NULL, - `UserLookAtY` float default NULL, - `UserLookAtZ` float default NULL, - `AuthbuyerID` varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000', - PRIMARY KEY (`UUID`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -CREATE TABLE `landaccesslist` ( - `LandUUID` varchar(255) default NULL, - `AccessUUID` varchar(255) default NULL, - `Flags` int(11) default NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - -COMMIT; - -:VERSION 2 #--------------------- - -BEGIN; - -CREATE index prims_regionuuid on prims(RegionUUID); -CREATE index primitems_primid on primitems(primID); - -COMMIT; - -:VERSION 3 #--------------------- - -BEGIN; - CREATE TABLE regionban (regionUUID VARCHAR(36) NOT NULL, bannedUUID VARCHAR(36) NOT NULL, bannedIp VARCHAR(16) NOT NULL, bannedIpHostMask VARCHAR(16) NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Rev. 1'; -COMMIT; - -:VERSION 4 #--------------------- - -BEGIN; - -ALTER TABLE primitems add flags integer not null default 0; - -COMMIT; - -:VERSION 5 #--------------------- -BEGIN; - -create table regionsettings ( - regionUUID char(36) not null, - block_terraform integer not null, - block_fly integer not null, - allow_damage integer not null, - restrict_pushing integer not null, - allow_land_resell integer not null, - allow_land_join_divide integer not null, - block_show_in_search integer not null, - agent_limit integer not null, - object_bonus float not null, - maturity integer not null, - disable_scripts integer not null, - disable_collisions integer not null, - disable_physics integer not null, - terrain_texture_1 char(36) not null, - terrain_texture_2 char(36) not null, - terrain_texture_3 char(36) not null, - terrain_texture_4 char(36) not null, - elevation_1_nw float not null, - elevation_2_nw float not null, - elevation_1_ne float not null, - elevation_2_ne float not null, - elevation_1_se float not null, - elevation_2_se float not null, - elevation_1_sw float not null, - elevation_2_sw float not null, - water_height float not null, - terrain_raise_limit float not null, - terrain_lower_limit float not null, - use_estate_sun integer not null, - fixed_sun integer not null, - sun_position float not null, - covenant char(36), - primary key(regionUUID) -); - -COMMIT; - - -:VERSION 6 #--------------------- - -BEGIN; - -alter table landaccesslist ENGINE = MyISAM; -alter table migrations ENGINE = MyISAM; -alter table primitems ENGINE = MyISAM; -alter table prims ENGINE = MyISAM; -alter table primshapes ENGINE = MyISAM; -alter table regionsettings ENGINE = MyISAM; -alter table terrain ENGINE = MyISAM; - -COMMIT; - -:VERSION 7 #--------------------- - -BEGIN; - -ALTER TABLE prims change UUID UUIDold varchar(255); -ALTER TABLE prims change RegionUUID RegionUUIDold varchar(255); -ALTER TABLE prims change CreatorID CreatorIDold varchar(255); -ALTER TABLE prims change OwnerID OwnerIDold varchar(255); -ALTER TABLE prims change GroupID GroupIDold varchar(255); -ALTER TABLE prims change LastOwnerID LastOwnerIDold varchar(255); -ALTER TABLE prims add UUID char(36); -ALTER TABLE prims add RegionUUID char(36); -ALTER TABLE prims add CreatorID char(36); -ALTER TABLE prims add OwnerID char(36); -ALTER TABLE prims add GroupID char(36); -ALTER TABLE prims add LastOwnerID char(36); -UPDATE prims set UUID = UUIDold, RegionUUID = RegionUUIDold, CreatorID = CreatorIDold, OwnerID = OwnerIDold, GroupID = GroupIDold, LastOwnerID = LastOwnerIDold; -ALTER TABLE prims drop UUIDold; -ALTER TABLE prims drop RegionUUIDold; -ALTER TABLE prims drop CreatorIDold; -ALTER TABLE prims drop OwnerIDold; -ALTER TABLE prims drop GroupIDold; -ALTER TABLE prims drop LastOwnerIDold; -ALTER TABLE prims add constraint primary key(UUID); -ALTER TABLE prims add index prims_regionuuid(RegionUUID); - -COMMIT; - -:VERSION 8 #--------------------- - -BEGIN; - -ALTER TABLE primshapes change UUID UUIDold varchar(255); -ALTER TABLE primshapes add UUID char(36); -UPDATE primshapes set UUID = UUIDold; -ALTER TABLE primshapes drop UUIDold; -ALTER TABLE primshapes add constraint primary key(UUID); - -COMMIT; - -:VERSION 9 #--------------------- - -BEGIN; - -ALTER TABLE primitems change itemID itemIDold varchar(255); -ALTER TABLE primitems change primID primIDold varchar(255); -ALTER TABLE primitems change assetID assetIDold varchar(255); -ALTER TABLE primitems change parentFolderID parentFolderIDold varchar(255); -ALTER TABLE primitems change creatorID creatorIDold varchar(255); -ALTER TABLE primitems change ownerID ownerIDold varchar(255); -ALTER TABLE primitems change groupID groupIDold varchar(255); -ALTER TABLE primitems change lastOwnerID lastOwnerIDold varchar(255); -ALTER TABLE primitems add itemID char(36); -ALTER TABLE primitems add primID char(36); -ALTER TABLE primitems add assetID char(36); -ALTER TABLE primitems add parentFolderID char(36); -ALTER TABLE primitems add creatorID char(36); -ALTER TABLE primitems add ownerID char(36); -ALTER TABLE primitems add groupID char(36); -ALTER TABLE primitems add lastOwnerID char(36); -UPDATE primitems set itemID = itemIDold, primID = primIDold, assetID = assetIDold, parentFolderID = parentFolderIDold, creatorID = creatorIDold, ownerID = ownerIDold, groupID = groupIDold, lastOwnerID = lastOwnerIDold; -ALTER TABLE primitems drop itemIDold; -ALTER TABLE primitems drop primIDold; -ALTER TABLE primitems drop assetIDold; -ALTER TABLE primitems drop parentFolderIDold; -ALTER TABLE primitems drop creatorIDold; -ALTER TABLE primitems drop ownerIDold; -ALTER TABLE primitems drop groupIDold; -ALTER TABLE primitems drop lastOwnerIDold; -ALTER TABLE primitems add constraint primary key(itemID); -ALTER TABLE primitems add index primitems_primid(primID); - -COMMIT; - -:VERSION 10 #--------------------- - -# 1 "010_RegionStore.sql" -# 1 "" -# 1 "" -# 1 "010_RegionStore.sql" -BEGIN; - -DELETE FROM regionsettings; - -COMMIT; - - -:VERSION 11 #--------------------- - -BEGIN; - -ALTER TABLE prims change SceneGroupID SceneGroupIDold varchar(255); -ALTER TABLE prims add SceneGroupID char(36); -UPDATE prims set SceneGroupID = SceneGroupIDold; -ALTER TABLE prims drop SceneGroupIDold; -ALTER TABLE prims add index prims_scenegroupid(SceneGroupID); - -COMMIT; - -:VERSION 12 #--------------------- - -BEGIN; - -ALTER TABLE prims add index prims_parentid(ParentID); - -COMMIT; - -:VERSION 13 #--------------------- -begin; - -drop table regionsettings; - -CREATE TABLE `regionsettings` ( + `Name` varchar(255) DEFAULT NULL, + `Description` varchar(255) DEFAULT NULL, + `OwnerUUID` varchar(255) DEFAULT NULL, + `IsGroupOwned` int(11) DEFAULT NULL, + `Area` int(11) DEFAULT NULL, + `AuctionID` int(11) DEFAULT NULL, + `Category` int(11) DEFAULT NULL, + `ClaimDate` int(11) DEFAULT NULL, + `ClaimPrice` int(11) DEFAULT NULL, + `GroupUUID` varchar(255) DEFAULT NULL, + `SalePrice` int(11) DEFAULT NULL, + `LandStatus` int(11) DEFAULT NULL, + `LandFlags` int(10) unsigned DEFAULT NULL, + `LandingType` int(11) DEFAULT NULL, + `MediaAutoScale` int(11) DEFAULT NULL, + `MediaTextureUUID` varchar(255) DEFAULT NULL, + `MediaURL` varchar(255) DEFAULT NULL, + `MusicURL` varchar(255) DEFAULT NULL, + `PassHours` float DEFAULT NULL, + `PassPrice` int(11) DEFAULT NULL, + `SnapshotUUID` varchar(255) DEFAULT NULL, + `UserLocationX` float DEFAULT NULL, + `UserLocationY` float DEFAULT NULL, + `UserLocationZ` float DEFAULT NULL, + `UserLookAtX` float DEFAULT NULL, + `UserLookAtY` float DEFAULT NULL, + `UserLookAtZ` float DEFAULT NULL, + `AuthbuyerID` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `OtherCleanTime` int(11) NOT NULL DEFAULT '0', + `Dwell` int(11) NOT NULL DEFAULT '0', + `MediaType` varchar(32) NOT NULL DEFAULT 'none/none', + `MediaDescription` varchar(255) NOT NULL DEFAULT '', + `MediaSize` varchar(16) NOT NULL DEFAULT '0,0', + `MediaLoop` tinyint(1) NOT NULL DEFAULT '0', + `ObscureMusic` tinyint(1) NOT NULL DEFAULT '0', + `ObscureMedia` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`UUID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `landaccesslist` ( + `LandUUID` varchar(255) DEFAULT NULL, + `AccessUUID` varchar(255) DEFAULT NULL, + `Flags` int(11) DEFAULT NULL, + `Expires` int(11) NOT NULL DEFAULT '0' +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +CREATE TABLE IF NOT EXISTS `regionban` ( + `regionUUID` varchar(36) NOT NULL, + `bannedUUID` varchar(36) NOT NULL, + `bannedIp` varchar(16) NOT NULL, + `bannedIpHostMask` varchar(16) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `regionsettings` ( `regionUUID` char(36) NOT NULL, `block_terraform` int(11) NOT NULL, `block_fly` int(11) NOT NULL, @@ -358,7 +230,7 @@ CREATE TABLE `regionsettings` ( `allow_land_join_divide` int(11) NOT NULL, `block_show_in_search` int(11) NOT NULL, `agent_limit` int(11) NOT NULL, - `object_bonus` float NOT NULL, + `object_bonus` double NOT NULL, `maturity` int(11) NOT NULL, `disable_scripts` int(11) NOT NULL, `disable_collisions` int(11) NOT NULL, @@ -367,360 +239,35 @@ CREATE TABLE `regionsettings` ( `terrain_texture_2` char(36) NOT NULL, `terrain_texture_3` char(36) NOT NULL, `terrain_texture_4` char(36) NOT NULL, - `elevation_1_nw` float NOT NULL, - `elevation_2_nw` float NOT NULL, - `elevation_1_ne` float NOT NULL, - `elevation_2_ne` float NOT NULL, - `elevation_1_se` float NOT NULL, - `elevation_2_se` float NOT NULL, - `elevation_1_sw` float NOT NULL, - `elevation_2_sw` float NOT NULL, - `water_height` float NOT NULL, - `terrain_raise_limit` float NOT NULL, - `terrain_lower_limit` float NOT NULL, + `elevation_1_nw` double NOT NULL, + `elevation_2_nw` double NOT NULL, + `elevation_1_ne` double NOT NULL, + `elevation_2_ne` double NOT NULL, + `elevation_1_se` double NOT NULL, + `elevation_2_se` double NOT NULL, + `elevation_1_sw` double NOT NULL, + `elevation_2_sw` double NOT NULL, + `water_height` double NOT NULL, + `terrain_raise_limit` double NOT NULL, + `terrain_lower_limit` double NOT NULL, `use_estate_sun` int(11) NOT NULL, `fixed_sun` int(11) NOT NULL, - `sun_position` float NOT NULL, - `covenant` char(36) default NULL, + `sun_position` double NOT NULL, + `covenant` char(36) DEFAULT NULL, `Sandbox` tinyint(4) NOT NULL, - PRIMARY KEY (`regionUUID`) -) ENGINE=MyISAM; - -commit; - -:VERSION 16 #--------------------- - -BEGIN; - -ALTER TABLE prims ADD COLUMN PayPrice integer not null default 0; -ALTER TABLE prims ADD COLUMN PayButton1 integer not null default 0; -ALTER TABLE prims ADD COLUMN PayButton2 integer not null default 0; -ALTER TABLE prims ADD COLUMN PayButton3 integer not null default 0; -ALTER TABLE prims ADD COLUMN PayButton4 integer not null default 0; -ALTER TABLE prims ADD COLUMN LoopedSound char(36) not null default '00000000-0000-0000-0000-000000000000'; -ALTER TABLE prims ADD COLUMN LoopedSoundGain float not null default 0.0; -ALTER TABLE prims ADD COLUMN TextureAnimation blob; -ALTER TABLE prims ADD COLUMN OmegaX float not null default 0.0; -ALTER TABLE prims ADD COLUMN OmegaY float not null default 0.0; -ALTER TABLE prims ADD COLUMN OmegaZ float not null default 0.0; -ALTER TABLE prims ADD COLUMN CameraEyeOffsetX float not null default 0.0; -ALTER TABLE prims ADD COLUMN CameraEyeOffsetY float not null default 0.0; -ALTER TABLE prims ADD COLUMN CameraEyeOffsetZ float not null default 0.0; -ALTER TABLE prims ADD COLUMN CameraAtOffsetX float not null default 0.0; -ALTER TABLE prims ADD COLUMN CameraAtOffsetY float not null default 0.0; -ALTER TABLE prims ADD COLUMN CameraAtOffsetZ float not null default 0.0; -ALTER TABLE prims ADD COLUMN ForceMouselook tinyint not null default 0; -ALTER TABLE prims ADD COLUMN ScriptAccessPin integer not null default 0; -ALTER TABLE prims ADD COLUMN AllowedDrop tinyint not null default 0; -ALTER TABLE prims ADD COLUMN DieAtEdge tinyint not null default 0; -ALTER TABLE prims ADD COLUMN SalePrice integer not null default 10; -ALTER TABLE prims ADD COLUMN SaleType tinyint not null default 0; - -COMMIT; - - -:VERSION 17 #--------------------- - -BEGIN; - -ALTER TABLE prims ADD COLUMN ColorR integer not null default 0; -ALTER TABLE prims ADD COLUMN ColorG integer not null default 0; -ALTER TABLE prims ADD COLUMN ColorB integer not null default 0; -ALTER TABLE prims ADD COLUMN ColorA integer not null default 0; -ALTER TABLE prims ADD COLUMN ParticleSystem blob; - -COMMIT; - - -:VERSION 18 #--------------------- - -begin; - -ALTER TABLE prims ADD COLUMN ClickAction tinyint NOT NULL default 0; - -commit; - -:VERSION 19 #--------------------- - -begin; - -ALTER TABLE prims ADD COLUMN Material tinyint NOT NULL default 3; - -commit; - - -:VERSION 20 #--------------------- - -begin; - -ALTER TABLE land ADD COLUMN OtherCleanTime integer NOT NULL default 0; -ALTER TABLE land ADD COLUMN Dwell integer NOT NULL default 0; - -commit; - -:VERSION 21 #--------------------- - -begin; - -ALTER TABLE regionsettings ADD COLUMN sunvectorx double NOT NULL default 0; -ALTER TABLE regionsettings ADD COLUMN sunvectory double NOT NULL default 0; -ALTER TABLE regionsettings ADD COLUMN sunvectorz double NOT NULL default 0; - -commit; - - -:VERSION 22 #--------------------- - -BEGIN; - -ALTER TABLE prims ADD COLUMN CollisionSound char(36) not null default '00000000-0000-0000-0000-000000000000'; -ALTER TABLE prims ADD COLUMN CollisionSoundVolume float not null default 0.0; - -COMMIT; - -:VERSION 23 #--------------------- - -BEGIN; - -ALTER TABLE prims ADD COLUMN LinkNumber integer not null default 0; - -COMMIT; - -:VERSION 24 #--------------------- - -BEGIN; - -alter table regionsettings change column `object_bonus` `object_bonus` double NOT NULL; -alter table regionsettings change column `elevation_1_nw` `elevation_1_nw` double NOT NULL; -alter table regionsettings change column `elevation_2_nw` `elevation_2_nw` double NOT NULL; -alter table regionsettings change column `elevation_1_ne` `elevation_1_ne` double NOT NULL; -alter table regionsettings change column `elevation_2_ne` `elevation_2_ne` double NOT NULL; -alter table regionsettings change column `elevation_1_se` `elevation_1_se` double NOT NULL; -alter table regionsettings change column `elevation_2_se` `elevation_2_se` double NOT NULL; -alter table regionsettings change column `elevation_1_sw` `elevation_1_sw` double NOT NULL; -alter table regionsettings change column `elevation_2_sw` `elevation_2_sw` double NOT NULL; -alter table regionsettings change column `water_height` `water_height` double NOT NULL; -alter table regionsettings change column `terrain_raise_limit` `terrain_raise_limit` double NOT NULL; -alter table regionsettings change column `terrain_lower_limit` `terrain_lower_limit` double NOT NULL; -alter table regionsettings change column `sun_position` `sun_position` double NOT NULL; - -COMMIT; - - -:VERSION 25 #--------------------- - -BEGIN; - -alter table prims change column `PositionX` `PositionX` double default NULL; -alter table prims change column `PositionY` `PositionY` double default NULL; -alter table prims change column `PositionZ` `PositionZ` double default NULL; -alter table prims change column `GroupPositionX` `GroupPositionX` double default NULL; -alter table prims change column `GroupPositionY` `GroupPositionY` double default NULL; -alter table prims change column `GroupPositionZ` `GroupPositionZ` double default NULL; -alter table prims change column `VelocityX` `VelocityX` double default NULL; -alter table prims change column `VelocityY` `VelocityY` double default NULL; -alter table prims change column `VelocityZ` `VelocityZ` double default NULL; -alter table prims change column `AngularVelocityX` `AngularVelocityX` double default NULL; -alter table prims change column `AngularVelocityY` `AngularVelocityY` double default NULL; -alter table prims change column `AngularVelocityZ` `AngularVelocityZ` double default NULL; -alter table prims change column `AccelerationX` `AccelerationX` double default NULL; -alter table prims change column `AccelerationY` `AccelerationY` double default NULL; -alter table prims change column `AccelerationZ` `AccelerationZ` double default NULL; -alter table prims change column `RotationX` `RotationX` double default NULL; -alter table prims change column `RotationY` `RotationY` double default NULL; -alter table prims change column `RotationZ` `RotationZ` double default NULL; -alter table prims change column `RotationW` `RotationW` double default NULL; -alter table prims change column `SitTargetOffsetX` `SitTargetOffsetX` double default NULL; -alter table prims change column `SitTargetOffsetY` `SitTargetOffsetY` double default NULL; -alter table prims change column `SitTargetOffsetZ` `SitTargetOffsetZ` double default NULL; -alter table prims change column `SitTargetOrientW` `SitTargetOrientW` double default NULL; -alter table prims change column `SitTargetOrientX` `SitTargetOrientX` double default NULL; -alter table prims change column `SitTargetOrientY` `SitTargetOrientY` double default NULL; -alter table prims change column `SitTargetOrientZ` `SitTargetOrientZ` double default NULL; -alter table prims change column `LoopedSoundGain` `LoopedSoundGain` double NOT NULL default '0'; -alter table prims change column `OmegaX` `OmegaX` double NOT NULL default '0'; -alter table prims change column `OmegaY` `OmegaY` double NOT NULL default '0'; -alter table prims change column `OmegaZ` `OmegaZ` double NOT NULL default '0'; -alter table prims change column `CameraEyeOffsetX` `CameraEyeOffsetX` double NOT NULL default '0'; -alter table prims change column `CameraEyeOffsetY` `CameraEyeOffsetY` double NOT NULL default '0'; -alter table prims change column `CameraEyeOffsetZ` `CameraEyeOffsetZ` double NOT NULL default '0'; -alter table prims change column `CameraAtOffsetX` `CameraAtOffsetX` double NOT NULL default '0'; -alter table prims change column `CameraAtOffsetY` `CameraAtOffsetY` double NOT NULL default '0'; -alter table prims change column `CameraAtOffsetZ` `CameraAtOffsetZ` double NOT NULL default '0'; -alter table prims change column `CollisionSoundVolume` `CollisionSoundVolume` double NOT NULL default '0'; - -alter table primshapes change column `ScaleX` `ScaleX` double NOT NULL default '0'; -alter table primshapes change column `ScaleY` `ScaleY` double NOT NULL default '0'; -alter table primshapes change column `ScaleZ` `ScaleZ` double NOT NULL default '0'; - -COMMIT; - -:VERSION 26 #--------------------- - -begin; - -alter table prims change column `PositionX` `PositionX` double default NULL; -alter table prims change column `PositionY` `PositionY` double default NULL; -alter table prims change column `PositionZ` `PositionZ` double default NULL; -alter table prims change column `GroupPositionX` `GroupPositionX` double default NULL; -alter table prims change column `GroupPositionY` `GroupPositionY` double default NULL; -alter table prims change column `GroupPositionZ` `GroupPositionZ` double default NULL; -alter table prims change column `VelocityX` `VelocityX` double default NULL; -alter table prims change column `VelocityY` `VelocityY` double default NULL; -alter table prims change column `VelocityZ` `VelocityZ` double default NULL; -alter table prims change column `AngularVelocityX` `AngularVelocityX` double default NULL; -alter table prims change column `AngularVelocityY` `AngularVelocityY` double default NULL; -alter table prims change column `AngularVelocityZ` `AngularVelocityZ` double default NULL; -alter table prims change column `AccelerationX` `AccelerationX` double default NULL; -alter table prims change column `AccelerationY` `AccelerationY` double default NULL; -alter table prims change column `AccelerationZ` `AccelerationZ` double default NULL; -alter table prims change column `RotationX` `RotationX` double default NULL; -alter table prims change column `RotationY` `RotationY` double default NULL; -alter table prims change column `RotationZ` `RotationZ` double default NULL; -alter table prims change column `RotationW` `RotationW` double default NULL; -alter table prims change column `SitTargetOffsetX` `SitTargetOffsetX` double default NULL; -alter table prims change column `SitTargetOffsetY` `SitTargetOffsetY` double default NULL; -alter table prims change column `SitTargetOffsetZ` `SitTargetOffsetZ` double default NULL; -alter table prims change column `SitTargetOrientW` `SitTargetOrientW` double default NULL; -alter table prims change column `SitTargetOrientX` `SitTargetOrientX` double default NULL; -alter table prims change column `SitTargetOrientY` `SitTargetOrientY` double default NULL; -alter table prims change column `SitTargetOrientZ` `SitTargetOrientZ` double default NULL; -alter table prims change column `LoopedSoundGain` `LoopedSoundGain` double NOT NULL default '0'; -alter table prims change column `OmegaX` `OmegaX` double NOT NULL default '0'; -alter table prims change column `OmegaY` `OmegaY` double NOT NULL default '0'; -alter table prims change column `OmegaZ` `OmegaZ` double NOT NULL default '0'; -alter table prims change column `CameraEyeOffsetX` `CameraEyeOffsetX` double NOT NULL default '0'; -alter table prims change column `CameraEyeOffsetY` `CameraEyeOffsetY` double NOT NULL default '0'; -alter table prims change column `CameraEyeOffsetZ` `CameraEyeOffsetZ` double NOT NULL default '0'; -alter table prims change column `CameraAtOffsetX` `CameraAtOffsetX` double NOT NULL default '0'; -alter table prims change column `CameraAtOffsetY` `CameraAtOffsetY` double NOT NULL default '0'; -alter table prims change column `CameraAtOffsetZ` `CameraAtOffsetZ` double NOT NULL default '0'; -alter table prims change column `CollisionSoundVolume` `CollisionSoundVolume` double NOT NULL default '0'; - -commit; - -:VERSION 27 #--------------------- - -BEGIN; - -ALTER TABLE prims DROP COLUMN ParentID; - -COMMIT; - -:VERSION 28 #--------------------- - -BEGIN; - -update terrain - set RegionUUID = concat(substr(RegionUUID, 1, 8), "-", substr(RegionUUID, 9, 4), "-", substr(RegionUUID, 13, 4), "-", substr(RegionUUID, 17, 4), "-", substr(RegionUUID, 21, 12)) - where RegionUUID not like '%-%'; - - -update landaccesslist - set LandUUID = concat(substr(LandUUID, 1, 8), "-", substr(LandUUID, 9, 4), "-", substr(LandUUID, 13, 4), "-", substr(LandUUID, 17, 4), "-", substr(LandUUID, 21, 12)) - where LandUUID not like '%-%'; - -update landaccesslist - set AccessUUID = concat(substr(AccessUUID, 1, 8), "-", substr(AccessUUID, 9, 4), "-", substr(AccessUUID, 13, 4), "-", substr(AccessUUID, 17, 4), "-", substr(AccessUUID, 21, 12)) - where AccessUUID not like '%-%'; - - -update prims - set UUID = concat(substr(UUID, 1, 8), "-", substr(UUID, 9, 4), "-", substr(UUID, 13, 4), "-", substr(UUID, 17, 4), "-", substr(UUID, 21, 12)) - where UUID not like '%-%'; - -update prims - set RegionUUID = concat(substr(RegionUUID, 1, 8), "-", substr(RegionUUID, 9, 4), "-", substr(RegionUUID, 13, 4), "-", substr(RegionUUID, 17, 4), "-", substr(RegionUUID, 21, 12)) - where RegionUUID not like '%-%'; - -update prims - set SceneGroupID = concat(substr(SceneGroupID, 1, 8), "-", substr(SceneGroupID, 9, 4), "-", substr(SceneGroupID, 13, 4), "-", substr(SceneGroupID, 17, 4), "-", substr(SceneGroupID, 21, 12)) - where SceneGroupID not like '%-%'; - -update prims - set CreatorID = concat(substr(CreatorID, 1, 8), "-", substr(CreatorID, 9, 4), "-", substr(CreatorID, 13, 4), "-", substr(CreatorID, 17, 4), "-", substr(CreatorID, 21, 12)) - where CreatorID not like '%-%'; - -update prims - set OwnerID = concat(substr(OwnerID, 1, 8), "-", substr(OwnerID, 9, 4), "-", substr(OwnerID, 13, 4), "-", substr(OwnerID, 17, 4), "-", substr(OwnerID, 21, 12)) - where OwnerID not like '%-%'; - -update prims - set GroupID = concat(substr(GroupID, 1, 8), "-", substr(GroupID, 9, 4), "-", substr(GroupID, 13, 4), "-", substr(GroupID, 17, 4), "-", substr(GroupID, 21, 12)) - where GroupID not like '%-%'; - -update prims - set LastOwnerID = concat(substr(LastOwnerID, 1, 8), "-", substr(LastOwnerID, 9, 4), "-", substr(LastOwnerID, 13, 4), "-", substr(LastOwnerID, 17, 4), "-", substr(LastOwnerID, 21, 12)) - where LastOwnerID not like '%-%'; - - -update primshapes - set UUID = concat(substr(UUID, 1, 8), "-", substr(UUID, 9, 4), "-", substr(UUID, 13, 4), "-", substr(UUID, 17, 4), "-", substr(UUID, 21, 12)) - where UUID not like '%-%'; - - -update land - set UUID = concat(substr(UUID, 1, 8), "-", substr(UUID, 9, 4), "-", substr(UUID, 13, 4), "-", substr(UUID, 17, 4), "-", substr(UUID, 21, 12)) - where UUID not like '%-%'; - -update land - set RegionUUID = concat(substr(RegionUUID, 1, 8), "-", substr(RegionUUID, 9, 4), "-", substr(RegionUUID, 13, 4), "-", substr(RegionUUID, 17, 4), "-", substr(RegionUUID, 21, 12)) - where RegionUUID not like '%-%'; - -update land - set OwnerUUID = concat(substr(OwnerUUID, 1, 8), "-", substr(OwnerUUID, 9, 4), "-", substr(OwnerUUID, 13, 4), "-", substr(OwnerUUID, 17, 4), "-", substr(OwnerUUID, 21, 12)) - where OwnerUUID not like '%-%'; - -update land - set GroupUUID = concat(substr(GroupUUID, 1, 8), "-", substr(GroupUUID, 9, 4), "-", substr(GroupUUID, 13, 4), "-", substr(GroupUUID, 17, 4), "-", substr(GroupUUID, 21, 12)) - where GroupUUID not like '%-%'; - -update land - set MediaTextureUUID = concat(substr(MediaTextureUUID, 1, 8), "-", substr(MediaTextureUUID, 9, 4), "-", substr(MediaTextureUUID, 13, 4), "-", substr(MediaTextureUUID, 17, 4), "-", substr(MediaTextureUUID, 21, 12)) - where MediaTextureUUID not like '%-%'; - -update land - set SnapshotUUID = concat(substr(SnapshotUUID, 1, 8), "-", substr(SnapshotUUID, 9, 4), "-", substr(SnapshotUUID, 13, 4), "-", substr(SnapshotUUID, 17, 4), "-", substr(SnapshotUUID, 21, 12)) - where SnapshotUUID not like '%-%'; - -update land - set AuthbuyerID = concat(substr(AuthbuyerID, 1, 8), "-", substr(AuthbuyerID, 9, 4), "-", substr(AuthbuyerID, 13, 4), "-", substr(AuthbuyerID, 17, 4), "-", substr(AuthbuyerID, 21, 12)) - where AuthbuyerID not like '%-%'; - -COMMIT; - -:VERSION 29 #--------------------- - -BEGIN; - -ALTER TABLE prims ADD COLUMN PassTouches tinyint not null default 0; - -COMMIT; - -:VERSION 30 #--------------------- - -BEGIN; - -ALTER TABLE regionsettings ADD COLUMN loaded_creation_date varchar(20) default NULL; -ALTER TABLE regionsettings ADD COLUMN loaded_creation_time varchar(20) default NULL; -ALTER TABLE regionsettings ADD COLUMN loaded_creation_id varchar(64) default NULL; - -COMMIT; - -:VERSION 31 #--------------------- - -BEGIN; - -ALTER TABLE regionsettings DROP COLUMN loaded_creation_date; -ALTER TABLE regionsettings DROP COLUMN loaded_creation_time; -ALTER TABLE regionsettings ADD COLUMN loaded_creation_datetime int unsigned NOT NULL default 0; - -COMMIT; - -:VERSION 32 - -BEGIN; -CREATE TABLE `regionwindlight` ( + `sunvectorx` double NOT NULL DEFAULT '0', + `sunvectory` double NOT NULL DEFAULT '0', + `sunvectorz` double NOT NULL DEFAULT '0', + `loaded_creation_id` varchar(64) DEFAULT NULL, + `loaded_creation_datetime` int(10) unsigned NOT NULL DEFAULT '0', + `map_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `TelehubObject` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `covenant_datetime` int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`regionUUID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `regionwindlight` ( `region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000', `water_color_r` float(9,6) unsigned NOT NULL DEFAULT '4.000000', `water_color_g` float(9,6) unsigned NOT NULL DEFAULT '38.000000', @@ -779,172 +326,144 @@ CREATE TABLE `regionwindlight` ( `cloud_detail_x` float(3,2) unsigned NOT NULL DEFAULT '1.00', `cloud_detail_y` float(3,2) unsigned NOT NULL DEFAULT '0.53', `cloud_detail_density` float(3,2) unsigned NOT NULL DEFAULT '0.12', - `cloud_scroll_x` float(3,2) unsigned NOT NULL DEFAULT '0.20', + `cloud_scroll_x` float(4,2) NOT NULL DEFAULT '0.20', `cloud_scroll_x_lock` tinyint(1) unsigned NOT NULL DEFAULT '0', - `cloud_scroll_y` float(3,2) unsigned NOT NULL DEFAULT '0.01', + `cloud_scroll_y` float(4,2) NOT NULL DEFAULT '0.01', `cloud_scroll_y_lock` tinyint(1) unsigned NOT NULL DEFAULT '0', `draw_classic_clouds` tinyint(1) unsigned NOT NULL DEFAULT '1', PRIMARY KEY (`region_id`) -); - - -:VERSION 33 #--------------------- - -BEGIN; -ALTER TABLE regionsettings ADD map_tile_ID CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; -COMMIT; - -:VERSION 34 #--------------------- - -BEGIN; -ALTER TABLE `regionwindlight` CHANGE COLUMN `cloud_scroll_x` `cloud_scroll_x` FLOAT(4,2) NOT NULL DEFAULT '0.20' AFTER `cloud_detail_density`, CHANGE COLUMN `cloud_scroll_y` `cloud_scroll_y` FLOAT(4,2) NOT NULL DEFAULT '0.01' AFTER `cloud_scroll_x_lock`; -COMMIT; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -:VERSION 35 #--------------------- - -BEGIN; -ALTER TABLE prims ADD COLUMN MediaURL varchar(255); -ALTER TABLE primshapes ADD COLUMN Media TEXT; -COMMIT; - -:VERSION 36 #--------------------- - -BEGIN; -ALTER TABLE `land` ADD COLUMN `MediaType` VARCHAR(32) NOT NULL DEFAULT 'none/none' ; -ALTER TABLE `land` ADD COLUMN `MediaDescription` VARCHAR(255) NOT NULL DEFAULT ''; -ALTER TABLE `land` ADD COLUMN `MediaSize` VARCHAR(16) NOT NULL DEFAULT '0,0'; -ALTER TABLE `land` ADD COLUMN `MediaLoop` BOOLEAN NOT NULL DEFAULT FALSE; -ALTER TABLE `land` ADD COLUMN `ObscureMusic` BOOLEAN NOT NULL DEFAULT FALSE; -ALTER TABLE `land` ADD COLUMN `ObscureMedia` BOOLEAN NOT NULL DEFAULT FALSE; -COMMIT; - -:VERSION 37 #--------------------- - -BEGIN; - -ALTER TABLE `prims` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT ''; -ALTER TABLE `primitems` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT ''; - -COMMIT; - -:VERSION 38 #--------------------- - -BEGIN; - -alter table land ENGINE = MyISAM; -alter table landaccesslist ENGINE = MyISAM; -alter table migrations ENGINE = MyISAM; -alter table primitems ENGINE = MyISAM; -alter table prims ENGINE = MyISAM; -alter table primshapes ENGINE = MyISAM; -alter table regionban ENGINE = MyISAM; -alter table regionsettings ENGINE = MyISAM; -alter table terrain ENGINE = MyISAM; - -COMMIT; - -:VERSION 39 #--------------- Telehub support - -BEGIN; CREATE TABLE IF NOT EXISTS `spawn_points` ( - `RegionID` varchar(36) COLLATE utf8_unicode_ci NOT NULL, + `RegionID` varchar(36) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `Yaw` float NOT NULL, `Pitch` float NOT NULL, `Distance` float NOT NULL, KEY `RegionID` (`RegionID`) -) ENGINE=MyISAM; - -ALTER TABLE `regionsettings` ADD COLUMN `TelehubObject` varchar(36) NOT NULL; -COMMIT; - -:VERSION 40 #---------------- Parcels for sale - -BEGIN; -ALTER TABLE `regionsettings` ADD COLUMN `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; -COMMIT; - -:VERSION 41 #---------------- Timed bans/access - -BEGIN; -ALTER TABLE `landaccesslist` ADD COLUMN `Expires` INTEGER NOT NULL DEFAULT 0; -COMMIT; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -:VERSION 42 #--------------------- Region Covenant changed time - -BEGIN; -ALTER TABLE regionsettings ADD COLUMN covenant_datetime int unsigned NOT NULL DEFAULT '0'; -COMMIT; - -:VERSION 43 #--------------------- - -BEGIN; - -ALTER TABLE `regionsettings` MODIFY COLUMN `TelehubObject` VARCHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; - -COMMIT; - -:VERSION 44 #--------------------- Environment Settings - -BEGIN; - -CREATE TABLE `regionenvironment` ( +CREATE TABLE IF NOT EXISTS `regionenvironment` ( `region_id` varchar(36) NOT NULL, - `llsd_settings` TEXT NOT NULL, + `llsd_settings` text NOT NULL, PRIMARY KEY (`region_id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -COMMIT; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -:VERSION 45 - -BEGIN; - -CREATE TABLE `regionextra` (`RegionID` char(36) not null, `Name` varchar(32) not null, `value` text, primary key(`RegionID`, `Name`)); +CREATE TABLE IF NOT EXISTS `regionextra` ( + `RegionID` char(36) NOT NULL, + `Name` varchar(32) NOT NULL, + `value` text, + PRIMARY KEY (`RegionID`,`Name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; COMMIT; -:VERSION 46 #---------------- Dynamic attributes +:VERSION 52 #---- avination fields BEGIN; -ALTER TABLE prims ADD COLUMN DynAttrs TEXT; +ALTER TABLE `prims` ADD COLUMN `PassCollisions` tinyint(4) NOT NULL default '0'; +ALTER TABLE `prims` ADD COLUMN `Vehicle` TEXT default NULL; +ALTER TABLE `regionsettings` ADD COLUMN `block_search` tinyint(4) NOT NULL default '0'; +ALTER TABLE `regionsettings` ADD COLUMN `casino` tinyint(4) NOT NULL default '0'; +ALTER TABLE `land` ADD COLUMN `SeeAVs` tinyint(4) NOT NULL default '1'; +ALTER TABLE `land` ADD COLUMN `AnyAVSounds` tinyint(4) NOT NULL default '1'; +ALTER TABLE `land` ADD COLUMN `GroupAVSounds` tinyint(4) NOT NULL default '1'; COMMIT; -:VERSION 47 #---------------- Extra physics params +:VERSION 53 #---- STATUS ROTATION axis locks BEGIN; -ALTER TABLE prims ADD COLUMN `PhysicsShapeType` tinyint(4) NOT NULL default '0'; -ALTER TABLE prims ADD COLUMN `Density` double NOT NULL default '1000'; -ALTER TABLE prims ADD COLUMN `GravityModifier` double NOT NULL default '1'; -ALTER TABLE prims ADD COLUMN `Friction` double NOT NULL default '0.6'; -ALTER TABLE prims ADD COLUMN `Restitution` double NOT NULL default '0.5'; +ALTER TABLE `prims` ADD COLUMN `RotationAxisLocks` tinyint(4) NOT NULL default '0'; COMMIT; -:VERSION 48 #---------------- Keyframes +:VERSION 54 #----- add baked terrain store BEGIN; -ALTER TABLE prims ADD COLUMN `KeyframeMotion` blob; - -COMMIT; - -:VERSION 49 #--------------------- Save attachment info - -BEGIN; -ALTER TABLE prims ADD COLUMN AttachedPosX double default 0; -ALTER TABLE prims ADD COLUMN AttachedPosY double default 0; -ALTER TABLE prims ADD COLUMN AttachedPosZ double default 0; -ALTER TABLE primshapes ADD COLUMN LastAttachPoint int(4) not null default '0'; -COMMIT; - -:VERSION 50 #---- Change LandFlags to unsigned - -BEGIN; - -ALTER TABLE land CHANGE COLUMN LandFlags LandFlags int unsigned default null; - +CREATE TABLE IF NOT EXISTS `bakedterrain` ( + `RegionUUID` varchar(255) DEFAULT NULL, + `Revision` int(11) DEFAULT NULL, + `Heightfield` longblob +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +COMMIT; + +:VERSION 55 #----- Increase float precision for windlight needed by scripts + +BEGIN; + +ALTER TABLE `regionwindlight` + +MODIFY `water_fog_density_exponent` float(9,7) unsigned NOT NULL DEFAULT '4.0', +MODIFY `underwater_fog_modifier` float(9,8) unsigned NOT NULL DEFAULT '0.25', +MODIFY `reflection_wavelet_scale_1` float(9,7) unsigned NOT NULL DEFAULT '2.0', +MODIFY `reflection_wavelet_scale_2` float(9,7) unsigned NOT NULL DEFAULT '2.0', +MODIFY `reflection_wavelet_scale_3` float(9,7) unsigned NOT NULL DEFAULT '2.0', +MODIFY `fresnel_scale` float(9,8) unsigned NOT NULL DEFAULT '0.40', +MODIFY `fresnel_offset` float(9,8) unsigned NOT NULL DEFAULT '0.50', +MODIFY `refract_scale_above` float(9,8) unsigned NOT NULL DEFAULT '0.03', +MODIFY `refract_scale_below` float(9,8) unsigned NOT NULL DEFAULT '0.20', +MODIFY `blur_multiplier` float(9,8) unsigned NOT NULL DEFAULT '0.040', +MODIFY `big_wave_direction_x` float(9,8) NOT NULL DEFAULT '1.05', +MODIFY `big_wave_direction_y` float(9,8) NOT NULL DEFAULT '-0.42', +MODIFY `little_wave_direction_x` float(9,8) NOT NULL DEFAULT '1.11', +MODIFY `little_wave_direction_y` float(9,8) NOT NULL DEFAULT '-1.16', +MODIFY `horizon_r` float(9,8) unsigned NOT NULL DEFAULT '0.25', +MODIFY `horizon_g` float(9,8) unsigned NOT NULL DEFAULT '0.25', +MODIFY `horizon_b` float(9,8) unsigned NOT NULL DEFAULT '0.32', +MODIFY `horizon_i` float(9,8) unsigned NOT NULL DEFAULT '0.32', +MODIFY `haze_horizon` float(9,8) unsigned NOT NULL DEFAULT '0.19', +MODIFY `blue_density_r` float(9,8) unsigned NOT NULL DEFAULT '0.12', +MODIFY `blue_density_g` float(9,8) unsigned NOT NULL DEFAULT '0.22', +MODIFY `blue_density_b` float(9,8) unsigned NOT NULL DEFAULT '0.38', +MODIFY `blue_density_i` float(9,8) unsigned NOT NULL DEFAULT '0.38', +MODIFY `haze_density` float(9,8) unsigned NOT NULL DEFAULT '0.70', +MODIFY `density_multiplier` float(9,8) unsigned NOT NULL DEFAULT '0.18', +MODIFY `distance_multiplier` float(9,6) unsigned NOT NULL DEFAULT '0.8', +MODIFY `sun_moon_color_r` float(9,8) unsigned NOT NULL DEFAULT '0.24', +MODIFY `sun_moon_color_g` float(9,8) unsigned NOT NULL DEFAULT '0.26', +MODIFY `sun_moon_color_b` float(9,8) unsigned NOT NULL DEFAULT '0.30', +MODIFY `sun_moon_color_i` float(9,8) unsigned NOT NULL DEFAULT '0.30', +MODIFY `sun_moon_position` float(9,8) unsigned NOT NULL DEFAULT '0.317', +MODIFY `ambient_r` float(9,8) unsigned NOT NULL DEFAULT '0.35', +MODIFY `ambient_g` float(9,8) unsigned NOT NULL DEFAULT '0.35', +MODIFY `ambient_b` float(9,8) unsigned NOT NULL DEFAULT '0.35', +MODIFY `ambient_i` float(9,8) unsigned NOT NULL DEFAULT '0.35', +MODIFY `east_angle` float(9,8) unsigned NOT NULL DEFAULT '0.00', +MODIFY `sun_glow_focus` float(9,8) unsigned NOT NULL DEFAULT '0.10', +MODIFY `sun_glow_size` float(9,8) unsigned NOT NULL DEFAULT '1.75', +MODIFY `scene_gamma` float(9,7) unsigned NOT NULL DEFAULT '1.00', +MODIFY `star_brightness` float(9,8) unsigned NOT NULL DEFAULT '0.00', +MODIFY `cloud_color_r` float(9,8) unsigned NOT NULL DEFAULT '0.41', +MODIFY `cloud_color_g` float(9,8) unsigned NOT NULL DEFAULT '0.41', +MODIFY `cloud_color_b` float(9,8) unsigned NOT NULL DEFAULT '0.41', +MODIFY `cloud_color_i` float(9,8) unsigned NOT NULL DEFAULT '0.41', +MODIFY `cloud_x` float(9,8) unsigned NOT NULL DEFAULT '1.00', +MODIFY `cloud_y` float(9,8) unsigned NOT NULL DEFAULT '0.53', +MODIFY `cloud_density` float(9,8) unsigned NOT NULL DEFAULT '1.00', +MODIFY `cloud_coverage` float(9,8) unsigned NOT NULL DEFAULT '0.27', +MODIFY `cloud_scale` float(9,8) unsigned NOT NULL DEFAULT '0.42', +MODIFY `cloud_detail_x` float(9,8) unsigned NOT NULL DEFAULT '1.00', +MODIFY `cloud_detail_y` float(9,8) unsigned NOT NULL DEFAULT '0.53', +MODIFY `cloud_detail_density` float(9,8) unsigned NOT NULL DEFAULT '0.12', +MODIFY `cloud_scroll_x` float(9,7) NOT NULL DEFAULT '0.20', +MODIFY `cloud_scroll_y` float(9,7) NOT NULL DEFAULT '0.01'; + +COMMIT; + +:VERSION 56 #----- Add RezzerID field in table prims + +BEGIN; + +ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL; + +COMMIT; + +:VERSION 57 #----- Add physics inertia data + +BEGIN; +ALTER TABLE `prims` ADD COLUMN `PhysInertia` TEXT default NULL; COMMIT; - diff --git a/OpenSim/Data/MySQL/Resources/UserAccount.migrations b/OpenSim/Data/MySQL/Resources/UserAccount.migrations index 97e5e4f..98be097 100644 --- a/OpenSim/Data/MySQL/Resources/UserAccount.migrations +++ b/OpenSim/Data/MySQL/Resources/UserAccount.migrations @@ -1,47 +1,31 @@ -:VERSION 1 # ------------------------- +:VERSION 5 # ------------------------- BEGIN; -CREATE TABLE `UserAccounts` ( - `PrincipalID` CHAR(36) NOT NULL, - `ScopeID` CHAR(36) NOT NULL, - `FirstName` VARCHAR(64) NOT NULL, - `LastName` VARCHAR(64) NOT NULL, - `Email` VARCHAR(64), - `ServiceURLs` TEXT, - `Created` INT(11) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; +CREATE TABLE IF NOT EXISTS `UserAccounts` ( + `PrincipalID` char(36) NOT NULL, + `ScopeID` char(36) NOT NULL, + `FirstName` varchar(64) NOT NULL, + `LastName` varchar(64) NOT NULL, + `Email` varchar(64) DEFAULT NULL, + `ServiceURLs` text, + `Created` int(11) DEFAULT NULL, + `UserLevel` int(11) NOT NULL DEFAULT '0', + `UserFlags` int(11) NOT NULL DEFAULT '0', + `UserTitle` varchar(64) NOT NULL DEFAULT '', + UNIQUE KEY `PrincipalID` (`PrincipalID`), + KEY `Email` (`Email`), + KEY `FirstName` (`FirstName`), + KEY `LastName` (`LastName`), + KEY `Name` (`FirstName`,`LastName`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; COMMIT; -:VERSION 2 # ------------------------- +:VERSION 6 # ------------------------- BEGIN; -INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created) SELECT `UUID` AS PrincipalID, '00000000-0000-0000-0000-000000000000' AS ScopeID, username AS FirstName, lastname AS LastName, email as Email, CONCAT('AssetServerURI=', userAssetURI, ' InventoryServerURI=', userInventoryURI, ' GatewayURI= HomeURI=') AS ServiceURLs, created as Created FROM users; +ALTER TABLE `UserAccounts` ADD `active` INT NOT NULL DEFAULT '1'; COMMIT; - -:VERSION 3 # ------------------------- - -BEGIN; - -CREATE UNIQUE INDEX PrincipalID ON UserAccounts(PrincipalID); -CREATE INDEX Email ON UserAccounts(Email); -CREATE INDEX FirstName ON UserAccounts(FirstName); -CREATE INDEX LastName ON UserAccounts(LastName); -CREATE INDEX Name ON UserAccounts(FirstName,LastName); - -COMMIT; - -:VERSION 4 # ------------------------- - -BEGIN; - -ALTER TABLE UserAccounts ADD COLUMN UserLevel integer NOT NULL DEFAULT 0; -ALTER TABLE UserAccounts ADD COLUMN UserFlags integer NOT NULL DEFAULT 0; -ALTER TABLE UserAccounts ADD COLUMN UserTitle varchar(64) NOT NULL DEFAULT ''; - -COMMIT; - - diff --git a/OpenSim/Data/MySQL/Resources/UserProfiles.migrations b/OpenSim/Data/MySQL/Resources/UserProfiles.migrations index 0759b26..cfcc18b 100644 --- a/OpenSim/Data/MySQL/Resources/UserProfiles.migrations +++ b/OpenSim/Data/MySQL/Resources/UserProfiles.migrations @@ -1,4 +1,4 @@ -:VERSION 1 # ------------------------------- +:VERSION 5 # ------------------------------- begin; @@ -19,7 +19,7 @@ CREATE TABLE IF NOT EXISTS `classifieds` ( `classifiedflags` int(8) NOT NULL, `priceforlisting` int(5) NOT NULL, PRIMARY KEY (`classifieduuid`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; +) ENGINE=InnoDB DEFAULT CHARSET=latin1; CREATE TABLE IF NOT EXISTS `usernotes` ( @@ -27,7 +27,7 @@ CREATE TABLE IF NOT EXISTS `usernotes` ( `targetuuid` varchar(36) NOT NULL, `notes` text NOT NULL, UNIQUE KEY `useruuid` (`useruuid`,`targetuuid`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; +) ENGINE=InnoDB DEFAULT CHARSET=latin1; CREATE TABLE IF NOT EXISTS `userpicks` ( @@ -44,8 +44,9 @@ CREATE TABLE IF NOT EXISTS `userpicks` ( `posglobal` varchar(255) NOT NULL, `sortorder` int(2) NOT NULL, `enabled` enum('true','false') NOT NULL, + `gatekeeper` varchar(255), PRIMARY KEY (`pickuuid`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; +) ENGINE=InnoDB DEFAULT CHARSET=latin1; CREATE TABLE IF NOT EXISTS `userprofile` ( @@ -64,35 +65,22 @@ CREATE TABLE IF NOT EXISTS `userprofile` ( `profileFirstImage` varchar(36) NOT NULL, `profileFirstText` text NOT NULL, PRIMARY KEY (`useruuid`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; +) ENGINE=InnoDB DEFAULT CHARSET=latin1; -commit; - -:VERSION 2 # ------------------------------- - -begin; CREATE TABLE IF NOT EXISTS `userdata` ( `UserId` char(36) NOT NULL, `TagId` varchar(64) NOT NULL, `DataKey` varchar(255), `DataVal` varchar(255), PRIMARY KEY (`UserId`,`TagId`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - -commit; +) ENGINE=InnoDB DEFAULT CHARSET=latin1; -:VERSION 3 # ------------------------------- -begin; CREATE TABLE IF NOT EXISTS `usersettings` ( `useruuid` varchar(36) NOT NULL, `imviaemail` enum('true','false') NOT NULL, `visible` enum('true','false') NOT NULL, `email` varchar(254) NOT NULL, PRIMARY KEY (`useruuid`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -commit; +) ENGINE=InnoDB DEFAULT CHARSET=latin1; -:VERSION 4 # ------------------------------- -begin; -ALTER TABLE userpicks ADD COLUMN gatekeeper varchar(255); commit; diff --git a/OpenSim/Data/MySQL/Resources/UserStore.migrations b/OpenSim/Data/MySQL/Resources/UserStore.migrations deleted file mode 100644 index 9129075..0000000 --- a/OpenSim/Data/MySQL/Resources/UserStore.migrations +++ /dev/null @@ -1,168 +0,0 @@ -:VERSION 1 # ----------------------------- - -BEGIN; - -SET FOREIGN_KEY_CHECKS=0; --- ---------------------------- --- Table structure for agents --- ---------------------------- -CREATE TABLE `agents` ( - `UUID` varchar(36) NOT NULL, - `sessionID` varchar(36) NOT NULL, - `secureSessionID` varchar(36) NOT NULL, - `agentIP` varchar(16) NOT NULL, - `agentPort` int(11) NOT NULL, - `agentOnline` tinyint(4) NOT NULL, - `loginTime` int(11) NOT NULL, - `logoutTime` int(11) NOT NULL, - `currentRegion` varchar(36) NOT NULL, - `currentHandle` bigint(20) unsigned NOT NULL, - `currentPos` varchar(64) NOT NULL, - PRIMARY KEY (`UUID`), - UNIQUE KEY `session` (`sessionID`), - UNIQUE KEY `ssession` (`secureSessionID`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- Create schema avatar_appearance --- - -CREATE TABLE `avatarappearance` ( - Owner char(36) NOT NULL, - Serial int(10) unsigned NOT NULL, - Visual_Params blob NOT NULL, - Texture blob NOT NULL, - Avatar_Height float NOT NULL, - Body_Item char(36) NOT NULL, - Body_Asset char(36) NOT NULL, - Skin_Item char(36) NOT NULL, - Skin_Asset char(36) NOT NULL, - Hair_Item char(36) NOT NULL, - Hair_Asset char(36) NOT NULL, - Eyes_Item char(36) NOT NULL, - Eyes_Asset char(36) NOT NULL, - Shirt_Item char(36) NOT NULL, - Shirt_Asset char(36) NOT NULL, - Pants_Item char(36) NOT NULL, - Pants_Asset char(36) NOT NULL, - Shoes_Item char(36) NOT NULL, - Shoes_Asset char(36) NOT NULL, - Socks_Item char(36) NOT NULL, - Socks_Asset char(36) NOT NULL, - Jacket_Item char(36) NOT NULL, - Jacket_Asset char(36) NOT NULL, - Gloves_Item char(36) NOT NULL, - Gloves_Asset char(36) NOT NULL, - Undershirt_Item char(36) NOT NULL, - Undershirt_Asset char(36) NOT NULL, - Underpants_Item char(36) NOT NULL, - Underpants_Asset char(36) NOT NULL, - Skirt_Item char(36) NOT NULL, - Skirt_Asset char(36) NOT NULL, - PRIMARY KEY (`Owner`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -SET FOREIGN_KEY_CHECKS=0; --- ---------------------------- --- Table structure for users --- ---------------------------- -CREATE TABLE `userfriends` ( - `ownerID` VARCHAR(37) NOT NULL, - `friendID` VARCHAR(37) NOT NULL, - `friendPerms` INT NOT NULL, - `datetimestamp` INT NOT NULL, - UNIQUE KEY (`ownerID`, `friendID`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; --- ---------------------------- --- Table structure for users --- ---------------------------- -CREATE TABLE `users` ( - `UUID` varchar(36) NOT NULL default '', - `username` varchar(32) NOT NULL, - `lastname` varchar(32) NOT NULL, - `passwordHash` varchar(32) NOT NULL, - `passwordSalt` varchar(32) NOT NULL, - `homeRegion` bigint(20) unsigned default NULL, - `homeLocationX` float default NULL, - `homeLocationY` float default NULL, - `homeLocationZ` float default NULL, - `homeLookAtX` float default NULL, - `homeLookAtY` float default NULL, - `homeLookAtZ` float default NULL, - `created` int(11) NOT NULL, - `lastLogin` int(11) NOT NULL, - `userInventoryURI` varchar(255) default NULL, - `userAssetURI` varchar(255) default NULL, - `profileCanDoMask` int(10) unsigned default NULL, - `profileWantDoMask` int(10) unsigned default NULL, - `profileAboutText` text, - `profileFirstText` text, - `profileImage` varchar(36) default NULL, - `profileFirstImage` varchar(36) default NULL, - `webLoginKey` varchar(36) default NULL, - PRIMARY KEY (`UUID`), - UNIQUE KEY `usernames` (`username`,`lastname`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- ---------------------------- --- Records --- ---------------------------- -COMMIT; - -:VERSION 2 # ----------------------------- - -BEGIN; - -ALTER TABLE users add homeRegionID char(36) NOT NULL default '00000000-0000-0000-0000-000000000000'; - -COMMIT; - -:VERSION 3 # ----------------------------- - -BEGIN; - -ALTER TABLE users add userFlags integer NOT NULL default 0; -ALTER TABLE users add godLevel integer NOT NULL default 0; - -COMMIT; - -:VERSION 4 # ----------------------------- - -BEGIN; - -ALTER TABLE users add customType varchar(32) not null default ''; -ALTER TABLE users add partner char(36) not null default '00000000-0000-0000-0000-000000000000'; - -COMMIT; - -:VERSION 5 # ----------------------------- - -BEGIN; - -CREATE TABLE `avatarattachments` (`UUID` char(36) NOT NULL, `attachpoint` int(11) NOT NULL, `item` char(36) NOT NULL, `asset` char(36) NOT NULL) ENGINE=MyISAM; - -COMMIT; - -:VERSION 6 # ----------------------------- - -BEGIN; - -ALTER TABLE agents add currentLookAt varchar(36) not null default ''; - -COMMIT; - -:VERSION 7 # ----------------------------- - -BEGIN; - -ALTER TABLE users add email varchar(250); - -COMMIT; - -:VERSION 8 # ----------------------------- - -BEGIN; - -ALTER TABLE users add scopeID char(36) not null default '00000000-0000-0000-0000-000000000000'; - -COMMIT; - diff --git a/OpenSim/Data/MySQL/Resources/XAssetStore.migrations b/OpenSim/Data/MySQL/Resources/XAssetStore.migrations index 78d6e51..9459e3e 100644 --- a/OpenSim/Data/MySQL/Resources/XAssetStore.migrations +++ b/OpenSim/Data/MySQL/Resources/XAssetStore.migrations @@ -16,13 +16,13 @@ CREATE TABLE `XAssetsMeta` ( `AssetFlags` int(11) NOT NULL, `CreatorID` varchar(128) NOT NULL, PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Version 1'; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Version 1'; CREATE TABLE `XAssetsData` ( `Hash` binary(32) NOT NULL, `Data` longblob NOT NULL, PRIMARY KEY (`hash`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Version 1'; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Version 1'; COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/XMute.migrations b/OpenSim/Data/MySQL/Resources/XMute.migrations new file mode 100644 index 0000000..4ac7f82 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/XMute.migrations @@ -0,0 +1,16 @@ +:VERSION 1 + +BEGIN; + +CREATE TABLE `XMute` ( + `AgentID` char(36) NOT NULL, + `MuteID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `MuteName` varchar(64) NOT NULL DEFAULT '', + `MuteType` int(11) NOT NULL DEFAULT '1', + `MuteFlags` int(11) NOT NULL DEFAULT '0', + `Stamp` int(11) NOT NULL, + UNIQUE KEY `AgentID_2` (`AgentID`,`MuteID`,`MuteName`), + KEY `AgentID` (`AgentID`) +); + +COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/os_groups_Store.migrations b/OpenSim/Data/MySQL/Resources/os_groups_Store.migrations index 9e6f1c1..6ec8914 100644 --- a/OpenSim/Data/MySQL/Resources/os_groups_Store.migrations +++ b/OpenSim/Data/MySQL/Resources/os_groups_Store.migrations @@ -31,7 +31,7 @@ CREATE TABLE `os_groups_membership` ( `AccessToken` char(36) NOT NULL default '', PRIMARY KEY (`GroupID`,`PrincipalID`), KEY `PrincipalID` (`PrincipalID`) -) ENGINE=MyISAM; +) ENGINE=InnoDB; CREATE TABLE `os_groups_roles` ( @@ -43,7 +43,7 @@ CREATE TABLE `os_groups_roles` ( `Powers` bigint(20) unsigned NOT NULL default '0', PRIMARY KEY (`GroupID`,`RoleID`), KEY `GroupID` (`GroupID`) -) ENGINE=MyISAM; +) ENGINE=InnoDB; CREATE TABLE `os_groups_rolemembership` ( @@ -52,7 +52,7 @@ CREATE TABLE `os_groups_rolemembership` ( `PrincipalID` VARCHAR(255) NOT NULL default '', PRIMARY KEY (`GroupID`,`RoleID`,`PrincipalID`), KEY `PrincipalID` (`PrincipalID`) -) ENGINE=MyISAM; +) ENGINE=InnoDB; CREATE TABLE `os_groups_invites` ( @@ -63,7 +63,7 @@ CREATE TABLE `os_groups_invites` ( `TMStamp` timestamp NOT NULL, PRIMARY KEY (`InviteID`), UNIQUE KEY `PrincipalGroup` (`GroupID`,`PrincipalID`) -) ENGINE=MyISAM; +) ENGINE=InnoDB; CREATE TABLE `os_groups_notices` ( @@ -81,13 +81,13 @@ CREATE TABLE `os_groups_notices` ( PRIMARY KEY (`NoticeID`), KEY `GroupID` (`GroupID`), KEY `TMStamp` (`TMStamp`) -) ENGINE=MyISAM; +) ENGINE=InnoDB; CREATE TABLE `os_groups_principals` ( `PrincipalID` VARCHAR(255) NOT NULL default '', `ActiveGroupID` char(36) NOT NULL default '', PRIMARY KEY (`PrincipalID`) -) ENGINE=MyISAM; +) ENGINE=InnoDB; COMMIT; @@ -112,4 +112,4 @@ DROP TABLE `diva_groups_principals`; DELETE FROM `migrations` WHERE name='diva_im_Store'; -COMMIT; \ No newline at end of file +COMMIT; diff --git a/OpenSim/Data/Null/NullEstateData.cs b/OpenSim/Data/Null/NullEstateData.cs old mode 100644 new mode 100755 index 57592f1..9f22896 --- a/OpenSim/Data/Null/NullEstateData.cs +++ b/OpenSim/Data/Null/NullEstateData.cs @@ -102,19 +102,19 @@ namespace OpenSim.Data.Null { return new EstateSettings(); } - + public List LoadEstateSettingsAll() { List allEstateSettings = new List(); allEstateSettings.Add(GetEstate()); return allEstateSettings; } - + public List GetEstatesAll() { List result = new List(); result.Add((int)GetEstate().EstateID); - return result; + return result; } public List GetEstates(string search) diff --git a/OpenSim/Data/Null/NullFriendsData.cs b/OpenSim/Data/Null/NullFriendsData.cs index 473999f..dc9cd38 100644 --- a/OpenSim/Data/Null/NullFriendsData.cs +++ b/OpenSim/Data/Null/NullFriendsData.cs @@ -79,7 +79,7 @@ namespace OpenSim.Data.Null { return fdata.PrincipalID == userID.ToString(); }); - + if (lst != null) { lst.ForEach(f => @@ -87,14 +87,14 @@ namespace OpenSim.Data.Null FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID); if (f2 != null) f.Data["TheirFlags"] = f2.Data["Flags"]; - + // m_log.DebugFormat( // "[NULL FRIENDS DATA]: Got {0} {1} {2} for {3}", // f.Friend, f.Data["Flags"], f2 != null ? f.Data["TheirFlags"] : "not found!", f.PrincipalID); }); - + // m_log.DebugFormat("[NULL FRIENDS DATA]: Got {0} friends for {1}", lst.Count, userID); - + return lst.ToArray(); } } @@ -134,7 +134,7 @@ namespace OpenSim.Data.Null // m_log.DebugFormat( // "[NULL FRIENDS DATA]: Deleting friend {0} {1} for {2}", // friend.Friend, friend.Data["Flags"], friend.PrincipalID); - + m_Data.Remove(friend); return true; } diff --git a/OpenSim/Data/Null/NullPresenceData.cs b/OpenSim/Data/Null/NullPresenceData.cs index aff0b0b..8c442c9 100644 --- a/OpenSim/Data/Null/NullPresenceData.cs +++ b/OpenSim/Data/Null/NullPresenceData.cs @@ -39,7 +39,7 @@ namespace OpenSim.Data.Null public class NullPresenceData : IPresenceData { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + public static NullPresenceData Instance; Dictionary m_presenceData = new Dictionary(); @@ -100,7 +100,7 @@ namespace OpenSim.Data.Null { if (Instance != this) return Instance.ReportAgent(sessionID, regionID); - + if (m_presenceData.ContainsKey(sessionID)) { m_presenceData[sessionID].RegionID = regionID; @@ -129,7 +129,7 @@ namespace OpenSim.Data.Null // Console.WriteLine("HOME for " + p.UserID + " is " + (p.Data.ContainsKey("HomeRegionID") ? p.Data["HomeRegionID"] : "Not found")); } } - + return presences.ToArray(); } else if (field == "SessionID") @@ -172,7 +172,7 @@ namespace OpenSim.Data.Null { // m_log.DebugFormat( // "[NULL PRESENCE DATA]: Deleting presence data for field {0} with parameter {1}", field, data); - + if (Instance != this) return Instance.Delete(field, data); diff --git a/OpenSim/Data/Null/NullRegionData.cs b/OpenSim/Data/Null/NullRegionData.cs index d28cd99..595db2f 100644 --- a/OpenSim/Data/Null/NullRegionData.cs +++ b/OpenSim/Data/Null/NullRegionData.cs @@ -134,21 +134,22 @@ namespace OpenSim.Data.Null if (m_useStaticInstance && Instance != this) return Instance.Get(posX, posY, scopeID); - List ret = new List(); + RegionData ret = null; lock (m_regionData) { foreach (RegionData r in m_regionData.Values) { - if (r.posX == posX && r.posY == posY) - ret.Add(r); + if (posX >= r.posX && posX < r.posX + r.sizeX + && posY >= r.posY && posY < r.posY + r.sizeY) + { + ret = r; + break; + } } } - if (ret.Count > 0) - return ret[0]; - - return null; + return ret; } public RegionData Get(UUID regionID, UUID scopeID) @@ -176,8 +177,9 @@ namespace OpenSim.Data.Null { foreach (RegionData r in m_regionData.Values) { - if (r.posX >= startX && r.posX <= endX && r.posY >= startY && r.posY <= endY) - ret.Add(r); + if (r.posX + r.sizeX > startX && r.posX <= endX + && r.posY + r.sizeX > startY && r.posY <= endY) + ret.Add(r); } } diff --git a/OpenSim/Data/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs index deeaced..7bb6da3 100644 --- a/OpenSim/Data/Null/NullSimulationData.cs +++ b/OpenSim/Data/Null/NullSimulationData.cs @@ -133,6 +133,7 @@ namespace OpenSim.Data.Null } Dictionary m_terrains = new Dictionary(); + Dictionary m_bakedterrains = new Dictionary(); public void StoreTerrain(TerrainData ter, UUID regionID) { if (m_terrains.ContainsKey(regionID)) @@ -140,6 +141,13 @@ namespace OpenSim.Data.Null m_terrains.Add(regionID, ter); } + public void StoreBakedTerrain(TerrainData ter, UUID regionID) + { + if (m_bakedterrains.ContainsKey(regionID)) + m_bakedterrains.Remove(regionID); + m_bakedterrains.Add(regionID, ter); + } + // Legacy. Just don't do this. public void StoreTerrain(double[,] ter, UUID regionID) { @@ -167,6 +175,15 @@ namespace OpenSim.Data.Null return null; } + public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) + { + if (m_bakedterrains.ContainsKey(regionID)) + { + return m_bakedterrains[regionID]; + } + return null; + } + public void RemoveLandObject(UUID globalID) { } @@ -184,6 +201,11 @@ namespace OpenSim.Data.Null { } + public UUID[] GetObjectIDs(UUID regionID) + { + return new UUID[0]; + } + public void SaveExtra(UUID regionID, string name, string value) { } diff --git a/OpenSim/Data/Null/NullUserAccountData.cs b/OpenSim/Data/Null/NullUserAccountData.cs index ec54dba..6d2e05a 100644 --- a/OpenSim/Data/Null/NullUserAccountData.cs +++ b/OpenSim/Data/Null/NullUserAccountData.cs @@ -40,7 +40,7 @@ namespace OpenSim.Data.Null public class NullUserAccountData : IUserAccountData { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + private Dictionary m_DataByUUID = new Dictionary(); private Dictionary m_DataByName = new Dictionary(); private Dictionary m_DataByEmail = new Dictionary(); @@ -48,7 +48,7 @@ namespace OpenSim.Data.Null public NullUserAccountData(string connectionString, string realm) { // m_log.DebugFormat( -// "[NULL USER ACCOUNT DATA]: Initializing new NullUserAccountData with connectionString [{0}], realm [{1}]", +// "[NULL USER ACCOUNT DATA]: Initializing new NullUserAccountData with connectionString [{0}], realm [{1}]", // connectionString, realm); } @@ -65,12 +65,12 @@ namespace OpenSim.Data.Null // if (m_log.IsDebugEnabled) // { // m_log.DebugFormat( -// "[NULL USER ACCOUNT DATA]: Called Get with fields [{0}], values [{1}]", +// "[NULL USER ACCOUNT DATA]: Called Get with fields [{0}], values [{1}]", // string.Join(", ", fields), string.Join(", ", values)); // } - + UserAccountData[] userAccounts = new UserAccountData[0]; - + List fieldsLst = new List(fields); if (fieldsLst.Contains("PrincipalID")) { @@ -79,33 +79,33 @@ namespace OpenSim.Data.Null if (UUID.TryParse(values[i], out id)) if (m_DataByUUID.ContainsKey(id)) userAccounts = new UserAccountData[] { m_DataByUUID[id] }; - } + } else if (fieldsLst.Contains("FirstName") && fieldsLst.Contains("LastName")) { int findex = fieldsLst.IndexOf("FirstName"); int lindex = fieldsLst.IndexOf("LastName"); if (m_DataByName.ContainsKey(values[findex] + " " + values[lindex])) - { + { userAccounts = new UserAccountData[] { m_DataByName[values[findex] + " " + values[lindex]] }; } - } + } else if (fieldsLst.Contains("Email")) { int i = fieldsLst.IndexOf("Email"); if (m_DataByEmail.ContainsKey(values[i])) userAccounts = new UserAccountData[] { m_DataByEmail[values[i]] }; } - + // if (m_log.IsDebugEnabled) // { // StringBuilder sb = new StringBuilder(); // foreach (UserAccountData uad in userAccounts) // sb.AppendFormat("({0} {1} {2}) ", uad.FirstName, uad.LastName, uad.PrincipalID); -// +// // m_log.DebugFormat( // "[NULL USER ACCOUNT DATA]: Returning {0} user accounts out of {1}: [{2}]", userAccounts.Length, m_DataByName.Count, sb); // } - + return userAccounts; } @@ -113,16 +113,16 @@ namespace OpenSim.Data.Null { if (data == null) return false; - + m_log.DebugFormat( - "[NULL USER ACCOUNT DATA]: Storing user account {0} {1} {2} {3}", + "[NULL USER ACCOUNT DATA]: Storing user account {0} {1} {2} {3}", data.FirstName, data.LastName, data.PrincipalID, this.GetHashCode()); - + m_DataByUUID[data.PrincipalID] = data; m_DataByName[data.FirstName + " " + data.LastName] = data; if (data.Data.ContainsKey("Email") && data.Data["Email"] != null && data.Data["Email"] != string.Empty) m_DataByEmail[data.Data["Email"]] = data; - + // m_log.DebugFormat("m_DataByUUID count is {0}, m_DataByName count is {1}", m_DataByUUID.Count, m_DataByName.Count); return true; @@ -132,7 +132,7 @@ namespace OpenSim.Data.Null { // m_log.DebugFormat( // "[NULL USER ACCOUNT DATA]: Called GetUsers with scope [{0}], query [{1}]", scopeID, query); - + string[] words = query.Split(new char[] { ' ' }); for (int i = 0; i < words.Length; i++) @@ -193,5 +193,10 @@ namespace OpenSim.Data.Null return false; } + + public UserAccountData[] GetUsersWhere(UUID scopeID, string where) + { + return null; + } } } diff --git a/OpenSim/Data/Null/Properties/AssemblyInfo.cs b/OpenSim/Data/Null/Properties/AssemblyInfo.cs index a827bd0..508f1c7 100644 --- a/OpenSim/Data/Null/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/Null/Properties/AssemblyInfo.cs @@ -61,5 +61,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly : AssemblyVersion("0.8.2.*")] +[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] diff --git a/OpenSim/Data/PGSQL/PGSQLAgentPreferencesData.cs b/OpenSim/Data/PGSQL/PGSQLAgentPreferencesData.cs index 20612fe..4794c71 100644 --- a/OpenSim/Data/PGSQL/PGSQLAgentPreferencesData.cs +++ b/OpenSim/Data/PGSQL/PGSQLAgentPreferencesData.cs @@ -44,20 +44,12 @@ namespace OpenSim.Data.PGSQL public AgentPreferencesData GetPrefs(UUID agentID) { - // Until someone sends in a table that works - return null; - //AgentPreferencesData[] ret = Get("PrincipalID", agentID.ToString()); - //if (ret.Length == 0) - // return null; + AgentPreferencesData[] ret = Get("PrincipalID", agentID.ToString()); - //return ret[0]; - } - - public override bool Store(AgentPreferencesData row) - { - // Until someone sends in a table that works - return false; + if (ret.Length == 0) + return null; + return ret[0]; } } diff --git a/OpenSim/Data/PGSQL/PGSQLAssetData.cs b/OpenSim/Data/PGSQL/PGSQLAssetData.cs index 5d8b0a2..7b79521 100644 --- a/OpenSim/Data/PGSQL/PGSQLAssetData.cs +++ b/OpenSim/Data/PGSQL/PGSQLAssetData.cs @@ -149,37 +149,37 @@ namespace OpenSim.Data.PGSQL /// Create asset in m_database /// /// the asset - override public void StoreAsset(AssetBase asset) + override public bool StoreAsset(AssetBase asset) { - + string sql = @"UPDATE assets set name = :name, description = :description, " + "\"assetType\" " + @" = :assetType, local = :local, temporary = :temporary, creatorid = :creatorid, data = :data WHERE id=:id; INSERT INTO assets - (id, name, description, " + "\"assetType\" " + @", local, + (id, name, description, " + "\"assetType\" " + @", local, temporary, create_time, access_time, creatorid, asset_flags, data) - Select :id, :name, :description, :assetType, :local, + Select :id, :name, :description, :assetType, :local, :temporary, :create_time, :access_time, :creatorid, :asset_flags, :data - Where not EXISTS(SELECT * FROM assets WHERE id=:id) + Where not EXISTS(SELECT * FROM assets WHERE id=:id) "; - + string assetName = asset.Name; if (asset.Name.Length > AssetBase.MAX_ASSET_NAME) { assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME); m_log.WarnFormat( - "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", + "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", asset.Name, asset.ID, asset.Name.Length, assetName.Length); } - + string assetDescription = asset.Description; if (asset.Description.Length > AssetBase.MAX_ASSET_DESC) { assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC); m_log.WarnFormat( - "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", + "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); } @@ -208,6 +208,7 @@ namespace OpenSim.Data.PGSQL m_log.Error("[ASSET DB]: Error storing item :" + e.Message + " sql "+sql); } } + return true; } @@ -277,7 +278,7 @@ namespace OpenSim.Data.PGSQL { List retList = new List(count); string sql = @" SELECT id, name, description, " + "\"assetType\"" + @", temporary, creatorid - FROM assets + FROM assets order by id limit :stop offset :start;"; diff --git a/OpenSim/Data/PGSQL/PGSQLAuthenticationData.cs b/OpenSim/Data/PGSQL/PGSQLAuthenticationData.cs index d174112..8f83309 100644 --- a/OpenSim/Data/PGSQL/PGSQLAuthenticationData.cs +++ b/OpenSim/Data/PGSQL/PGSQLAuthenticationData.cs @@ -145,7 +145,7 @@ namespace OpenSim.Data.PGSQL updateBuilder.AppendFormat("\"{0}\" = :{0}",field); first = false; - + cmd.Parameters.Add(m_database.CreateParameter("" + field, data.Data[field])); } @@ -154,7 +154,7 @@ namespace OpenSim.Data.PGSQL cmd.CommandText = updateBuilder.ToString(); cmd.Connection = conn; cmd.Parameters.Add(m_database.CreateParameter("principalID", data.PrincipalID)); - + conn.Open(); if (cmd.ExecuteNonQuery() < 1) { @@ -195,7 +195,7 @@ namespace OpenSim.Data.PGSQL { if (System.Environment.TickCount - m_LastExpire > 30000) DoExpire(); - + string sql = "insert into tokens (uuid, token, validity) values (:principalID, :token, :lifetime)"; using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString)) using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) diff --git a/OpenSim/Data/PGSQL/PGSQLAvatarData.cs b/OpenSim/Data/PGSQL/PGSQLAvatarData.cs index d9c4905..3d56d4d 100644 --- a/OpenSim/Data/PGSQL/PGSQLAvatarData.cs +++ b/OpenSim/Data/PGSQL/PGSQLAvatarData.cs @@ -45,7 +45,7 @@ namespace OpenSim.Data.PGSQL IAvatarData { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + public PGSQLAvatarData(string connectionString, string realm) : base(connectionString, realm, "Avatar") { diff --git a/OpenSim/Data/PGSQL/PGSQLEstateData.cs b/OpenSim/Data/PGSQL/PGSQLEstateData.cs index b5ca235..9489d6c 100644 --- a/OpenSim/Data/PGSQL/PGSQLEstateData.cs +++ b/OpenSim/Data/PGSQL/PGSQLEstateData.cs @@ -594,7 +594,7 @@ namespace OpenSim.Data.PGSQL public bool DeleteEstate(int estateID) { - // TODO: Implementation! + // TODO: Implementation! return false; } #endregion diff --git a/OpenSim/Data/PGSQL/PGSQLFSAssetData.cs b/OpenSim/Data/PGSQL/PGSQLFSAssetData.cs new file mode 100644 index 0000000..59b857c --- /dev/null +++ b/OpenSim/Data/PGSQL/PGSQLFSAssetData.cs @@ -0,0 +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 OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using System.Collections.Generic; +using System.Data; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using log4net; +using OpenMetaverse; +using Npgsql; +using NpgsqlTypes; + +namespace OpenSim.Data.PGSQL +{ + public class PGSQLFSAssetData : IFSAssetDataPlugin + { + private const string _migrationStore = "FSAssetStore"; + private static string m_Table = "fsassets"; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private long m_ticksToEpoch; + + private PGSQLManager m_database; + private string m_connectionString; + + public PGSQLFSAssetData() + { + } + + public void Initialise(string connect, string realm, int UpdateAccessTime) + { + DaysBetweenAccessTimeUpdates = UpdateAccessTime; + + m_ticksToEpoch = new System.DateTime(1970, 1, 1).Ticks; + + m_connectionString = connect; + m_database = new PGSQLManager(m_connectionString); + + //New migration to check for DB changes + m_database.CheckMigration(_migrationStore); + } + + public void Initialise() + { + throw new NotImplementedException(); + } + + /// + /// Number of days that must pass before we update the access time on an asset when it has been fetched + /// Config option to change this is "DaysBetweenAccessTimeUpdates" + /// + private int DaysBetweenAccessTimeUpdates = 0; + + protected virtual Assembly Assembly + { + get { return GetType().Assembly; } + } + + #region IPlugin Members + + public string Version { get { return "1.0.0.0"; } } + + public void Dispose() { } + + public string Name + { + get { return "PGSQL FSAsset storage engine"; } + } + + #endregion + + #region IFSAssetDataPlugin Members + + public AssetMetadata Get(string id, out string hash) + { + hash = String.Empty; + AssetMetadata meta = null; + UUID uuid = new UUID(id); + + string query = String.Format("select \"id\", \"type\", \"hash\", \"create_time\", \"access_time\", \"asset_flags\" from {0} where \"id\" = :id", m_Table); + using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) + { + dbcon.Open(); + cmd.Parameters.Add(m_database.CreateParameter("id", uuid)); + using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default)) + { + if (reader.Read()) + { + meta = new AssetMetadata(); + hash = reader["hash"].ToString(); + meta.ID = id; + meta.FullID = uuid; + meta.Name = String.Empty; + meta.Description = String.Empty; + meta.Type = (sbyte)Convert.ToInt32(reader["type"]); + meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type); + meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"])); + meta.Flags = (AssetFlags)Convert.ToInt32(reader["asset_flags"]); + int atime = Convert.ToInt32(reader["access_time"]); + UpdateAccessTime(atime, uuid); + } + } + } + + return meta; + } + + private void UpdateAccessTime(int AccessTime, UUID id) + { + // Reduce DB work by only updating access time if asset hasn't recently been accessed + // 0 By Default, Config option is "DaysBetweenAccessTimeUpdates" + if (DaysBetweenAccessTimeUpdates > 0 && (DateTime.UtcNow - Utils.UnixTimeToDateTime(AccessTime)).TotalDays < DaysBetweenAccessTimeUpdates) + return; + + string query = String.Format("UPDATE {0} SET \"access_time\" = :access_time WHERE \"id\" = :id", m_Table); + using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) + { + dbcon.Open(); + int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000); + cmd.Parameters.Add(m_database.CreateParameter("id", id)); + cmd.Parameters.Add(m_database.CreateParameter("access_time", now)); + cmd.ExecuteNonQuery(); + } + } + + public bool Store(AssetMetadata meta, string hash) + { + try + { + bool found = false; + string oldhash; + AssetMetadata existingAsset = Get(meta.ID, out oldhash); + + string query = String.Format("UPDATE {0} SET \"access_time\" = :access_time WHERE \"id\" = :id", m_Table); + if (existingAsset == null) + { + query = String.Format("insert into {0} (\"id\", \"type\", \"hash\", \"asset_flags\", \"create_time\", \"access_time\") values ( :id, :type, :hash, :asset_flags, :create_time, :access_time)", m_Table); + found = true; + } + + using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) + { + dbcon.Open(); + int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000); + cmd.Parameters.Add(m_database.CreateParameter("id", meta.FullID)); + cmd.Parameters.Add(m_database.CreateParameter("type", meta.Type)); + cmd.Parameters.Add(m_database.CreateParameter("hash", hash)); + cmd.Parameters.Add(m_database.CreateParameter("asset_flags", Convert.ToInt32(meta.Flags))); + cmd.Parameters.Add(m_database.CreateParameter("create_time", now)); + cmd.Parameters.Add(m_database.CreateParameter("access_time", now)); + cmd.ExecuteNonQuery(); + } + return found; + } + catch(Exception e) + { + m_log.Error("[PGSQL FSASSETS] Failed to store asset with ID " + meta.ID); + m_log.Error(e.ToString()); + return false; + } + } + + /// + /// Check if the assets exist in the database. + /// + /// The asset UUID's + /// For each asset: true if it exists, false otherwise + public bool[] AssetsExist(UUID[] uuids) + { + if (uuids.Length == 0) + return new bool[0]; + + HashSet exists = new HashSet(); + + string ids = "'" + string.Join("','", uuids) + "'"; + string query = string.Format("select \"id\" from {1} where id in ({0})", ids, m_Table); + using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) + { + dbcon.Open(); + using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default)) + { + while (reader.Read()) + { + UUID id = DBGuid.FromDB(reader["id"]);; + exists.Add(id); + } + } + } + + bool[] results = new bool[uuids.Length]; + for (int i = 0; i < uuids.Length; i++) + results[i] = exists.Contains(uuids[i]); + return results; + } + + public int Count() + { + int count = 0; + string query = String.Format("select count(*) as count from {0}", m_Table); + using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) + { + dbcon.Open(); + IDataReader reader = cmd.ExecuteReader(); + reader.Read(); + count = Convert.ToInt32(reader["count"]); + reader.Close(); + } + + return count; + } + + public bool Delete(string id) + { + string query = String.Format("delete from {0} where \"id\" = :id", m_Table); + using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) + { + dbcon.Open(); + cmd.Parameters.Add(m_database.CreateParameter("id", new UUID(id))); + cmd.ExecuteNonQuery(); + } + + return true; + } + + public void Import(string conn, string table, int start, int count, bool force, FSStoreDelegate store) + { + int imported = 0; + string limit = String.Empty; + if(count != -1) + { + limit = String.Format(" limit {0} offset {1}", start, count); + } + string query = String.Format("select * from {0}{1}", table, limit); + try + { + using (NpgsqlConnection remote = new NpgsqlConnection(conn)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, remote)) + { + remote.Open(); + MainConsole.Instance.Output("Querying database"); + MainConsole.Instance.Output("Reading data"); + using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default)) + { + while (reader.Read()) + { + if ((imported % 100) == 0) + { + MainConsole.Instance.Output(String.Format("{0} assets imported so far", imported)); + } + + AssetBase asset = new AssetBase(); + AssetMetadata meta = new AssetMetadata(); + + meta.ID = reader["id"].ToString(); + meta.FullID = new UUID(meta.ID); + + meta.Name = String.Empty; + meta.Description = String.Empty; + meta.Type = (sbyte)Convert.ToInt32(reader["assetType"]); + meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type); + meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"])); + + asset.Metadata = meta; + asset.Data = (byte[])reader["data"]; + + store(asset, force); + + imported++; + } + } + } + } + catch (Exception e) + { + m_log.ErrorFormat("[PGSQL FSASSETS]: Error importing assets: {0}", + e.Message.ToString()); + return; + } + + MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported)); + } + + #endregion + } +} diff --git a/OpenSim/Data/PGSQL/PGSQLFriendsData.cs b/OpenSim/Data/PGSQL/PGSQLFriendsData.cs index a841353..58dffed 100644 --- a/OpenSim/Data/PGSQL/PGSQLFriendsData.cs +++ b/OpenSim/Data/PGSQL/PGSQLFriendsData.cs @@ -50,7 +50,7 @@ namespace OpenSim.Data.PGSQL } } - + public override bool Delete(string principalID, string friend) { UUID princUUID = UUID.Zero; @@ -97,7 +97,7 @@ namespace OpenSim.Data.PGSQL using (NpgsqlCommand cmd = new NpgsqlCommand()) { - cmd.CommandText = String.Format("select a.*,case when b.\"Flags\" is null then '-1' else b.\"Flags\" end as \"TheirFlags\" from {0} as a " + + cmd.CommandText = String.Format("select a.*,case when b.\"Flags\" is null then '-1' else b.\"Flags\" end as \"TheirFlags\" from {0} as a " + " left join {0} as b on a.\"PrincipalID\" = b.\"Friend\" and a.\"Friend\" = b.\"PrincipalID\" " + " where a.\"PrincipalID\" = :PrincipalID", m_Realm); cmd.Parameters.Add(m_database.CreateParameter("PrincipalID", principalID.ToString())); @@ -111,6 +111,6 @@ namespace OpenSim.Data.PGSQL { return GetFriends(principalID); } - + } } diff --git a/OpenSim/Data/PGSQL/PGSQLGenericTableHandler.cs b/OpenSim/Data/PGSQL/PGSQLGenericTableHandler.cs index 826c6fc..5b24720 100644 --- a/OpenSim/Data/PGSQL/PGSQLGenericTableHandler.cs +++ b/OpenSim/Data/PGSQL/PGSQLGenericTableHandler.cs @@ -64,7 +64,7 @@ namespace OpenSim.Data.PGSQL : base(connectionString) { m_Realm = realm; - + m_ConnectionString = connectionString; if (storeName != String.Empty) @@ -104,7 +104,7 @@ namespace OpenSim.Data.PGSQL m_FieldTypes = new Dictionary(); string query = string.Format(@"select column_name,data_type - from INFORMATION_SCHEMA.COLUMNS + from INFORMATION_SCHEMA.COLUMNS where table_name = lower('{0}'); ", m_Realm); @@ -145,27 +145,22 @@ namespace OpenSim.Data.PGSQL private List GetConstraints() { List constraints = new List(); - string query = string.Format(@"SELECT kcu.column_name - FROM information_schema.table_constraints tc - LEFT JOIN information_schema.key_column_usage kcu - ON tc.constraint_catalog = kcu.constraint_catalog - AND tc.constraint_schema = kcu.constraint_schema - AND tc.constraint_name = kcu.constraint_name - - LEFT JOIN information_schema.referential_constraints rc - ON tc.constraint_catalog = rc.constraint_catalog - AND tc.constraint_schema = rc.constraint_schema - AND tc.constraint_name = rc.constraint_name - - LEFT JOIN information_schema.constraint_column_usage ccu - ON rc.unique_constraint_catalog = ccu.constraint_catalog - AND rc.unique_constraint_schema = ccu.constraint_schema - AND rc.unique_constraint_name = ccu.constraint_name - - where tc.table_name = lower('{0}') - and lower(tc.constraint_type) in ('primary key') - and kcu.column_name is not null - ;", m_Realm); + string query = string.Format(@"select + a.attname as column_name + from + pg_class t, + pg_class i, + pg_index ix, + pg_attribute a + where + t.oid = ix.indrelid + and i.oid = ix.indexrelid + and a.attrelid = t.oid + and a.attnum = ANY(ix.indkey) + and t.relkind = 'r' + and ix.indisunique = true + and t.relname = lower('{0}') + ;", m_Realm); using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString)) using (NpgsqlCommand cmd = new NpgsqlCommand(query, conn)) @@ -237,7 +232,7 @@ namespace OpenSim.Data.PGSQL if (reader == null) return new T[0]; - CheckColumnNames(reader); + CheckColumnNames(reader); while (reader.Read()) { @@ -344,7 +339,7 @@ namespace OpenSim.Data.PGSQL names.Add(fi.Name); values.Add(":" + fi.Name); // Temporarily return more information about what field is unexpectedly null for - // http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the + // http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the // InventoryTransferModule or we may be required to substitute a DBNull here. if (fi.GetValue(row) == null) throw new NullReferenceException( @@ -400,11 +395,11 @@ namespace OpenSim.Data.PGSQL } string where = String.Join(" AND ", terms.ToArray()); query.AppendFormat(" WHERE {0} ", where); - + } cmd.Connection = conn; cmd.CommandText = query.ToString(); - + conn.Open(); if (cmd.ExecuteNonQuery() > 0) { @@ -421,7 +416,7 @@ namespace OpenSim.Data.PGSQL query.Append("\") values (" + String.Join(",", values.ToArray()) + ")"); cmd.Connection = conn; cmd.CommandText = query.ToString(); - + // m_log.WarnFormat("[PGSQLGenericTable]: Inserting into {0} sql {1}", m_Realm, cmd.CommandText); if (conn.State != ConnectionState.Open) diff --git a/OpenSim/Data/PGSQL/PGSQLGroupsData.cs b/OpenSim/Data/PGSQL/PGSQLGroupsData.cs old mode 100644 new mode 100755 index e257e7c..f398256 --- a/OpenSim/Data/PGSQL/PGSQLGroupsData.cs +++ b/OpenSim/Data/PGSQL/PGSQLGroupsData.cs @@ -37,7 +37,7 @@ using Npgsql; namespace OpenSim.Data.PGSQL { public class PGSQLGroupsData : IGroupsData - { + { private PGSqlGroupsGroupsHandler m_Groups; private PGSqlGroupsMembershipHandler m_Membership; private PGSqlGroupsRolesHandler m_Roles; @@ -83,17 +83,17 @@ namespace OpenSim.Data.PGSQL public GroupData[] RetrieveGroups(string pattern) { - + if (string.IsNullOrEmpty(pattern)) // True for where clause { pattern = " 1 ORDER BY lower(\"Name\") LIMIT 100"; - + return m_Groups.Get(pattern); } - else - { + else + { pattern = " \"ShowInList\" = 1 AND lower(\"Name\") LIKE lower('%" + pattern + "%') ORDER BY lower(\"Name\") LIMIT 100"; - + return m_Groups.Get(pattern, new NpgsqlParameter("pattern", pattern)); } } @@ -138,10 +138,10 @@ namespace OpenSim.Data.PGSQL public bool DeleteMember(UUID groupID, string pricipalID) { - return m_Membership.Delete(new string[] { "GroupID", "PrincipalID" }, + return m_Membership.Delete(new string[] { "GroupID", "PrincipalID" }, new string[] { groupID.ToString(), pricipalID }); } - + public int MemberCount(UUID groupID) { return (int)m_Membership.GetCount("GroupID", groupID.ToString()); @@ -173,7 +173,7 @@ namespace OpenSim.Data.PGSQL public bool DeleteRole(UUID groupID, UUID roleID) { - return m_Roles.Delete(new string[] { "GroupID", "RoleID" }, + return m_Roles.Delete(new string[] { "GroupID", "RoleID" }, new string[] { groupID.ToString(), roleID.ToString() }); } @@ -365,7 +365,7 @@ namespace OpenSim.Data.PGSQL get { return GetType().Assembly; } } - public PGSqlGroupsGroupsHandler(string connectionString, string realm, string store) + public PGSqlGroupsGroupsHandler(string connectionString, string realm, string store) : base(connectionString, realm, store) { } @@ -380,7 +380,7 @@ namespace OpenSim.Data.PGSQL get { return GetType().Assembly; } } - public PGSqlGroupsMembershipHandler(string connectionString, string realm) + public PGSqlGroupsMembershipHandler(string connectionString, string realm) : base(connectionString, realm, string.Empty) { } @@ -395,7 +395,7 @@ namespace OpenSim.Data.PGSQL get { return GetType().Assembly; } } - public PGSqlGroupsRolesHandler(string connectionString, string realm) + public PGSqlGroupsRolesHandler(string connectionString, string realm) : base(connectionString, realm, string.Empty) { } @@ -410,7 +410,7 @@ namespace OpenSim.Data.PGSQL get { return GetType().Assembly; } } - public PGSqlGroupsRoleMembershipHandler(string connectionString, string realm) + public PGSqlGroupsRoleMembershipHandler(string connectionString, string realm) : base(connectionString, realm, string.Empty) { } @@ -425,7 +425,7 @@ namespace OpenSim.Data.PGSQL get { return GetType().Assembly; } } - public PGSqlGroupsInvitesHandler(string connectionString, string realm) + public PGSqlGroupsInvitesHandler(string connectionString, string realm) : base(connectionString, realm, string.Empty) { } @@ -435,8 +435,8 @@ namespace OpenSim.Data.PGSQL using (NpgsqlCommand cmd = new NpgsqlCommand()) { - cmd.CommandText = String.Format("delete from {0} where \"TMStamp\" < CURRENT_DATE - INTERVAL '2 week'", m_Realm); - + cmd.CommandText = String.Format("delete from {0} where \"TMStamp\"::abstime::timestamp < now() - INTERVAL '2 week'", m_Realm); + ExecuteNonQuery(cmd); } @@ -451,7 +451,7 @@ namespace OpenSim.Data.PGSQL get { return GetType().Assembly; } } - public PGSqlGroupsNoticesHandler(string connectionString, string realm) + public PGSqlGroupsNoticesHandler(string connectionString, string realm) : base(connectionString, realm, string.Empty) { } @@ -461,8 +461,8 @@ namespace OpenSim.Data.PGSQL using (NpgsqlCommand cmd = new NpgsqlCommand()) { - cmd.CommandText = String.Format("delete from {0} where \"TMStamp\" < CURRENT_DATE - INTERVAL '2 week'", m_Realm); - + cmd.CommandText = String.Format("delete from {0} where \"TMStamp\"::abstime::timestamp < now() - INTERVAL '2 week'", m_Realm); + ExecuteNonQuery(cmd); } @@ -477,7 +477,7 @@ namespace OpenSim.Data.PGSQL get { return GetType().Assembly; } } - public PGSqlGroupsPrincipalsHandler(string connectionString, string realm) + public PGSqlGroupsPrincipalsHandler(string connectionString, string realm) : base(connectionString, realm, string.Empty) { } diff --git a/OpenSim/Data/PGSQL/PGSQLInventoryData.cs b/OpenSim/Data/PGSQL/PGSQLInventoryData.cs index c999433..30fc5ea 100644 --- a/OpenSim/Data/PGSQL/PGSQLInventoryData.cs +++ b/OpenSim/Data/PGSQL/PGSQLInventoryData.cs @@ -69,7 +69,7 @@ namespace OpenSim.Data.PGSQL { m_connectionString = connectionString; database = new PGSQLManager(connectionString); - + //New migrations check of store database.CheckMigration(_migrationStore); } @@ -190,8 +190,8 @@ namespace OpenSim.Data.PGSQL /* NOTE: the implementation below is very inefficient (makes a separate request to get subfolders for * every found folder, recursively). Inventory code for other DBs has been already rewritten to get ALL * inventory for a specific user at once. - * - * Meanwhile, one little thing is corrected: getFolderHierarchy(UUID.Zero) doesn't make sense and should never + * + * Meanwhile, one little thing is corrected: getFolderHierarchy(UUID.Zero) doesn't make sense and should never * be used, so check for that and return an empty list. */ @@ -264,11 +264,11 @@ namespace OpenSim.Data.PGSQL /// Folder to update public void updateInventoryFolder(InventoryFolderBase folder) { - string sql = @"UPDATE inventoryfolders SET ""agentID"" = :agentID, + string sql = @"UPDATE inventoryfolders SET ""agentID"" = :agentID, ""parentFolderID"" = :parentFolderID, ""folderName"" = :folderName, type = :type, - version = :version + version = :version WHERE folderID = :folderID"; string folderName = folder.Name; @@ -337,7 +337,7 @@ namespace OpenSim.Data.PGSQL cmd.Parameters.Add(database.CreateParameter("parentID", UUID.Zero)); conn.Open(); subFolders = getFolderHierarchy(folderID, cmd); - + //Delete all sub-folders foreach (InventoryFolderBase f in subFolders) @@ -403,7 +403,7 @@ namespace OpenSim.Data.PGSQL } } } - + m_log.InfoFormat("[INVENTORY DB]: Found no inventory item with ID : {0}", itemID); return null; } @@ -420,24 +420,24 @@ namespace OpenSim.Data.PGSQL return; } - string sql = @"INSERT INTO inventoryitems - (""inventoryID"", ""assetID"", ""assetType"", ""parentFolderID"", ""avatarID"", ""inventoryName"", + string sql = @"INSERT INTO inventoryitems + (""inventoryID"", ""assetID"", ""assetType"", ""parentFolderID"", ""avatarID"", ""inventoryName"", ""inventoryDescription"", ""inventoryNextPermissions"", ""inventoryCurrentPermissions"", ""invType"", ""creatorID"", ""inventoryBasePermissions"", ""inventoryEveryOnePermissions"", ""inventoryGroupPermissions"", - ""salePrice"", ""SaleType"", ""creationDate"", ""groupID"", ""groupOwned"", flags) + ""salePrice"", ""SaleType"", ""creationDate"", ""groupID"", ""groupOwned"", flags) VALUES (:inventoryID, :assetID, :assetType, :parentFolderID, :avatarID, :inventoryName, :inventoryDescription, :inventoryNextPermissions, :inventoryCurrentPermissions, :invType, :creatorID, :inventoryBasePermissions, :inventoryEveryOnePermissions, :inventoryGroupPermissions, :SalePrice, :SaleType, :creationDate, :groupID, :groupOwned, :flags)"; - + string itemName = item.Name; if (item.Name.Length > 64) { itemName = item.Name.Substring(0, 64); m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length.ToString() + " to " + itemName.Length.ToString() + " characters"); } - + string itemDesc = item.Description; if (item.Description.Length > 128) { @@ -502,25 +502,25 @@ namespace OpenSim.Data.PGSQL /// Inventory item to update public void updateInventoryItem(InventoryItemBase item) { - string sql = @"UPDATE inventoryitems SET ""assetID"" = :assetID, + string sql = @"UPDATE inventoryitems SET ""assetID"" = :assetID, ""assetType"" = :assetType, ""parentFolderID"" = :parentFolderID, ""avatarID"" = :avatarID, - ""inventoryName"" = :inventoryName, - ""inventoryDescription"" = :inventoryDescription, - ""inventoryNextPermissions"" = :inventoryNextPermissions, - ""inventoryCurrentPermissions"" = :inventoryCurrentPermissions, - ""invType"" = :invType, - ""creatorID"" = :creatorID, - ""inventoryBasePermissions"" = :inventoryBasePermissions, - ""inventoryEveryOnePermissions"" = :inventoryEveryOnePermissions, - ""inventoryGroupPermissions"" = :inventoryGroupPermissions, - ""salePrice"" = :SalePrice, - ""saleType"" = :SaleType, - ""creationDate"" = :creationDate, - ""groupID"" = :groupID, - ""groupOwned"" = :groupOwned, - flags = :flags + ""inventoryName"" = :inventoryName, + ""inventoryDescription"" = :inventoryDescription, + ""inventoryNextPermissions"" = :inventoryNextPermissions, + ""inventoryCurrentPermissions"" = :inventoryCurrentPermissions, + ""invType"" = :invType, + ""creatorID"" = :creatorID, + ""inventoryBasePermissions"" = :inventoryBasePermissions, + ""inventoryEveryOnePermissions"" = :inventoryEveryOnePermissions, + ""inventoryGroupPermissions"" = :inventoryGroupPermissions, + ""salePrice"" = :SalePrice, + ""saleType"" = :SaleType, + ""creationDate"" = :creationDate, + ""groupID"" = :groupID, + ""groupOwned"" = :groupOwned, + flags = :flags WHERE ""inventoryID"" = :inventoryID"; string itemName = item.Name; @@ -529,7 +529,7 @@ namespace OpenSim.Data.PGSQL itemName = item.Name.Substring(0, 64); m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length.ToString() + " to " + itemName.Length.ToString() + " characters on update"); } - + string itemDesc = item.Description; if (item.Description.Length > 128) { diff --git a/OpenSim/Data/PGSQL/PGSQLManager.cs b/OpenSim/Data/PGSQL/PGSQLManager.cs index 46f835a..276a37c 100644 --- a/OpenSim/Data/PGSQL/PGSQLManager.cs +++ b/OpenSim/Data/PGSQL/PGSQLManager.cs @@ -251,7 +251,7 @@ namespace OpenSim.Data.PGSQL } if (PGFieldType == "double precision") { - return (Double)value; + return Convert.ToDouble(value); } return CreateParameterValue(value); } @@ -326,7 +326,7 @@ namespace OpenSim.Data.PGSQL /// migrationStore. public void CheckMigration(string migrationStore) { - using (NpgsqlConnection connection = new NpgsqlConnection(connectionString)) + using (NpgsqlConnection connection = new NpgsqlConnection(connectionString)) { connection.Open(); Assembly assem = GetType().Assembly; diff --git a/OpenSim/Data/PGSQL/PGSQLMigration.cs b/OpenSim/Data/PGSQL/PGSQLMigration.cs index 709fde0..749a3f2 100644 --- a/OpenSim/Data/PGSQL/PGSQLMigration.cs +++ b/OpenSim/Data/PGSQL/PGSQLMigration.cs @@ -54,8 +54,8 @@ namespace OpenSim.Data.PGSQL { try { - cmd.CommandText = "select version from migrations where name = '" + type + "' " + - " order by version desc limit 1"; //Must be + cmd.CommandText = "select version from migrations where name = '" + type + "' " + + " order by version desc limit 1"; //Must be using (NpgsqlDataReader reader = cmd.ExecuteReader()) { if (reader.Read()) diff --git a/OpenSim/Data/PGSQL/PGSQLOfflineIMData.cs b/OpenSim/Data/PGSQL/PGSQLOfflineIMData.cs index 82e5ed8..a0c3542 100644 --- a/OpenSim/Data/PGSQL/PGSQLOfflineIMData.cs +++ b/OpenSim/Data/PGSQL/PGSQLOfflineIMData.cs @@ -47,7 +47,7 @@ namespace OpenSim.Data.PGSQL using (NpgsqlCommand cmd = new NpgsqlCommand()) { cmd.CommandText = String.Format("delete from {0} where \"TMStamp\" < CURRENT_DATE - INTERVAL '2 week'", m_Realm); - + ExecuteNonQuery(cmd); } diff --git a/OpenSim/Data/PGSQL/PGSQLPresenceData.cs b/OpenSim/Data/PGSQL/PGSQLPresenceData.cs old mode 100644 new mode 100755 index 0376585..ebbe8d3 --- a/OpenSim/Data/PGSQL/PGSQLPresenceData.cs +++ b/OpenSim/Data/PGSQL/PGSQLPresenceData.cs @@ -80,7 +80,7 @@ namespace OpenSim.Data.PGSQL PresenceData[] pd = Get("SessionID", sessionID.ToString()); if (pd.Length == 0) return false; - + if (regionID == UUID.Zero) return false; @@ -103,7 +103,7 @@ namespace OpenSim.Data.PGSQL public bool VerifyAgent(UUID agentId, UUID secureSessionID) { PresenceData[] ret = Get("SecureSessionID", secureSessionID.ToString()); - + if (ret.Length == 0) return false; diff --git a/OpenSim/Data/PGSQL/PGSQLRegionData.cs b/OpenSim/Data/PGSQL/PGSQLRegionData.cs index b3076f0..1272e37 100644 --- a/OpenSim/Data/PGSQL/PGSQLRegionData.cs +++ b/OpenSim/Data/PGSQL/PGSQLRegionData.cs @@ -26,16 +26,14 @@ */ using System; +using System.Collections; using System.Collections.Generic; using System.Data; -using System.Drawing; -using System.IO; using System.Reflection; using log4net; using OpenMetaverse; using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; +using OpenSim.Data; using RegionFlags = OpenSim.Framework.RegionFlags; using Npgsql; @@ -59,7 +57,7 @@ namespace OpenSim.Data.PGSQL get { return GetType().Assembly; } } - public PGSQLRegionData(string connectionString, string realm) + public PGSQLRegionData(string connectionString, string realm) { m_Realm = realm; m_ConnectionString = connectionString; @@ -79,7 +77,7 @@ namespace OpenSim.Data.PGSQL m_FieldTypes = new Dictionary(); string query = string.Format(@"select column_name,data_type - from INFORMATION_SCHEMA.COLUMNS + from INFORMATION_SCHEMA.COLUMNS where table_name = lower('{0}'); ", m_Realm); @@ -109,7 +107,7 @@ namespace OpenSim.Data.PGSQL using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) { cmd.Parameters.Add(m_database.CreateParameter("regionName", regionName)); - if (scopeID != UUID.Zero) + if (scopeID != UUID.Zero) cmd.Parameters.Add(m_database.CreateParameter("scopeID", scopeID)); conn.Open(); return RunCommand(cmd); @@ -118,24 +116,46 @@ namespace OpenSim.Data.PGSQL public RegionData Get(int posX, int posY, UUID scopeID) { - string sql = "select * from "+m_Realm+" where \"locX\" = :posX and \"locY\" = :posY"; + // extend database search for maximum region size area + string sql = "select * from "+m_Realm+" where \"locX\" between :startX and :endX and \"locY\" between :startY and :endY"; if (scopeID != UUID.Zero) sql += " and \"ScopeID\" = :scopeID"; + int startX = posX - (int)Constants.MaximumRegionSize; + int startY = posY - (int)Constants.MaximumRegionSize; + int endX = posX; + int endY = posY; + + List ret; using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString)) using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) { - cmd.Parameters.Add(m_database.CreateParameter("posX", posX)); - cmd.Parameters.Add(m_database.CreateParameter("posY", posY)); - if (scopeID != UUID.Zero) + cmd.Parameters.Add(m_database.CreateParameter("startX", startX)); + cmd.Parameters.Add(m_database.CreateParameter("startY", startY)); + cmd.Parameters.Add(m_database.CreateParameter("endX", endX)); + cmd.Parameters.Add(m_database.CreateParameter("endY", endY)); + if (scopeID != UUID.Zero) cmd.Parameters.Add(m_database.CreateParameter("scopeID", scopeID)); conn.Open(); - List ret = RunCommand(cmd); - if (ret.Count == 0) - return null; + ret = RunCommand(cmd); + } - return ret[0]; + if (ret.Count == 0) + return null; + + // Find the first that contains pos + RegionData rg = null; + foreach (RegionData r in ret) + { + if (posX >= r.posX && posX < r.posX + r.sizeX + && posY >= r.posY && posY < r.posY + r.sizeY) + { + rg = r; + break; + } } + + return rg; } public RegionData Get(UUID regionID, UUID scopeID) @@ -147,7 +167,7 @@ namespace OpenSim.Data.PGSQL using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) { cmd.Parameters.Add(m_database.CreateParameter("regionID", regionID)); - if (scopeID != UUID.Zero) + if (scopeID != UUID.Zero) cmd.Parameters.Add(m_database.CreateParameter("scopeID", scopeID)); conn.Open(); List ret = RunCommand(cmd); @@ -160,21 +180,41 @@ namespace OpenSim.Data.PGSQL public List Get(int startX, int startY, int endX, int endY, UUID scopeID) { + // extend database search for maximum region size area string sql = "select * from "+m_Realm+" where \"locX\" between :startX and :endX and \"locY\" between :startY and :endY"; if (scopeID != UUID.Zero) sql += " and \"ScopeID\" = :scopeID"; + int qstartX = startX - (int)Constants.MaximumRegionSize; + int qstartY = startY - (int)Constants.MaximumRegionSize; + + List dbret; using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString)) using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) { - cmd.Parameters.Add(m_database.CreateParameter("startX", startX)); - cmd.Parameters.Add(m_database.CreateParameter("startY", startY)); + cmd.Parameters.Add(m_database.CreateParameter("startX", qstartX)); + cmd.Parameters.Add(m_database.CreateParameter("startY", qstartY)); cmd.Parameters.Add(m_database.CreateParameter("endX", endX)); cmd.Parameters.Add(m_database.CreateParameter("endY", endY)); - cmd.Parameters.Add(m_database.CreateParameter("scopeID", scopeID)); + if (scopeID != UUID.Zero) + cmd.Parameters.Add(m_database.CreateParameter("scopeID", scopeID)); conn.Open(); - return RunCommand(cmd); + + dbret = RunCommand(cmd); } + + List ret = new List(); + + if(dbret.Count == 0) + return ret; + + foreach (RegionData r in dbret) + { + if (r.posX + r.sizeX > startX && r.posX <= endX + && r.posY + r.sizeY > startY && r.posY <= endY) + ret.Add(r); + } + return ret; } public List RunCommand(NpgsqlCommand cmd) @@ -258,7 +298,7 @@ namespace OpenSim.Data.PGSQL { string update = "update " + m_Realm + " set \"locX\"=:posX, \"locY\"=:posY, \"sizeX\"=:sizeX, \"sizeY\"=:sizeY "; - + foreach (string field in fields) { diff --git a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs old mode 100644 new mode 100755 index 77d87d4..f4af40b --- a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs +++ b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs @@ -31,11 +31,13 @@ using System.Data; using System.Drawing; using System.IO; using System.Reflection; +using System.Threading; using log4net; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Data; using Npgsql; namespace OpenSim.Data.PGSQL @@ -108,11 +110,11 @@ namespace OpenSim.Data.PGSQL Dictionary objects = new Dictionary(); SceneObjectGroup grp = null; - string sql = @"SELECT *, - CASE WHEN prims.""UUID"" = prims.""SceneGroupID"" THEN 0 ELSE 1 END as sort - FROM prims - LEFT JOIN primshapes ON prims.""UUID"" = primshapes.""UUID"" - WHERE ""RegionUUID"" = :RegionUUID + string sql = @"SELECT *, + CASE WHEN prims.""UUID"" = prims.""SceneGroupID"" THEN 0 ELSE 1 END as sort + FROM prims + LEFT JOIN primshapes ON prims.""UUID"" = primshapes.""UUID"" + WHERE ""RegionUUID"" = :RegionUUID ORDER BY ""SceneGroupID"" asc, sort asc, ""LinkNumber"" asc"; using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) @@ -144,7 +146,7 @@ namespace OpenSim.Data.PGSQL // There sometimes exist OpenSim bugs that 'orphan groups' so that none of the prims are // recorded as the root prim (for which the UUID must equal the persisted group UUID). In // this case, force the UUID to be the same as the group UUID so that at least these can be - // deleted (we need to change the UUID so that any other prims in the linkset can also be + // deleted (we need to change the UUID so that any other prims in the linkset can also be // deleted). if (sceneObjectPart.UUID != groupID && groupID != UUID.Zero) { @@ -176,7 +178,7 @@ namespace OpenSim.Data.PGSQL objects[grp.UUID] = grp; // Instead of attempting to LoadItems on every prim, - // most of which probably have no items... get a + // most of which probably have no items... get a // list from DB of all prims which have items and // LoadItems only on those List primsWithInventory = new List(); @@ -329,54 +331,55 @@ namespace OpenSim.Data.PGSQL private void StoreSceneObjectPrim(SceneObjectPart sceneObjectPart, NpgsqlCommand sqlCommand, UUID sceneGroupID, UUID regionUUID) { //Big query to update or insert a new prim. - + string queryPrims = @" - UPDATE prims SET - ""CreationDate"" = :CreationDate, ""Name"" = :Name, ""Text"" = :Text, ""Description"" = :Description, ""SitName"" = :SitName, - ""TouchName"" = :TouchName, ""ObjectFlags"" = :ObjectFlags, ""OwnerMask"" = :OwnerMask, ""NextOwnerMask"" = :NextOwnerMask, ""GroupMask"" = :GroupMask, - ""EveryoneMask"" = :EveryoneMask, ""BaseMask"" = :BaseMask, ""PositionX"" = :PositionX, ""PositionY"" = :PositionY, ""PositionZ"" = :PositionZ, - ""GroupPositionX"" = :GroupPositionX, ""GroupPositionY"" = :GroupPositionY, ""GroupPositionZ"" = :GroupPositionZ, ""VelocityX"" = :VelocityX, - ""VelocityY"" = :VelocityY, ""VelocityZ"" = :VelocityZ, ""AngularVelocityX"" = :AngularVelocityX, ""AngularVelocityY"" = :AngularVelocityY, - ""AngularVelocityZ"" = :AngularVelocityZ, ""AccelerationX"" = :AccelerationX, ""AccelerationY"" = :AccelerationY, - ""AccelerationZ"" = :AccelerationZ, ""RotationX"" = :RotationX, ""RotationY"" = :RotationY, ""RotationZ"" = :RotationZ, ""RotationW"" = :RotationW, - ""SitTargetOffsetX"" = :SitTargetOffsetX, ""SitTargetOffsetY"" = :SitTargetOffsetY, ""SitTargetOffsetZ"" = :SitTargetOffsetZ, - ""SitTargetOrientW"" = :SitTargetOrientW, ""SitTargetOrientX"" = :SitTargetOrientX, ""SitTargetOrientY"" = :SitTargetOrientY, - ""SitTargetOrientZ"" = :SitTargetOrientZ, ""RegionUUID"" = :RegionUUID, ""CreatorID"" = :CreatorID, ""OwnerID"" = :OwnerID, ""GroupID"" = :GroupID, - ""LastOwnerID"" = :LastOwnerID, ""SceneGroupID"" = :SceneGroupID, ""PayPrice"" = :PayPrice, ""PayButton1"" = :PayButton1, ""PayButton2"" = :PayButton2, - ""PayButton3"" = :PayButton3, ""PayButton4"" = :PayButton4, ""LoopedSound"" = :LoopedSound, ""LoopedSoundGain"" = :LoopedSoundGain, - ""TextureAnimation"" = :TextureAnimation, ""OmegaX"" = :OmegaX, ""OmegaY"" = :OmegaY, ""OmegaZ"" = :OmegaZ, ""CameraEyeOffsetX"" = :CameraEyeOffsetX, - ""CameraEyeOffsetY"" = :CameraEyeOffsetY, ""CameraEyeOffsetZ"" = :CameraEyeOffsetZ, ""CameraAtOffsetX"" = :CameraAtOffsetX, - ""CameraAtOffsetY"" = :CameraAtOffsetY, ""CameraAtOffsetZ"" = :CameraAtOffsetZ, ""ForceMouselook"" = :ForceMouselook, - ""ScriptAccessPin"" = :ScriptAccessPin, ""AllowedDrop"" = :AllowedDrop, ""DieAtEdge"" = :DieAtEdge, ""SalePrice"" = :SalePrice, - ""SaleType"" = :SaleType, ""ColorR"" = :ColorR, ""ColorG"" = :ColorG, ""ColorB"" = :ColorB, ""ColorA"" = :ColorA, ""ParticleSystem"" = :ParticleSystem, + UPDATE prims SET + ""CreationDate"" = :CreationDate, ""Name"" = :Name, ""Text"" = :Text, ""Description"" = :Description, ""SitName"" = :SitName, + ""TouchName"" = :TouchName, ""ObjectFlags"" = :ObjectFlags, ""OwnerMask"" = :OwnerMask, ""NextOwnerMask"" = :NextOwnerMask, ""GroupMask"" = :GroupMask, + ""EveryoneMask"" = :EveryoneMask, ""BaseMask"" = :BaseMask, ""PositionX"" = :PositionX, ""PositionY"" = :PositionY, ""PositionZ"" = :PositionZ, + ""GroupPositionX"" = :GroupPositionX, ""GroupPositionY"" = :GroupPositionY, ""GroupPositionZ"" = :GroupPositionZ, ""VelocityX"" = :VelocityX, + ""VelocityY"" = :VelocityY, ""VelocityZ"" = :VelocityZ, ""AngularVelocityX"" = :AngularVelocityX, ""AngularVelocityY"" = :AngularVelocityY, + ""AngularVelocityZ"" = :AngularVelocityZ, ""AccelerationX"" = :AccelerationX, ""AccelerationY"" = :AccelerationY, + ""AccelerationZ"" = :AccelerationZ, ""RotationX"" = :RotationX, ""RotationY"" = :RotationY, ""RotationZ"" = :RotationZ, ""RotationW"" = :RotationW, + ""SitTargetOffsetX"" = :SitTargetOffsetX, ""SitTargetOffsetY"" = :SitTargetOffsetY, ""SitTargetOffsetZ"" = :SitTargetOffsetZ, + ""SitTargetOrientW"" = :SitTargetOrientW, ""SitTargetOrientX"" = :SitTargetOrientX, ""SitTargetOrientY"" = :SitTargetOrientY, + ""SitTargetOrientZ"" = :SitTargetOrientZ, ""RegionUUID"" = :RegionUUID, ""CreatorID"" = :CreatorID, ""OwnerID"" = :OwnerID, ""GroupID"" = :GroupID, + ""LastOwnerID"" = :LastOwnerID, ""SceneGroupID"" = :SceneGroupID, ""PayPrice"" = :PayPrice, ""PayButton1"" = :PayButton1, ""PayButton2"" = :PayButton2, + ""PayButton3"" = :PayButton3, ""PayButton4"" = :PayButton4, ""LoopedSound"" = :LoopedSound, ""LoopedSoundGain"" = :LoopedSoundGain, + ""TextureAnimation"" = :TextureAnimation, ""OmegaX"" = :OmegaX, ""OmegaY"" = :OmegaY, ""OmegaZ"" = :OmegaZ, ""CameraEyeOffsetX"" = :CameraEyeOffsetX, + ""CameraEyeOffsetY"" = :CameraEyeOffsetY, ""CameraEyeOffsetZ"" = :CameraEyeOffsetZ, ""CameraAtOffsetX"" = :CameraAtOffsetX, + ""CameraAtOffsetY"" = :CameraAtOffsetY, ""CameraAtOffsetZ"" = :CameraAtOffsetZ, ""ForceMouselook"" = :ForceMouselook, + ""ScriptAccessPin"" = :ScriptAccessPin, ""AllowedDrop"" = :AllowedDrop, ""DieAtEdge"" = :DieAtEdge, ""SalePrice"" = :SalePrice, + ""PhysicsShapeType"" = :PhysicsShapeType, ""Density"" = :Density, ""GravityModifier"" = :GravityModifier, ""Friction"" = :Friction, ""Restitution"" = :Restitution, + ""PassCollisions"" = :PassCollisions, ""RotationAxisLocks"" = :RotationAxisLocks, ""RezzerID"" = :RezzerID, ""ClickAction"" = :ClickAction, ""Material"" = :Material, ""CollisionSound"" = :CollisionSound, ""CollisionSoundVolume"" = :CollisionSoundVolume, ""PassTouches"" = :PassTouches, ""LinkNumber"" = :LinkNumber, ""MediaURL"" = :MediaURL, ""DynAttrs"" = :DynAttrs, - ""PhysicsShapeType"" = :PhysicsShapeType, ""Density"" = :Density, ""GravityModifier"" = :GravityModifier, ""Friction"" = :Friction, ""Restitution"" = :Restitution + ""PhysInertia"" = :PhysInertia WHERE ""UUID"" = :UUID ; - INSERT INTO + INSERT INTO prims ( ""UUID"", ""CreationDate"", ""Name"", ""Text"", ""Description"", ""SitName"", ""TouchName"", ""ObjectFlags"", ""OwnerMask"", ""NextOwnerMask"", ""GroupMask"", - ""EveryoneMask"", ""BaseMask"", ""PositionX"", ""PositionY"", ""PositionZ"", ""GroupPositionX"", ""GroupPositionY"", ""GroupPositionZ"", ""VelocityX"", - ""VelocityY"", ""VelocityZ"", ""AngularVelocityX"", ""AngularVelocityY"", ""AngularVelocityZ"", ""AccelerationX"", ""AccelerationY"", ""AccelerationZ"", - ""RotationX"", ""RotationY"", ""RotationZ"", ""RotationW"", ""SitTargetOffsetX"", ""SitTargetOffsetY"", ""SitTargetOffsetZ"", ""SitTargetOrientW"", - ""SitTargetOrientX"", ""SitTargetOrientY"", ""SitTargetOrientZ"", ""RegionUUID"", ""CreatorID"", ""OwnerID"", ""GroupID"", ""LastOwnerID"", ""SceneGroupID"", - ""PayPrice"", ""PayButton1"", ""PayButton2"", ""PayButton3"", ""PayButton4"", ""LoopedSound"", ""LoopedSoundGain"", ""TextureAnimation"", ""OmegaX"", - ""OmegaY"", ""OmegaZ"", ""CameraEyeOffsetX"", ""CameraEyeOffsetY"", ""CameraEyeOffsetZ"", ""CameraAtOffsetX"", ""CameraAtOffsetY"", ""CameraAtOffsetZ"", - ""ForceMouselook"", ""ScriptAccessPin"", ""AllowedDrop"", ""DieAtEdge"", ""SalePrice"", ""SaleType"", ""ColorR"", ""ColorG"", ""ColorB"", ""ColorA"", + ""EveryoneMask"", ""BaseMask"", ""PositionX"", ""PositionY"", ""PositionZ"", ""GroupPositionX"", ""GroupPositionY"", ""GroupPositionZ"", ""VelocityX"", + ""VelocityY"", ""VelocityZ"", ""AngularVelocityX"", ""AngularVelocityY"", ""AngularVelocityZ"", ""AccelerationX"", ""AccelerationY"", ""AccelerationZ"", + ""RotationX"", ""RotationY"", ""RotationZ"", ""RotationW"", ""SitTargetOffsetX"", ""SitTargetOffsetY"", ""SitTargetOffsetZ"", ""SitTargetOrientW"", + ""SitTargetOrientX"", ""SitTargetOrientY"", ""SitTargetOrientZ"", ""RegionUUID"", ""CreatorID"", ""OwnerID"", ""GroupID"", ""LastOwnerID"", ""SceneGroupID"", + ""PayPrice"", ""PayButton1"", ""PayButton2"", ""PayButton3"", ""PayButton4"", ""LoopedSound"", ""LoopedSoundGain"", ""TextureAnimation"", ""OmegaX"", + ""OmegaY"", ""OmegaZ"", ""CameraEyeOffsetX"", ""CameraEyeOffsetY"", ""CameraEyeOffsetZ"", ""CameraAtOffsetX"", ""CameraAtOffsetY"", ""CameraAtOffsetZ"", + ""ForceMouselook"", ""ScriptAccessPin"", ""AllowedDrop"", ""DieAtEdge"", ""SalePrice"", ""SaleType"", ""ColorR"", ""ColorG"", ""ColorB"", ""ColorA"", ""ParticleSystem"", ""ClickAction"", ""Material"", ""CollisionSound"", ""CollisionSoundVolume"", ""PassTouches"", ""LinkNumber"", ""MediaURL"", ""DynAttrs"", - ""PhysicsShapeType"", ""Density"", ""GravityModifier"", ""Friction"", ""Restitution"" - ) Select - :UUID, :CreationDate, :Name, :Text, :Description, :SitName, :TouchName, :ObjectFlags, :OwnerMask, :NextOwnerMask, :GroupMask, - :EveryoneMask, :BaseMask, :PositionX, :PositionY, :PositionZ, :GroupPositionX, :GroupPositionY, :GroupPositionZ, :VelocityX, - :VelocityY, :VelocityZ, :AngularVelocityX, :AngularVelocityY, :AngularVelocityZ, :AccelerationX, :AccelerationY, :AccelerationZ, - :RotationX, :RotationY, :RotationZ, :RotationW, :SitTargetOffsetX, :SitTargetOffsetY, :SitTargetOffsetZ, :SitTargetOrientW, - :SitTargetOrientX, :SitTargetOrientY, :SitTargetOrientZ, :RegionUUID, :CreatorID, :OwnerID, :GroupID, :LastOwnerID, :SceneGroupID, - :PayPrice, :PayButton1, :PayButton2, :PayButton3, :PayButton4, :LoopedSound, :LoopedSoundGain, :TextureAnimation, :OmegaX, - :OmegaY, :OmegaZ, :CameraEyeOffsetX, :CameraEyeOffsetY, :CameraEyeOffsetZ, :CameraAtOffsetX, :CameraAtOffsetY, :CameraAtOffsetZ, - :ForceMouselook, :ScriptAccessPin, :AllowedDrop, :DieAtEdge, :SalePrice, :SaleType, :ColorR, :ColorG, :ColorB, :ColorA, + ""PhysicsShapeType"", ""Density"", ""GravityModifier"", ""Friction"", ""Restitution"", ""PassCollisions"", ""RotationAxisLocks"", ""RezzerID"" , ""PhysInertia"" + ) Select + :UUID, :CreationDate, :Name, :Text, :Description, :SitName, :TouchName, :ObjectFlags, :OwnerMask, :NextOwnerMask, :GroupMask, + :EveryoneMask, :BaseMask, :PositionX, :PositionY, :PositionZ, :GroupPositionX, :GroupPositionY, :GroupPositionZ, :VelocityX, + :VelocityY, :VelocityZ, :AngularVelocityX, :AngularVelocityY, :AngularVelocityZ, :AccelerationX, :AccelerationY, :AccelerationZ, + :RotationX, :RotationY, :RotationZ, :RotationW, :SitTargetOffsetX, :SitTargetOffsetY, :SitTargetOffsetZ, :SitTargetOrientW, + :SitTargetOrientX, :SitTargetOrientY, :SitTargetOrientZ, :RegionUUID, :CreatorID, :OwnerID, :GroupID, :LastOwnerID, :SceneGroupID, + :PayPrice, :PayButton1, :PayButton2, :PayButton3, :PayButton4, :LoopedSound, :LoopedSoundGain, :TextureAnimation, :OmegaX, + :OmegaY, :OmegaZ, :CameraEyeOffsetX, :CameraEyeOffsetY, :CameraEyeOffsetZ, :CameraAtOffsetX, :CameraAtOffsetY, :CameraAtOffsetZ, + :ForceMouselook, :ScriptAccessPin, :AllowedDrop, :DieAtEdge, :SalePrice, :SaleType, :ColorR, :ColorG, :ColorB, :ColorA, :ParticleSystem, :ClickAction, :Material, :CollisionSound, :CollisionSoundVolume, :PassTouches, :LinkNumber, :MediaURL, :DynAttrs, - :PhysicsShapeType, :Density, :GravityModifier, :Friction, :Restitution + :PhysicsShapeType, :Density, :GravityModifier, :Friction, :Restitution, :PassCollisions, :RotationAxisLocks, :RezzerID, :PhysInertia where not EXISTS (SELECT ""UUID"" FROM prims WHERE ""UUID"" = :UUID); "; @@ -399,26 +402,26 @@ namespace OpenSim.Data.PGSQL private void StoreSceneObjectPrimShapes(SceneObjectPart sceneObjectPart, NpgsqlCommand sqlCommand, UUID sceneGroupID, UUID regionUUID) { //Big query to or insert or update primshapes - + string queryPrimShapes = @" - UPDATE primshapes SET - ""Shape"" = :Shape, ""ScaleX"" = :ScaleX, ""ScaleY"" = :ScaleY, ""ScaleZ"" = :ScaleZ, ""PCode"" = :PCode, ""PathBegin"" = :PathBegin, - ""PathEnd"" = :PathEnd, ""PathScaleX"" = :PathScaleX, ""PathScaleY"" = :PathScaleY, ""PathShearX"" = :PathShearX, ""PathShearY"" = :PathShearY, - ""PathSkew"" = :PathSkew, ""PathCurve"" = :PathCurve, ""PathRadiusOffset"" = :PathRadiusOffset, ""PathRevolutions"" = :PathRevolutions, - ""PathTaperX"" = :PathTaperX, ""PathTaperY"" = :PathTaperY, ""PathTwist"" = :PathTwist, ""PathTwistBegin"" = :PathTwistBegin, - ""ProfileBegin"" = :ProfileBegin, ""ProfileEnd"" = :ProfileEnd, ""ProfileCurve"" = :ProfileCurve, ""ProfileHollow"" = :ProfileHollow, + UPDATE primshapes SET + ""Shape"" = :Shape, ""ScaleX"" = :ScaleX, ""ScaleY"" = :ScaleY, ""ScaleZ"" = :ScaleZ, ""PCode"" = :PCode, ""PathBegin"" = :PathBegin, + ""PathEnd"" = :PathEnd, ""PathScaleX"" = :PathScaleX, ""PathScaleY"" = :PathScaleY, ""PathShearX"" = :PathShearX, ""PathShearY"" = :PathShearY, + ""PathSkew"" = :PathSkew, ""PathCurve"" = :PathCurve, ""PathRadiusOffset"" = :PathRadiusOffset, ""PathRevolutions"" = :PathRevolutions, + ""PathTaperX"" = :PathTaperX, ""PathTaperY"" = :PathTaperY, ""PathTwist"" = :PathTwist, ""PathTwistBegin"" = :PathTwistBegin, + ""ProfileBegin"" = :ProfileBegin, ""ProfileEnd"" = :ProfileEnd, ""ProfileCurve"" = :ProfileCurve, ""ProfileHollow"" = :ProfileHollow, ""Texture"" = :Texture, ""ExtraParams"" = :ExtraParams, ""State"" = :State, ""Media"" = :Media WHERE ""UUID"" = :UUID ; - INSERT INTO + INSERT INTO primshapes ( - ""UUID"", ""Shape"", ""ScaleX"", ""ScaleY"", ""ScaleZ"", ""PCode"", ""PathBegin"", ""PathEnd"", ""PathScaleX"", ""PathScaleY"", ""PathShearX"", ""PathShearY"", - ""PathSkew"", ""PathCurve"", ""PathRadiusOffset"", ""PathRevolutions"", ""PathTaperX"", ""PathTaperY"", ""PathTwist"", ""PathTwistBegin"", ""ProfileBegin"", + ""UUID"", ""Shape"", ""ScaleX"", ""ScaleY"", ""ScaleZ"", ""PCode"", ""PathBegin"", ""PathEnd"", ""PathScaleX"", ""PathScaleY"", ""PathShearX"", ""PathShearY"", + ""PathSkew"", ""PathCurve"", ""PathRadiusOffset"", ""PathRevolutions"", ""PathTaperX"", ""PathTaperY"", ""PathTwist"", ""PathTwistBegin"", ""ProfileBegin"", ""ProfileEnd"", ""ProfileCurve"", ""ProfileHollow"", ""Texture"", ""ExtraParams"", ""State"", ""Media"" - ) + ) Select - :UUID, :Shape, :ScaleX, :ScaleY, :ScaleZ, :PCode, :PathBegin, :PathEnd, :PathScaleX, :PathScaleY, :PathShearX, :PathShearY, - :PathSkew, :PathCurve, :PathRadiusOffset, :PathRevolutions, :PathTaperX, :PathTaperY, :PathTwist, :PathTwistBegin, :ProfileBegin, + :UUID, :Shape, :ScaleX, :ScaleY, :ScaleZ, :PCode, :PathBegin, :PathEnd, :PathScaleX, :PathScaleY, :PathShearX, :PathShearY, + :PathSkew, :PathCurve, :PathRadiusOffset, :PathRevolutions, :PathTaperX, :PathTaperY, :PathTwist, :PathTwistBegin, :ProfileBegin, :ProfileEnd, :ProfileCurve, :ProfileHollow, :Texture, :ExtraParams, :State, :Media where not EXISTS (SELECT ""UUID"" FROM primshapes WHERE ""UUID"" = :UUID); "; @@ -498,7 +501,7 @@ namespace OpenSim.Data.PGSQL sql = @"INSERT INTO primitems ( ""itemID"",""primID"",""assetID"",""parentFolderID"",""invType"",""assetType"",""name"",""description"",""creationDate"",""creatorID"",""ownerID"",""lastOwnerID"",""groupID"", - ""nextPermissions"",""currentPermissions"",""basePermissions"",""everyonePermissions"",""groupPermissions"",""flags"") + ""nextPermissions"",""currentPermissions"",""basePermissions"",""everyonePermissions"",""groupPermissions"",""flags"") VALUES (:itemID,:primID,:assetID,:parentFolderID,:invType,:assetType,:name,:description,:creationDate,:creatorID,:ownerID, :lastOwnerID,:groupID,:nextPermissions,:currentPermissions,:basePermissions,:everyonePermissions,:groupPermissions,:flags)"; @@ -536,7 +539,7 @@ namespace OpenSim.Data.PGSQL { TerrainData terrData = null; - string sql = @"select ""RegionUUID"", ""Revision"", ""Heightfield"" from terrain + string sql = @"select ""RegionUUID"", ""Revision"", ""Heightfield"" from terrain where ""RegionUUID"" = :RegionUUID order by ""Revision"" desc limit 1; "; using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) @@ -552,8 +555,11 @@ namespace OpenSim.Data.PGSQL if (reader.Read()) { rev = Convert.ToInt32(reader["Revision"]); - byte[] blob = (byte[])reader["Heightfield"]; - terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); + if ((reader["Heightfield"] != DBNull.Value)) + { + byte[] blob = (byte[])reader["Heightfield"]; + terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); + } } else { @@ -568,6 +574,39 @@ namespace OpenSim.Data.PGSQL return terrData; } + public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) + { + TerrainData terrData = null; + + string sql = @"select ""RegionUUID"", ""Revision"", ""Heightfield"" from bakedterrain + where ""RegionUUID"" = :RegionUUID; "; + + using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) + { + using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) + { + // PGSqlParameter param = new PGSqlParameter(); + cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID)); + conn.Open(); + using (NpgsqlDataReader reader = cmd.ExecuteReader()) + { + int rev; + if (reader.Read()) + { + rev = Convert.ToInt32(reader["Revision"]); + if ((reader["Heightfield"] != DBNull.Value)) + { + byte[] blob = (byte[])reader["Heightfield"]; + terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); + } + } + } + } + } + + return terrData; + } + // Legacy entry point for when terrain was always a 256x256 heightmap public void StoreTerrain(double[,] terrain, UUID regionID) { @@ -619,6 +658,49 @@ namespace OpenSim.Data.PGSQL } /// + /// Stores the baked terrain map to DB. + /// + /// terrain map data. + /// regionID. + public void StoreBakedTerrain(TerrainData terrData, UUID regionID) + { + //Delete old terrain map + string sql = @"delete from bakedterrain where ""RegionUUID""=:RegionUUID"; + using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) + { + using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) + { + cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID)); + conn.Open(); + cmd.ExecuteNonQuery(); + + _Log.InfoFormat("{0} Deleted bakedterrain id = {1}", LogHeader, regionID); + } + } + + int terrainDBRevision; + Array terrainDBblob; + terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); + + sql = @"insert into bakedterrain(""RegionUUID"", ""Revision"", ""Heightfield"") values(:RegionUUID, :Revision, :Heightfield)"; + + using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) + { + using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) + { + cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID)); + cmd.Parameters.Add(_Database.CreateParameter("Revision", terrainDBRevision)); + cmd.Parameters.Add(_Database.CreateParameter("Heightfield", terrainDBblob)); + conn.Open(); + cmd.ExecuteNonQuery(); + + _Log.InfoFormat("{0} Stored bakedterrain id = {1}, terrainSize = <{2},{3}>", + LogHeader, regionID, terrData.SizeX, terrData.SizeY); + } + } + } + + /// /// Loads all the land objects of a region. /// /// The region UUID. @@ -683,11 +765,14 @@ namespace OpenSim.Data.PGSQL string sql = @"INSERT INTO land (""UUID"",""RegionUUID"",""LocalLandID"",""Bitmap"",""Name"",""Description"",""OwnerUUID"",""IsGroupOwned"",""Area"",""AuctionID"",""Category"",""ClaimDate"",""ClaimPrice"", ""GroupUUID"",""SalePrice"",""LandStatus"",""LandFlags"",""LandingType"",""MediaAutoScale"",""MediaTextureUUID"",""MediaURL"",""MusicURL"",""PassHours"",""PassPrice"", - ""SnapshotUUID"",""UserLocationX"",""UserLocationY"",""UserLocationZ"",""UserLookAtX"",""UserLookAtY"",""UserLookAtZ"",""AuthbuyerID"",""OtherCleanTime"") + ""SnapshotUUID"",""UserLocationX"",""UserLocationY"",""UserLocationZ"",""UserLookAtX"",""UserLookAtY"",""UserLookAtZ"",""AuthbuyerID"",""OtherCleanTime"",""Dwell"", + ""MediaType"",""MediaDescription"",""MediaSize"",""MediaLoop"",""ObscureMusic"",""ObscureMedia"",""SeeAVs"",""AnyAVSounds"",""GroupAVSounds"") VALUES (:UUID,:RegionUUID,:LocalLandID,:Bitmap,:Name,:Description,:OwnerUUID,:IsGroupOwned,:Area,:AuctionID,:Category,:ClaimDate,:ClaimPrice, :GroupUUID,:SalePrice,:LandStatus,:LandFlags,:LandingType,:MediaAutoScale,:MediaTextureUUID,:MediaURL,:MusicURL,:PassHours,:PassPrice, - :SnapshotUUID,:UserLocationX,:UserLocationY,:UserLocationZ,:UserLookAtX,:UserLookAtY,:UserLookAtZ,:AuthbuyerID,:OtherCleanTime)"; + :SnapshotUUID,:UserLocationX,:UserLocationY,:UserLocationZ,:UserLookAtX,:UserLookAtY,:UserLookAtZ,:AuthbuyerID,:OtherCleanTime,:Dwell, + :MediaType,:MediaDescription,:MediaWidth::text || ',' || :MediaHeight::text,:MediaLoop,:ObscureMusic,:ObscureMedia,:SeeAVs::int::smallint, + :AnyAVSounds::int::smallint,:GroupAVSounds::int::smallint)"; using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) @@ -1235,7 +1320,7 @@ namespace OpenSim.Data.PGSQL { { string sql = "DELETE FROM regionenvironment WHERE region_id = :region_id ;"; - + using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) { @@ -1336,17 +1421,17 @@ namespace OpenSim.Data.PGSQL { //This method only updates region settings!!! First call LoadRegionSettings to create new region settings in DB sql = - @"UPDATE regionsettings SET block_terraform = :block_terraform ,block_fly = :block_fly ,allow_damage = :allow_damage -,restrict_pushing = :restrict_pushing ,allow_land_resell = :allow_land_resell ,allow_land_join_divide = :allow_land_join_divide -,block_show_in_search = :block_show_in_search ,agent_limit = :agent_limit ,object_bonus = :object_bonus ,maturity = :maturity -,disable_scripts = :disable_scripts ,disable_collisions = :disable_collisions ,disable_physics = :disable_physics -,terrain_texture_1 = :terrain_texture_1 ,terrain_texture_2 = :terrain_texture_2 ,terrain_texture_3 = :terrain_texture_3 -,terrain_texture_4 = :terrain_texture_4 ,elevation_1_nw = :elevation_1_nw ,elevation_2_nw = :elevation_2_nw -,elevation_1_ne = :elevation_1_ne ,elevation_2_ne = :elevation_2_ne ,elevation_1_se = :elevation_1_se ,elevation_2_se = :elevation_2_se -,elevation_1_sw = :elevation_1_sw ,elevation_2_sw = :elevation_2_sw ,water_height = :water_height ,terrain_raise_limit = :terrain_raise_limit -,terrain_lower_limit = :terrain_lower_limit ,use_estate_sun = :use_estate_sun ,fixed_sun = :fixed_sun ,sun_position = :sun_position -,covenant = :covenant ,covenant_datetime = :covenant_datetime, sunvectorx = :sunvectorx, sunvectory = :sunvectory, sunvectorz = :sunvectorz, -""Sandbox"" = :Sandbox, loaded_creation_datetime = :loaded_creation_datetime, loaded_creation_id = :loaded_creation_id, ""map_tile_ID"" = :TerrainImageID, + @"UPDATE regionsettings SET block_terraform = :block_terraform ,block_fly = :block_fly ,allow_damage = :allow_damage +,restrict_pushing = :restrict_pushing ,allow_land_resell = :allow_land_resell ,allow_land_join_divide = :allow_land_join_divide +,block_show_in_search = :block_show_in_search ,agent_limit = :agent_limit ,object_bonus = :object_bonus ,maturity = :maturity +,disable_scripts = :disable_scripts ,disable_collisions = :disable_collisions ,disable_physics = :disable_physics +,terrain_texture_1 = :terrain_texture_1 ,terrain_texture_2 = :terrain_texture_2 ,terrain_texture_3 = :terrain_texture_3 +,terrain_texture_4 = :terrain_texture_4 ,elevation_1_nw = :elevation_1_nw ,elevation_2_nw = :elevation_2_nw +,elevation_1_ne = :elevation_1_ne ,elevation_2_ne = :elevation_2_ne ,elevation_1_se = :elevation_1_se ,elevation_2_se = :elevation_2_se +,elevation_1_sw = :elevation_1_sw ,elevation_2_sw = :elevation_2_sw ,water_height = :water_height ,terrain_raise_limit = :terrain_raise_limit +,terrain_lower_limit = :terrain_lower_limit ,use_estate_sun = :use_estate_sun ,fixed_sun = :fixed_sun ,sun_position = :sun_position +,covenant = :covenant ,covenant_datetime = :covenant_datetime, sunvectorx = :sunvectorx, sunvectory = :sunvectory, sunvectorz = :sunvectorz, +""Sandbox"" = :Sandbox, loaded_creation_datetime = :loaded_creation_datetime, loaded_creation_id = :loaded_creation_id, ""map_tile_ID"" = :TerrainImageID, ""TelehubObject"" = :telehubobject, ""parcel_tile_ID"" = :ParcelImageID WHERE ""regionUUID"" = :regionUUID"; @@ -1381,13 +1466,13 @@ namespace OpenSim.Data.PGSQL elevation_2_ne,elevation_1_se,elevation_2_se,elevation_1_sw,elevation_2_sw,water_height,terrain_raise_limit, terrain_lower_limit,use_estate_sun,fixed_sun,sun_position,covenant,covenant_datetime,sunvectorx, sunvectory, sunvectorz, ""Sandbox"", loaded_creation_datetime, loaded_creation_id - ) + ) VALUES (:regionUUID,:block_terraform,:block_fly,:allow_damage,:restrict_pushing,:allow_land_resell,:allow_land_join_divide, :block_show_in_search,:agent_limit,:object_bonus,:maturity,:disable_scripts,:disable_collisions,:disable_physics, :terrain_texture_1,:terrain_texture_2,:terrain_texture_3,:terrain_texture_4,:elevation_1_nw,:elevation_2_nw,:elevation_1_ne, :elevation_2_ne,:elevation_1_se,:elevation_2_se,:elevation_1_sw,:elevation_2_sw,:water_height,:terrain_raise_limit, - :terrain_lower_limit,:use_estate_sun,:fixed_sun,:sun_position,:covenant, :covenant_datetime, :sunvectorx,:sunvectory, + :terrain_lower_limit,:use_estate_sun,:fixed_sun,:sun_position,:covenant, :covenant_datetime, :sunvectorx,:sunvectory, :sunvectorz, :Sandbox, :loaded_creation_datetime, :loaded_creation_id )"; using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) @@ -1515,6 +1600,8 @@ namespace OpenSim.Data.PGSQL newData.SnapshotID = new UUID((Guid)row["SnapshotUUID"]); newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); + newData.Dwell = Convert.ToSingle(row["Dwell"]); + try { @@ -1541,6 +1628,10 @@ namespace OpenSim.Data.PGSQL newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]); newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]); + newData.SeeAVs = Convert.ToBoolean(row["SeeAVs"]); + newData.AnyAVSounds = Convert.ToBoolean(row["AnyAVSounds"]); + newData.GroupAVSounds = Convert.ToBoolean(row["GroupAVSounds"]); + return newData; } @@ -1588,6 +1679,12 @@ namespace OpenSim.Data.PGSQL prim.OwnerID = new UUID((Guid)primRow["OwnerID"]); prim.GroupID = new UUID((Guid)primRow["GroupID"]); prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]); + + if (primRow["RezzerID"] != DBNull.Value) + prim.RezzerID = new UUID((Guid)primRow["RezzerID"]); + else + prim.RezzerID = UUID.Zero; + prim.OwnerMask = Convert.ToUInt32(primRow["OwnerMask"]); prim.NextOwnerMask = Convert.ToUInt32(primRow["NextOwnerMask"]); prim.GroupMask = Convert.ToUInt32(primRow["GroupMask"]); @@ -1692,6 +1789,7 @@ namespace OpenSim.Data.PGSQL prim.CollisionSoundVolume = Convert.ToSingle(primRow["CollisionSoundVolume"]); prim.PassTouches = (bool)primRow["PassTouches"]; + prim.PassCollisions = (bool)primRow["PassCollisions"]; if (!(primRow["MediaURL"] is System.DBNull)) prim.MediaUrl = (string)primRow["MediaURL"]; @@ -1699,13 +1797,20 @@ namespace OpenSim.Data.PGSQL if (!(primRow["DynAttrs"] is System.DBNull) && (string)primRow["DynAttrs"] != "") prim.DynAttrs = DAMap.FromXml((string)primRow["DynAttrs"]); else - prim.DynAttrs = new DAMap(); + prim.DynAttrs = new DAMap(); prim.PhysicsShapeType = Convert.ToByte(primRow["PhysicsShapeType"]); prim.Density = Convert.ToSingle(primRow["Density"]); prim.GravityModifier = Convert.ToSingle(primRow["GravityModifier"]); prim.Friction = Convert.ToSingle(primRow["Friction"]); prim.Restitution = Convert.ToSingle(primRow["Restitution"]); + prim.RotationAxisLocks = Convert.ToByte(primRow["RotationAxisLocks"]); + + + PhysicsInertiaData pdata = null; + if (!(primRow["PhysInertia"] is System.DBNull)) + pdata = PhysicsInertiaData.FromXml2(primRow["PhysInertia"].ToString()); + prim.PhysicsInertia = pdata; return prim; } @@ -1942,6 +2047,17 @@ namespace OpenSim.Data.PGSQL parameters.Add(_Database.CreateParameter("UserLookAtZ", land.UserLookAt.Z)); parameters.Add(_Database.CreateParameter("AuthBuyerID", land.AuthBuyerID)); parameters.Add(_Database.CreateParameter("OtherCleanTime", land.OtherCleanTime)); + parameters.Add(_Database.CreateParameter("Dwell", land.Dwell)); + parameters.Add(_Database.CreateParameter("MediaDescription", land.MediaDescription)); + parameters.Add(_Database.CreateParameter("MediaType", land.MediaType)); + parameters.Add(_Database.CreateParameter("MediaWidth", land.MediaWidth)); + parameters.Add(_Database.CreateParameter("MediaHeight", land.MediaHeight)); + parameters.Add(_Database.CreateParameter("MediaLoop", land.MediaLoop)); + parameters.Add(_Database.CreateParameter("ObscureMusic", land.ObscureMusic)); + parameters.Add(_Database.CreateParameter("ObscureMedia", land.ObscureMedia)); + parameters.Add(_Database.CreateParameter("SeeAVs", land.SeeAVs)); + parameters.Add(_Database.CreateParameter("AnyAVSounds", land.AnyAVSounds)); + parameters.Add(_Database.CreateParameter("GroupAVSounds", land.GroupAVSounds)); return parameters.ToArray(); } @@ -1996,6 +2112,7 @@ namespace OpenSim.Data.PGSQL parameters.Add(_Database.CreateParameter("OwnerID", prim.OwnerID)); parameters.Add(_Database.CreateParameter("GroupID", prim.GroupID)); parameters.Add(_Database.CreateParameter("LastOwnerID", prim.LastOwnerID)); + parameters.Add(_Database.CreateParameter("RezzerID", prim.RezzerID)); parameters.Add(_Database.CreateParameter("OwnerMask", prim.OwnerMask)); parameters.Add(_Database.CreateParameter("NextOwnerMask", prim.NextOwnerMask)); parameters.Add(_Database.CreateParameter("GroupMask", prim.GroupMask)); @@ -2094,28 +2211,47 @@ namespace OpenSim.Data.PGSQL parameters.Add(_Database.CreateParameter("CollisionSound", prim.CollisionSound)); parameters.Add(_Database.CreateParameter("CollisionSoundVolume", prim.CollisionSoundVolume)); + + parameters.Add(_Database.CreateParameter("PassTouches", (bool)prim.PassTouches)); + parameters.Add(_Database.CreateParameter("PassCollisions", (bool)prim.PassCollisions)); + - parameters.Add(_Database.CreateParameter("PassTouches", prim.PassTouches)); + if (prim.PassTouches) + parameters.Add(_Database.CreateParameter("PassTouches", true)); + else + parameters.Add(_Database.CreateParameter("PassTouches", false)); + + if (prim.PassCollisions) + parameters.Add(_Database.CreateParameter("PassCollisions", true)); + else + parameters.Add(_Database.CreateParameter("PassCollisions", false)); parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum)); parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl)); + if (prim.PhysicsInertia != null) + parameters.Add(_Database.CreateParameter("PhysInertia", prim.PhysicsInertia.ToXml2())); + else + parameters.Add(_Database.CreateParameter("PhysInertia", String.Empty)); + + if (prim.DynAttrs.CountNamespaces > 0) parameters.Add(_Database.CreateParameter("DynAttrs", prim.DynAttrs.ToXml())); else parameters.Add(_Database.CreateParameter("DynAttrs", null)); - + parameters.Add(_Database.CreateParameter("PhysicsShapeType", prim.PhysicsShapeType)); parameters.Add(_Database.CreateParameter("Density", (double)prim.Density)); parameters.Add(_Database.CreateParameter("GravityModifier", (double)prim.GravityModifier)); parameters.Add(_Database.CreateParameter("Friction", (double)prim.Friction)); parameters.Add(_Database.CreateParameter("Restitution", (double)prim.Restitution)); + parameters.Add(_Database.CreateParameter("RotationAxisLocks", prim.RotationAxisLocks)); return parameters.ToArray(); } /// - /// Creates the primshape parameters for stroing in DB. + /// Creates the primshape parameters for storing in DB. /// /// Basic data of SceneObjectpart prim. /// The scene group ID. @@ -2227,6 +2363,11 @@ namespace OpenSim.Data.PGSQL } } + public UUID[] GetObjectIDs(UUID regionID) + { + return new UUID[0]; + } + public void SaveExtra(UUID regionID, string name, string value) { } diff --git a/OpenSim/Data/PGSQL/PGSQLUserAccountData.cs b/OpenSim/Data/PGSQL/PGSQLUserAccountData.cs index 0a68b23..64cfff0 100644 --- a/OpenSim/Data/PGSQL/PGSQLUserAccountData.cs +++ b/OpenSim/Data/PGSQL/PGSQLUserAccountData.cs @@ -42,13 +42,13 @@ namespace OpenSim.Data.PGSQL { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + public PGSQLUserAccountData(string connectionString, string realm) : base(connectionString, realm, "UserAccount") { } - - /* + + /* private string m_Realm; private List m_ColumnNames = null; private PGSQLManager m_database; @@ -122,7 +122,7 @@ namespace OpenSim.Data.PGSQL { cmd.Parameters.Add(m_database.CreateParameter("principalID", principalID)); cmd.Parameters.Add(m_database.CreateParameter("scopeID", scopeID)); - + conn.Open(); using (NpgsqlDataReader result = cmd.ExecuteReader()) { @@ -158,8 +158,8 @@ namespace OpenSim.Data.PGSQL } return null; } - - + + public override bool Store(UserAccountData data) { if (data.Data.ContainsKey("PrincipalID")) @@ -214,7 +214,7 @@ namespace OpenSim.Data.PGSQL catch (Exception e){ m_log.ErrorFormat("[USER]: ERROR opened update user {0} ", e.Message); } - + if (conta < 1) { @@ -242,14 +242,14 @@ namespace OpenSim.Data.PGSQL } return true; } - + public bool Store(UserAccountData data, UUID principalID, string token) { return false; } - + public bool SetDataItem(UUID principalID, string item, string value) { string sql = string.Format(@"update {0} set {1} = :{1} where ""UUID"" = :UUID", m_Realm, item); @@ -299,7 +299,7 @@ namespace OpenSim.Data.PGSQL string sql = ""; UUID scope_id; - UUID.TryParse(scopeID.ToString(), out scope_id); + UUID.TryParse(scopeID.ToString(), out scope_id); using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString)) using (NpgsqlCommand cmd = new NpgsqlCommand()) @@ -325,5 +325,10 @@ namespace OpenSim.Data.PGSQL return DoQuery(cmd); } } + + public UserAccountData[] GetUsersWhere(UUID scopeID, string where) + { + return null; + } } } diff --git a/OpenSim/Data/PGSQL/PGSQLUserProfilesData.cs b/OpenSim/Data/PGSQL/PGSQLUserProfilesData.cs index f166976..75a51e2 100644 --- a/OpenSim/Data/PGSQL/PGSQLUserProfilesData.cs +++ b/OpenSim/Data/PGSQL/PGSQLUserProfilesData.cs @@ -412,15 +412,15 @@ namespace OpenSim.Data.PGSQL query = @"WITH upsert AS ( UPDATE userpicks SET pickuuid = :PickId, creatoruuid = :CreatorId, toppick = :TopPick, parceluuid = :ParcelId, - name = :Name, description = :Desc, snapshotuuid = :SnapshotId, ""user"" = :User, - originalname = :Original, simname = :SimName, posglobal = :GlobalPos, - sortorder = :SortOrder, enabled = :Enabled - RETURNING * ) + name = :Name, description = :Desc, snapshotuuid = :SnapshotId, ""user"" = :User, + originalname = :Original, simname = :SimName, posglobal = :GlobalPos, + sortorder = :SortOrder, enabled = :Enabled + RETURNING * ) INSERT INTO userpicks (pickuuid,creatoruuid,toppick,parceluuid,name,description, - snapshotuuid,""user"",originalname,simname,posglobal,sortorder,enabled) + snapshotuuid,""user"",originalname,simname,posglobal,sortorder,enabled) SELECT :PickId,:CreatorId,:TopPick,:ParcelId,:Name,:Desc,:SnapshotId,:User, - :Original,:SimName,:GlobalPos,:SortOrder,:Enabled + :Original,:SimName,:GlobalPos,:SortOrder,:Enabled WHERE NOT EXISTS ( SELECT * FROM upsert )"; diff --git a/OpenSim/Data/PGSQL/PGSQLXAssetData.cs b/OpenSim/Data/PGSQL/PGSQLXAssetData.cs index 4f682f0..1798d20 100644 --- a/OpenSim/Data/PGSQL/PGSQLXAssetData.cs +++ b/OpenSim/Data/PGSQL/PGSQLXAssetData.cs @@ -141,7 +141,7 @@ namespace OpenSim.Data.PGSQL using (NpgsqlCommand cmd = new NpgsqlCommand( @"SELECT name, description, access_time, ""AssetType"", local, temporary, asset_flags, creatorid, data - FROM XAssetsMeta + FROM XAssetsMeta JOIN XAssetsData ON XAssetsMeta.hash = XAssetsData.Hash WHERE id=:ID", dbcon)) { @@ -173,16 +173,18 @@ namespace OpenSim.Data.PGSQL if (m_enableCompression) { - using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress)) + using(MemoryStream ms = new MemoryStream(asset.Data)) + using(GZipStream decompressionStream = new GZipStream(ms, CompressionMode.Decompress)) { - MemoryStream outputStream = new MemoryStream(); - WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue); - // int compressedLength = asset.Data.Length; - asset.Data = outputStream.ToArray(); - - // m_log.DebugFormat( - // "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}", - // asset.ID, asset.Name, asset.Data.Length, compressedLength); + using(MemoryStream outputStream = new MemoryStream()) + { + decompressionStream.CopyTo(outputStream,int.MaxValue); + // int compressedLength = asset.Data.Length; + asset.Data = outputStream.ToArray(); + } + // m_log.DebugFormat( + // "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}", + // asset.ID, asset.Name, asset.Data.Length, compressedLength); } } @@ -223,16 +225,16 @@ namespace OpenSim.Data.PGSQL { assetName = asset.Name.Substring(0, 64); m_log.WarnFormat( - "[XASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", + "[XASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", asset.Name, asset.ID, asset.Name.Length, assetName.Length); } - + string assetDescription = asset.Description; if (asset.Description.Length > 64) { assetDescription = asset.Description.Substring(0, 64); m_log.WarnFormat( - "[XASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", + "[XASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); } @@ -268,8 +270,8 @@ namespace OpenSim.Data.PGSQL where not exists( Select id from XAssetsMeta where id = :ID); update XAssetsMeta - set id = :ID, hash = :Hash, name = :Name, description = :Description, - ""AssetType"" = :AssetType, local = :Local, temporary = :Temporary, create_time = :CreateTime, + set id = :ID, hash = :Hash, name = :Name, description = :Description, + ""AssetType"" = :AssetType, local = :Local, temporary = :Temporary, create_time = :CreateTime, access_time = :AccessTime, asset_flags = :AssetFlags, creatorid = :CreatorID where id = :ID; ", @@ -321,13 +323,13 @@ namespace OpenSim.Data.PGSQL { m_log.ErrorFormat("[XASSET DB]: PGSQL failure creating asset data {0} with name \"{1}\". Error: {2}", asset.FullID, asset.Name, e.Message); - + transaction.Rollback(); - + return; } } - + transaction.Commit(); } } @@ -374,7 +376,7 @@ namespace OpenSim.Data.PGSQL catch (Exception e) { m_log.ErrorFormat( - "[XASSET PGSQL DB]: Failure updating access_time for asset {0} with name {1} : {2}", + "[XASSET PGSQL DB]: Failure updating access_time for asset {0} with name {1} : {2}", assetMetadata.ID, assetMetadata.Name, e.Message); } } @@ -518,40 +520,42 @@ namespace OpenSim.Data.PGSQL using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) { dbcon.Open(); - NpgsqlCommand cmd = new NpgsqlCommand( @"SELECT name, description, access_time, ""AssetType"", temporary, id, asset_flags, creatorid - FROM XAssetsMeta - LIMIT :start, :count", dbcon); - cmd.Parameters.Add(m_database.CreateParameter("start", start)); - cmd.Parameters.Add(m_database.CreateParameter("count", count)); - - try + using(NpgsqlCommand cmd = new NpgsqlCommand(@"SELECT name, description, access_time, ""AssetType"", temporary, id, asset_flags, creatorid + FROM XAssetsMeta + LIMIT :start, :count",dbcon)) { - using (NpgsqlDataReader dbReader = cmd.ExecuteReader()) + cmd.Parameters.Add(m_database.CreateParameter("start",start)); + cmd.Parameters.Add(m_database.CreateParameter("count", count)); + + try { - while (dbReader.Read()) + using (NpgsqlDataReader dbReader = cmd.ExecuteReader()) { - AssetMetadata metadata = new AssetMetadata(); - metadata.Name = (string)dbReader["name"]; - metadata.Description = (string)dbReader["description"]; - metadata.Type = Convert.ToSByte(dbReader["AssetType"]); - metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); - metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); - metadata.FullID = DBGuid.FromDB(dbReader["id"]); - metadata.CreatorID = dbReader["creatorid"].ToString(); + while (dbReader.Read()) + { + AssetMetadata metadata = new AssetMetadata(); + metadata.Name = (string)dbReader["name"]; + metadata.Description = (string)dbReader["description"]; + metadata.Type = Convert.ToSByte(dbReader["AssetType"]); + metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); + metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); + metadata.FullID = DBGuid.FromDB(dbReader["id"]); + metadata.CreatorID = dbReader["creatorid"].ToString(); - // We'll ignore this for now - it appears unused! -// metadata.SHA1 = dbReader["hash"]); + // We'll ignore this for now - it appears unused! + // metadata.SHA1 = dbReader["hash"]); - UpdateAccessTime(metadata, (int)dbReader["access_time"]); + UpdateAccessTime(metadata, (int)dbReader["access_time"]); - retList.Add(metadata); + retList.Add(metadata); + } } } - } - catch (Exception e) - { - m_log.Error("[XASSETS DB]: PGSql failure fetching asset set" + Environment.NewLine + e.ToString()); - } + catch (Exception e) + { + m_log.Error("[XASSETS DB]: PGSql failure fetching asset set" + Environment.NewLine + e.ToString()); + } + } } } diff --git a/OpenSim/Data/PGSQL/PGSQLXInventoryData.cs b/OpenSim/Data/PGSQL/PGSQLXInventoryData.cs index a22b882..4c10ac9 100644 --- a/OpenSim/Data/PGSQL/PGSQLXInventoryData.cs +++ b/OpenSim/Data/PGSQL/PGSQLXInventoryData.cs @@ -174,7 +174,9 @@ namespace OpenSim.Data.PGSQL { using (NpgsqlCommand cmd = new NpgsqlCommand()) { - cmd.CommandText = String.Format(@"select * from inventoryitems where ""avatarID"" = :uuid and ""assetType"" = :type and ""flags"" = 1", m_Realm); +// cmd.CommandText = String.Format(@"select * from inventoryitems where ""avatarID"" = :uuid and ""assetType"" = :type and ""flags"" = 1", m_Realm); + + cmd.CommandText = String.Format(@"select * from inventoryitems where ""avatarID"" = :uuid and ""assetType"" = :type and ""flags"" = 1"); UUID princID = UUID.Zero; UUID.TryParse(principalID, out princID); @@ -194,11 +196,18 @@ namespace OpenSim.Data.PGSQL { using (NpgsqlCommand cmd = new NpgsqlCommand()) { - cmd.CommandText = String.Format(@"select bit_or(""inventoryCurrentPermissions"") as ""inventoryCurrentPermissions"" - from inventoryitems - where ""avatarID"" = :PrincipalID - and ""assetID"" = :AssetID +/* + cmd.CommandText = String.Format(@"select bit_or(""inventoryCurrentPermissions"") as ""inventoryCurrentPermissions"" + from inventoryitems + where ""avatarID"" = :PrincipalID + and ""assetID"" = :AssetID group by ""assetID"" ", m_Realm); +*/ + cmd.CommandText = String.Format(@"select bit_or(""inventoryCurrentPermissions"") as ""inventoryCurrentPermissions"" + from inventoryitems + where ""avatarID""::uuid = :PrincipalID + and ""assetID""::uuid = :AssetID + group by ""assetID"" "); cmd.Parameters.Add(m_database.CreateParameter("PrincipalID", principalID)); cmd.Parameters.Add(m_database.CreateParameter("AssetID", assetID)); diff --git a/OpenSim/Data/PGSQL/Properties/AssemblyInfo.cs b/OpenSim/Data/PGSQL/Properties/AssemblyInfo.cs index 1e88b2c..ad7ffb8 100644 --- a/OpenSim/Data/PGSQL/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/PGSQL/Properties/AssemblyInfo.cs @@ -61,5 +61,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly : AssemblyVersion("0.8.2.*")] +[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] diff --git a/OpenSim/Data/PGSQL/Resources/AgentPrefs.migrations b/OpenSim/Data/PGSQL/Resources/AgentPrefs.migrations new file mode 100644 index 0000000..ca3cca2 --- /dev/null +++ b/OpenSim/Data/PGSQL/Resources/AgentPrefs.migrations @@ -0,0 +1,19 @@ +:VERSION 1 + +BEGIN TRANSACTION; + +CREATE TABLE IF NOT EXISTS "public"."agentprefs" ( + "PrincipalID" uuid NOT NULL, + "AccessPrefs" char(2) NOT NULL DEFAULT 'M'::bpchar COLLATE "default", + "HoverHeight" float8 NOT NULL DEFAULT 0, + "Language" char(5) NOT NULL DEFAULT 'en-us'::bpchar COLLATE "default", + "LanguageIsPublic" bool NOT NULL DEFAULT true, + "PermEveryone" int4 NOT NULL DEFAULT 0, + "PermGroup" int4 NOT NULL DEFAULT 0, + "PermNextOwner" int4 NOT NULL DEFAULT 532480 +) +WITH (OIDS=FALSE); + +ALTER TABLE "public"."agentprefs" ADD PRIMARY KEY ("PrincipalID") NOT DEFERRABLE INITIALLY IMMEDIATE; + +COMMIT; diff --git a/OpenSim/Data/PGSQL/Resources/AuthStore.migrations b/OpenSim/Data/PGSQL/Resources/AuthStore.migrations index a1f5b61..043a8f7 100644 --- a/OpenSim/Data/PGSQL/Resources/AuthStore.migrations +++ b/OpenSim/Data/PGSQL/Resources/AuthStore.migrations @@ -30,3 +30,11 @@ BEGIN TRANSACTION; COMMIT; +:VERSION 3 + +BEGIN TRANSACTION; + +CREATE UNIQUE INDEX auth_pkey ON auth USING btree (uuid); +ALTER TABLE tokens ADD CONSTRAINT "uuid_token" UNIQUE ("uuid","token") NOT DEFERRABLE INITIALLY IMMEDIATE; + +COMMIT; \ No newline at end of file diff --git a/OpenSim/Data/PGSQL/Resources/EstateStore.migrations b/OpenSim/Data/PGSQL/Resources/EstateStore.migrations index 59270f8..5b450aa 100644 --- a/OpenSim/Data/PGSQL/Resources/EstateStore.migrations +++ b/OpenSim/Data/PGSQL/Resources/EstateStore.migrations @@ -1,307 +1,127 @@ -:VERSION 1 +:VERSION 12 BEGIN TRANSACTION; -CREATE TABLE estate_managers( - "EstateID" int NOT NULL Primary Key, - uuid varchar(36) NOT NULL - ); - -CREATE TABLE estate_groups( - "EstateID" int NOT NULL, - uuid varchar(36) NOT NULL - ); - - -CREATE TABLE estate_users( - "EstateID" int NOT NULL, - uuid varchar(36) NOT NULL - ); - - -CREATE TABLE estateban( - "EstateID" int NOT NULL, - "bannedUUID" varchar(36) NOT NULL, - "bannedIp" varchar(16) NOT NULL, - "bannedIpHostMask" varchar(16) NOT NULL, - "bannedNameMask" varchar(64) NULL DEFAULT NULL - ); - -Create Sequence estate_settings_id increment by 100 start with 100; - -CREATE TABLE estate_settings( - "EstateID" integer DEFAULT nextval('estate_settings_id') NOT NULL, - "EstateName" varchar(64) NULL DEFAULT (NULL), - "AbuseEmailToEstateOwner" boolean NOT NULL, - "DenyAnonymous" boolean NOT NULL, - "ResetHomeOnTeleport" boolean NOT NULL, - "FixedSun" boolean NOT NULL, - "DenyTransacted" boolean NOT NULL, - "BlockDwell" boolean NOT NULL, - "DenyIdentified" boolean NOT NULL, - "AllowVoice" boolean NOT NULL, - "UseGlobalTime" boolean NOT NULL, - "PricePerMeter" int NOT NULL, - "TaxFree" boolean NOT NULL, - "AllowDirectTeleport" boolean NOT NULL, - "RedirectGridX" int NOT NULL, - "RedirectGridY" int NOT NULL, - "ParentEstateID" int NOT NULL, - "SunPosition" double precision NOT NULL, - "EstateSkipScripts" boolean NOT NULL, - "BillableFactor" double precision NOT NULL, - "PublicAccess" boolean NOT NULL, - "AbuseEmail" varchar(255) NOT NULL, - "EstateOwner" varchar(36) NOT NULL, - "DenyMinors" boolean NOT NULL - ); - - -CREATE TABLE estate_map( - "RegionID" varchar(36) NOT NULL DEFAULT ('00000000-0000-0000-0000-000000000000'), - "EstateID" int NOT NULL - ); - -COMMIT; - -:VERSION 2 - -BEGIN TRANSACTION; - -CREATE INDEX IX_estate_managers ON estate_managers - ( - "EstateID" - ); - - -CREATE INDEX IX_estate_groups ON estate_groups - ( - "EstateID" - ); - - -CREATE INDEX IX_estate_users ON estate_users - ( - "EstateID" - ); - -COMMIT; - -:VERSION 3 - -BEGIN TRANSACTION; - -CREATE TABLE Tmp_estateban - ( - "EstateID" int NOT NULL, - "bannedUUID" varchar(36) NOT NULL, - "bannedIp" varchar(16) NULL, - "bannedIpHostMask" varchar(16) NULL, - "bannedNameMask" varchar(64) NULL - ); - - INSERT INTO Tmp_estateban ("EstateID", "bannedUUID", "bannedIp", "bannedIpHostMask", "bannedNameMask") - SELECT "EstateID", "bannedUUID", "bannedIp", "bannedIpHostMask", "bannedNameMask" FROM estateban; - -DROP TABLE estateban; - -Alter table Tmp_estateban - rename to estateban; - -CREATE INDEX IX_estateban ON estateban - ( - "EstateID" - ); - -COMMIT; - - -:VERSION 4 - -BEGIN TRANSACTION; - -CREATE TABLE Tmp_estate_managers - ( - "EstateID" int NOT NULL, - uuid uuid NOT NULL - ); - -INSERT INTO Tmp_estate_managers ("EstateID", uuid) - SELECT "EstateID", cast(uuid as uuid) FROM estate_managers; - -DROP TABLE estate_managers; - -Alter table Tmp_estate_managers - rename to estate_managers; - -CREATE INDEX IX_estate_managers ON estate_managers - ( - "EstateID" - ); - -COMMIT; - - -:VERSION 5 - -BEGIN TRANSACTION; - -CREATE TABLE Tmp_estate_groups - ( - "EstateID" int NOT NULL, - uuid uuid NOT NULL - ) ; - - INSERT INTO Tmp_estate_groups ("EstateID", uuid) - SELECT "EstateID", cast(uuid as uuid) FROM estate_groups; - -DROP TABLE estate_groups; - -Alter table Tmp_estate_groups - rename to estate_groups; - -CREATE INDEX IX_estate_groups ON estate_groups - ( - "EstateID" - ); - -COMMIT; - - -:VERSION 6 - -BEGIN TRANSACTION; - -CREATE TABLE Tmp_estate_users - ( - "EstateID" int NOT NULL, - uuid uuid NOT NULL - ); - -INSERT INTO Tmp_estate_users ("EstateID", uuid) - SELECT "EstateID", cast(uuid as uuid) FROM estate_users ; - -DROP TABLE estate_users; - -Alter table Tmp_estate_users - rename to estate_users; - -CREATE INDEX IX_estate_users ON estate_users - ( - "EstateID" - ); - -COMMIT; - - -:VERSION 7 - -BEGIN TRANSACTION; - -CREATE TABLE Tmp_estateban - ( - "EstateID" int NOT NULL, - "bannedUUID" uuid NOT NULL, - "bannedIp" varchar(16) NULL, - "bannedIpHostMask" varchar(16) NULL, - "bannedNameMask" varchar(64) NULL - ); - -INSERT INTO Tmp_estateban ("EstateID", "bannedUUID", "bannedIp", "bannedIpHostMask", "bannedNameMask") - SELECT "EstateID", cast("bannedUUID" as uuid), "bannedIp", "bannedIpHostMask", "bannedNameMask" FROM estateban ; - -DROP TABLE estateban; - -Alter table Tmp_estateban - rename to estateban; - -CREATE INDEX IX_estateban ON estateban - ( - "EstateID" - ); - -COMMIT; - - -:VERSION 8 - -BEGIN TRANSACTION; - -CREATE TABLE Tmp_estate_settings - ( - "EstateID" integer default nextval('estate_settings_id') NOT NULL, - "EstateName" varchar(64) NULL DEFAULT (NULL), - "AbuseEmailToEstateOwner" boolean NOT NULL, - "DenyAnonymous" boolean NOT NULL, - "ResetHomeOnTeleport" boolean NOT NULL, - "FixedSun" boolean NOT NULL, - "DenyTransacted" boolean NOT NULL, - "BlockDwell" boolean NOT NULL, - "DenyIdentified" boolean NOT NULL, - "AllowVoice" boolean NOT NULL, - "UseGlobalTime" boolean NOT NULL, - "PricePerMeter" int NOT NULL, - "TaxFree" boolean NOT NULL, - "AllowDirectTeleport" boolean NOT NULL, - "RedirectGridX" int NOT NULL, - "RedirectGridY" int NOT NULL, - "ParentEstateID" int NOT NULL, - "SunPosition" double precision NOT NULL, - "EstateSkipScripts" boolean NOT NULL, - "BillableFactor" double precision NOT NULL, - "PublicAccess" boolean NOT NULL, - "AbuseEmail" varchar(255) NOT NULL, +-- ---------------------------- +-- Table structure for estate_groups +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "public"."estate_groups" ( + "EstateID" int4 NOT NULL, + "uuid" uuid NOT NULL +) +WITH (OIDS=FALSE); + +-- Indexes structure for table estate_groups +-- ---------------------------- +CREATE INDEX IF NOT EXISTS "ix_estate_groups" ON "public"."estate_groups" USING btree("EstateID" "pg_catalog"."int4_ops" ASC NULLS LAST); + +-- ---------------------------- +-- Table structure for estate_managers +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "public"."estate_managers" ( + "EstateID" int4 NOT NULL, + "uuid" uuid NOT NULL +) +WITH (OIDS=FALSE); + +-- Indexes structure for table estate_managers +-- ---------------------------- +CREATE INDEX IF NOT EXISTS "ix_estate_managers" ON "public"."estate_managers" USING btree("EstateID" "pg_catalog"."int4_ops" ASC NULLS LAST); + +-- ---------------------------- +-- Table structure for estate_map +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "public"."estate_map" ( + "RegionID" uuid NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'::uuid, + "EstateID" int4 NOT NULL +) +WITH (OIDS=FALSE); + +-- Primary key structure for table estate_map +-- ---------------------------- +ALTER TABLE "public"."estate_map" ADD PRIMARY KEY ("RegionID") NOT DEFERRABLE INITIALLY IMMEDIATE; + +-- ---------------------------- +-- Table structure for estate_settings +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "public"."estate_settings" ( + "EstateID" int4 NOT NULL DEFAULT nextval('estate_settings_id'::regclass), + "EstateName" varchar(64) DEFAULT NULL::character varying COLLATE "default", + "AbuseEmailToEstateOwner" bool NOT NULL, + "DenyAnonymous" bool NOT NULL, + "ResetHomeOnTeleport" bool NOT NULL, + "FixedSun" bool NOT NULL, + "DenyTransacted" bool NOT NULL, + "BlockDwell" bool NOT NULL, + "DenyIdentified" bool NOT NULL, + "AllowVoice" bool NOT NULL, + "UseGlobalTime" bool NOT NULL, + "PricePerMeter" int4 NOT NULL, + "TaxFree" bool NOT NULL, + "AllowDirectTeleport" bool NOT NULL, + "RedirectGridX" int4 NOT NULL, + "RedirectGridY" int4 NOT NULL, + "ParentEstateID" int4 NOT NULL, + "SunPosition" float8 NOT NULL, + "EstateSkipScripts" bool NOT NULL, + "BillableFactor" float8 NOT NULL, + "PublicAccess" bool NOT NULL, + "AbuseEmail" varchar(255) NOT NULL COLLATE "default", "EstateOwner" uuid NOT NULL, - "DenyMinors" boolean NOT NULL - ); - -INSERT INTO Tmp_estate_settings ("EstateID", "EstateName", "AbuseEmailToEstateOwner", "DenyAnonymous", "ResetHomeOnTeleport", "FixedSun", "DenyTransacted", "BlockDwell", "DenyIdentified", "AllowVoice", "UseGlobalTime", "PricePerMeter", "TaxFree", "AllowDirectTeleport", "RedirectGridX", "RedirectGridY", "ParentEstateID", "SunPosition", "EstateSkipScripts", "BillableFactor", "PublicAccess", "AbuseEmail", "EstateOwner", "DenyMinors") - SELECT "EstateID", "EstateName", "AbuseEmailToEstateOwner", "DenyAnonymous", "ResetHomeOnTeleport", "FixedSun", "DenyTransacted", "BlockDwell", "DenyIdentified", "AllowVoice", "UseGlobalTime", "PricePerMeter", "TaxFree", "AllowDirectTeleport", "RedirectGridX", "RedirectGridY", "ParentEstateID", "SunPosition", "EstateSkipScripts", "BillableFactor", "PublicAccess", "AbuseEmail", cast("EstateOwner" as uuid), "DenyMinors" FROM estate_settings ; - -DROP TABLE estate_settings; - - -Alter table Tmp_estate_settings - rename to estate_settings; - + "DenyMinors" bool NOT NULL, + "AllowLandmark" bool NOT NULL DEFAULT true, + "AllowParcelChanges" bool NOT NULL DEFAULT true, + "AllowSetHome" bool NOT NULL DEFAULT true +) +WITH (OIDS=FALSE); + +-- Primary key structure for table estate_settings +-- ---------------------------- +ALTER TABLE "public"."estate_settings" ADD PRIMARY KEY ("EstateID") NOT DEFERRABLE INITIALLY IMMEDIATE; + +-- ---------------------------- +-- Table structure for estate_users +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "public"."estate_users" ( + "EstateID" int4 NOT NULL, + "uuid" uuid NOT NULL +) +WITH (OIDS=FALSE); + +-- Indexes structure for table estate_users +-- ---------------------------- +CREATE INDEX IF NOT EXISTS "ix_estate_users" ON "public"."estate_users" USING btree("EstateID" "pg_catalog"."int4_ops" ASC NULLS LAST); + +-- ---------------------------- +-- Table structure for estateban +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "public"."estateban" ( + "EstateID" int4 NOT NULL, + "bannedUUID" uuid NOT NULL, + "bannedIp" varchar(16) COLLATE "default", + "bannedIpHostMask" varchar(16) COLLATE "default", + "bannedNameMask" varchar(64) COLLATE "default" +) +WITH (OIDS=FALSE); -Create index on estate_settings (lower("EstateName")); +-- Indexes structure for table estateban +-- ---------------------------- +CREATE INDEX IF NOT EXISTS "ix_estateban" ON "public"."estateban" USING btree("EstateID" "pg_catalog"."int4_ops" ASC NULLS LAST); COMMIT; +:VERSION 13 -:VERSION 9 - -BEGIN TRANSACTION; - -CREATE TABLE Tmp_estate_map - ( - "RegionID" uuid NOT NULL DEFAULT ('00000000-0000-0000-0000-000000000000'), - "EstateID" int NOT NULL - ); - -INSERT INTO Tmp_estate_map ("RegionID", "EstateID") - SELECT cast("RegionID" as uuid), "EstateID" FROM estate_map ; - -DROP TABLE estate_map; - -Alter table Tmp_estate_map - rename to estate_map; - -COMMIT; + BEGIN TRASACTION; -:VERSION 10 +-- ---------------------------- +-- SEQUENCE estate_settings_id +-- ---------------------------- +CREATE SEQUENCE IF NOT EXISTS "public"."estate_settings_id" + INCREMENT 100 + MINVALUE 1 + MAXVALUE 9223372036854775807 + START 100 + CACHE 1; -BEGIN TRANSACTION; -ALTER TABLE estate_settings ADD COLUMN "AllowLandmark" boolean NOT NULL default true; -ALTER TABLE estate_settings ADD COLUMN "AllowParcelChanges" boolean NOT NULL default true; -ALTER TABLE estate_settings ADD COLUMN "AllowSetHome" boolean NOT NULL default true; COMMIT; - -:VERSION 11 - -Begin transaction; - - -Commit; - diff --git a/OpenSim/Data/PGSQL/Resources/FSAssetStore.migrations b/OpenSim/Data/PGSQL/Resources/FSAssetStore.migrations new file mode 100644 index 0000000..3a072e5 --- /dev/null +++ b/OpenSim/Data/PGSQL/Resources/FSAssetStore.migrations @@ -0,0 +1,14 @@ +:VERSION 1 + +BEGIN TRANSACTION; + +CREATE TABLE fsassets ( + "id" uuid NOT NULL PRIMARY KEY, + "type" integer NOT NULL, + "hash" char(64) NOT NULL, + "create_time" integer NOT NULL DEFAULT '0', + "access_time" integer NOT NULL DEFAULT '0', + "asset_flags" integer NOT NULL DEFAULT '0' +); + +COMMIT; diff --git a/OpenSim/Data/PGSQL/Resources/Presence.migrations b/OpenSim/Data/PGSQL/Resources/Presence.migrations old mode 100644 new mode 100755 diff --git a/OpenSim/Data/PGSQL/Resources/RegionStore.migrations b/OpenSim/Data/PGSQL/Resources/RegionStore.migrations index 1284ce0..fcefb6b 100644 --- a/OpenSim/Data/PGSQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/PGSQL/Resources/RegionStore.migrations @@ -1153,10 +1153,75 @@ ALTER TABLE regionwindlight ALTER COLUMN draw_classic_clouds SET DEFAULT FALSE; COMMIT; -VERSION 41 #-- Change Landlags to bigint +:VERSION 41 #-- Change Landlags to bigint BEGIN TRANSACTION; ALTER TABLE land ALTER "LandFlags" TYPE bigint; COMMIT; + +:VERSION 42 #-- avination fields + +BEGIN TRANSACTION; + +ALTER TABLE prims ADD "PassCollisions" smallint NOT NULL DEFAULT (0); +ALTER TABLE prims ADD "Vehicle" text COLLATE "default"; +ALTER TABLE regionsettings ADD "block_search" smallint NOT NULL DEFAULT (0); +ALTER TABLE regionsettings ADD "casino" smallint NOT NULL DEFAULT (0); +ALTER TABLE land ADD "SeeAVs" smallint NOT NULL DEFAULT (1); +ALTER TABLE land ADD "AnyAVSounds" smallint NOT NULL DEFAULT (1); +ALTER TABLE land ADD "GroupAVSounds" smallint NOT NULL DEFAULT (1); + +COMMIT; + +:VERSION 43 #---- STATUS ROTATION axis locks + +BEGIN TRANSACTION; + +ALTER TABLE prims ADD "RotationAxisLocks" smallint NOT NULL DEFAULT (0); + +COMMIT; + +:VERSION 44 #---- add baked terrain store + +BEGIN TRANSACTION; + +CREATE TABLE bakedterrain + ( + "RegionUUID" uuid NULL, + "Revision" int NULL, + "Heightfield" bytea NULL + ); + +COMMIT; + +:VERSION 45 #---- Add RezzerID filed in table prims + +BEGIN TRANSACTION; + +ALTER TABLE prims ADD "RezzerID" uuid NULL; + +COMMIT; + +:VERSION 46 #---- Add physics inertia data to table prims + +BEGIN TRANSACTION; + +ALTER TABLE prims ADD "PhysInertia" TEXT; + +COMMIT; + + +:VERSION 47 #---- Convert field PassCollisions in table prims to BOOLEAN + +BEGIN TRANSACTION; + +ALTER TABLE "public"."prims" ALTER COLUMN "PassCollisions" DROP DEFAULT; +ALTER TABLE "public"."prims" + ALTER COLUMN "PassCollisions" TYPE BOOLEAN + USING CASE WHEN "PassCollisions" = 0 THEN FALSE + WHEN "PassCollisions" = 1 THEN TRUE + ELSE NULL + END; +COMMIT; diff --git a/OpenSim/Data/PGSQL/Resources/UserAccount.migrations b/OpenSim/Data/PGSQL/Resources/UserAccount.migrations index c785463..31358fa 100644 --- a/OpenSim/Data/PGSQL/Resources/UserAccount.migrations +++ b/OpenSim/Data/PGSQL/Resources/UserAccount.migrations @@ -48,4 +48,10 @@ ALTER TABLE UserAccounts ADD "UserTitle" varchar(64) NOT NULL DEFAULT ''; COMMIT; +:VERSION 5 +BEGIN TRANSACTION; + +ALTER TABLE UserAccounts ADD "active" integer NOT NULL DEFAULT 1; + +COMMIT; diff --git a/OpenSim/Data/PGSQL/Resources/UserProfiles.migrations b/OpenSim/Data/PGSQL/Resources/UserProfiles.migrations index a6bd8ca..26104c0 100644 --- a/OpenSim/Data/PGSQL/Resources/UserProfiles.migrations +++ b/OpenSim/Data/PGSQL/Resources/UserProfiles.migrations @@ -152,4 +152,12 @@ BEGIN; ALTER TABLE usersettings ALTER COLUMN imviaemail SET DATA TYPE boolean USING CASE WHEN false THEN false ELSE true END; -COMMIT; \ No newline at end of file +COMMIT; + +:VERSION 6 # ------------------------------- + +BEGIN TRANSACTION; + +ALTER TABLE userpicks ADD "gatekeeper" varchar(255) COLLATE "default"; + +COMMIT; diff --git a/OpenSim/Data/Properties/AssemblyInfo.cs b/OpenSim/Data/Properties/AssemblyInfo.cs index b1f234b..92c48bc 100644 --- a/OpenSim/Data/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/Properties/AssemblyInfo.cs @@ -61,5 +61,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly : AssemblyVersion("0.8.2.*")] +[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] diff --git a/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs b/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs index d2e62d2..9884f74 100644 --- a/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs @@ -61,5 +61,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly : AssemblyVersion("0.8.2.*")] +[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] diff --git a/OpenSim/Data/SQLite/Resources/AgentPrefs.migrations b/OpenSim/Data/SQLite/Resources/AgentPrefs.migrations index 7e0525d..8c2663e 100644 --- a/OpenSim/Data/SQLite/Resources/AgentPrefs.migrations +++ b/OpenSim/Data/SQLite/Resources/AgentPrefs.migrations @@ -11,7 +11,7 @@ CREATE TABLE `AgentPrefs` ( `PermEveryone` INT(6) NOT NULL DEFAULT 0, `PermGroup` INT(6) NOT NULL DEFAULT 0, `PermNextOwner` INT(6) NOT NULL DEFAULT 532480, - UNIQUE KEY `PrincipalID` (`PrincipalID`), + UNIQUE (`PrincipalID`), PRIMARY KEY(`PrincipalID`)); COMMIT; diff --git a/OpenSim/Data/SQLite/Resources/AssetStore.migrations b/OpenSim/Data/SQLite/Resources/AssetStore.migrations index f20631c..0743c45 100644 --- a/OpenSim/Data/SQLite/Resources/AssetStore.migrations +++ b/OpenSim/Data/SQLite/Resources/AssetStore.migrations @@ -1,66 +1,17 @@ -:VERSION 1 +:VERSION 6 BEGIN TRANSACTION; -CREATE TABLE assets( - UUID varchar(255) primary key, - Name varchar(255), - Description varchar(255), - Type integer, - InvType integer, - Local integer, - Temporary integer, - Data blob); -COMMIT; - -:VERSION 2 - -BEGIN TRANSACTION; - -CREATE TEMPORARY TABLE assets_backup(UUID,Name,Description,Type,Local,Temporary,Data); -INSERT INTO assets_backup SELECT UUID,Name,Description,Type,Local,Temporary,Data FROM assets; -DROP TABLE assets; -CREATE TABLE assets(UUID,Name,Description,Type,Local,Temporary,Data); -INSERT INTO assets SELECT UUID,Name,Description,Type,Local,Temporary,Data FROM assets_backup; -DROP TABLE assets_backup; - -COMMIT; - -:VERSION 3 - -DELETE FROM assets WHERE UUID = 'dc4b9f0bd00845c696a401dd947ac621' - -:VERSION 4 - -BEGIN; - -update assets - set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12) - where UUID not like '%-%'; - -COMMIT; - -:VERSION 5 - -BEGIN TRANSACTION; - -CREATE TEMPORARY TABLE assets_backup(UUID,Name,Description,Type,Local,Temporary,Data); -INSERT INTO assets_backup SELECT UUID,Name,Description,Type,Local,Temporary,Data FROM assets; -DROP TABLE assets; -CREATE TABLE assets( - UUID NOT NULL PRIMARY KEY, - Name, - Description, - Type, - Local, - Temporary, - asset_flags INTEGER NOT NULL DEFAULT 0, - CreatorID varchar(128) default '', - Data); - -INSERT INTO assets(UUID,Name,Description,Type,Local,Temporary,Data) -SELECT UUID,Name,Description,Type,Local,Temporary,Data FROM assets_backup; -DROP TABLE assets_backup; +CREATE TABLE IF NOT EXISTS assets( + UUID NOT NULL PRIMARY KEY, + Name, + Description, + Type, + Local, + Temporary, + asset_flags INTEGER NOT NULL DEFAULT 0, + CreatorID varchar(128) default '', + Data); COMMIT; diff --git a/OpenSim/Data/SQLite/Resources/EstateStore.migrations b/OpenSim/Data/SQLite/Resources/EstateStore.migrations index 0aec49b..37fa1d9 100644 --- a/OpenSim/Data/SQLite/Resources/EstateStore.migrations +++ b/OpenSim/Data/SQLite/Resources/EstateStore.migrations @@ -1,23 +1,27 @@ -:VERSION 6 +:VERSION 10 BEGIN TRANSACTION; -CREATE TABLE estate_groups ( +CREATE TABLE IF NOT EXISTS estate_groups ( EstateID int(10) NOT NULL, uuid char(36) NOT NULL ); +CREATE INDEX estate_groups_estate_id on estate_groups(EstateID); -CREATE TABLE estate_managers ( +CREATE TABLE IF NOT EXISTS estate_managers ( EstateID int(10) NOT NULL, uuid char(36) NOT NULL ); +CREATE INDEX estate_managers_estate_id on estate_managers(EstateID); -CREATE TABLE estate_map ( +CREATE TABLE IF NOT EXISTS estate_map ( RegionID char(36) NOT NULL default '00000000-0000-0000-0000-000000000000', EstateID int(11) NOT NULL ); +CREATE INDEX estate_map_estate_id on estate_map(EstateID); +CREATE UNIQUE INDEX estate_map_region_id on estate_map(RegionID); -CREATE TABLE estate_settings ( +CREATE TABLE IF NOT EXISTS estate_settings ( EstateID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, EstateName varchar(64) default NULL, AbuseEmailToEstateOwner tinyint(4) NOT NULL, @@ -38,60 +42,28 @@ CREATE TABLE estate_settings ( SunPosition double NOT NULL, EstateSkipScripts tinyint(4) NOT NULL, BillableFactor float NOT NULL, - PublicAccess tinyint(4) NOT NULL -); - -insert into estate_settings ( - EstateID,EstateName,AbuseEmailToEstateOwner,DenyAnonymous,ResetHomeOnTeleport,FixedSun,DenyTransacted,BlockDwell,DenyIdentified,AllowVoice,UseGlobalTime,PricePerMeter,TaxFree,AllowDirectTeleport,RedirectGridX,RedirectGridY,ParentEstateID,SunPosition,PublicAccess,EstateSkipScripts,BillableFactor) - values ( 99, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''); -delete from estate_settings; - -CREATE TABLE estate_users ( + PublicAccess tinyint(4) NOT NULL, + AbuseEmail varchar(255) not null default '', + EstateOwner varchar(36) not null default '', + DenyMinors tinyint not null default 0, + AllowLandmark tinyint not null default '1', + AllowParcelChanges tinyint not null default '1', + AllowSetHome tinyint not null default '1'); + +CREATE TABLE IF NOT EXISTS estate_users ( EstateID int(10) NOT NULL, uuid char(36) NOT NULL ); +CREATE INDEX estate_users_estate_id on estate_users(EstateID); -CREATE TABLE estateban ( +CREATE TABLE IF NOT EXISTS estateban ( EstateID int(10) NOT NULL, bannedUUID varchar(36) NOT NULL, bannedIp varchar(16) NOT NULL, bannedIpHostMask varchar(16) NOT NULL, bannedNameMask varchar(64) default NULL ); - CREATE INDEX estate_ban_estate_id on estateban(EstateID); -CREATE INDEX estate_groups_estate_id on estate_groups(EstateID); -CREATE INDEX estate_managers_estate_id on estate_managers(EstateID); -CREATE INDEX estate_map_estate_id on estate_map(EstateID); -CREATE UNIQUE INDEX estate_map_region_id on estate_map(RegionID); -CREATE INDEX estate_users_estate_id on estate_users(EstateID); COMMIT; - -:VERSION 7 - -begin; - -alter table estate_settings add column AbuseEmail varchar(255) not null default ''; - -alter table estate_settings add column EstateOwner varchar(36) not null default ''; - -commit; - -:VERSION 8 - -begin; - -alter table estate_settings add column DenyMinors tinyint not null default 0; - -commit; - -:VERSION 9 - -begin; -alter table estate_settings add column AllowLandmark tinyint not null default '1'; -alter table estate_settings add column AllowParcelChanges tinyint not null default '1'; -alter table estate_settings add column AllowSetHome tinyint not null default '1'; -commit; - diff --git a/OpenSim/Data/SQLite/Resources/InventoryStore.migrations b/OpenSim/Data/SQLite/Resources/InventoryStore.migrations deleted file mode 100644 index 585ac49..0000000 --- a/OpenSim/Data/SQLite/Resources/InventoryStore.migrations +++ /dev/null @@ -1,92 +0,0 @@ -:VERSION 1 - -BEGIN TRANSACTION; - -CREATE TABLE inventoryfolders( - UUID varchar(255) primary key, - name varchar(255), - agentID varchar(255), - parentID varchar(255), - type integer, - version integer); - -CREATE TABLE inventoryitems( - UUID varchar(255) primary key, - assetID varchar(255), - assetType integer, - invType integer, - parentFolderID varchar(255), - avatarID varchar(255), - creatorsID varchar(255), - inventoryName varchar(255), - inventoryDescription varchar(255), - inventoryNextPermissions integer, - inventoryCurrentPermissions integer, - inventoryBasePermissions integer, - inventoryEveryOnePermissions integer, - salePrice integer default 99, - saleType integer default 0, - creationDate integer default 2000, - groupID varchar(255) default '00000000-0000-0000-0000-000000000000', - groupOwned integer default 0, - flags integer default 0); - -COMMIT; - -:VERSION 2 - -BEGIN TRANSACTION; - -create index inventoryfolders_agentid on inventoryfolders(agentid); -create index inventoryfolders_parentid on inventoryfolders(parentid); -create index inventoryitems_parentfolderid on inventoryitems(parentfolderid); -create index inventoryitems_avatarid on inventoryitems(avatarid); - -COMMIT; - -:VERSION 3 - -BEGIN; - -alter table inventoryitems add column inventoryGroupPermissions integer unsigned not null default 0; - -COMMIT; - -:VERSION 4 - -BEGIN; - -update inventoryitems - set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12) - where UUID not like '%-%'; - -update inventoryitems - set assetID = substr(assetID, 1, 8) || "-" || substr(assetID, 9, 4) || "-" || substr(assetID, 13, 4) || "-" || substr(assetID, 17, 4) || "-" || substr(assetID, 21, 12) - where assetID not like '%-%'; - -update inventoryitems - set parentFolderID = substr(parentFolderID, 1, 8) || "-" || substr(parentFolderID, 9, 4) || "-" || substr(parentFolderID, 13, 4) || "-" || substr(parentFolderID, 17, 4) || "-" || substr(parentFolderID, 21, 12) - where parentFolderID not like '%-%'; - -update inventoryitems - set avatarID = substr(avatarID, 1, 8) || "-" || substr(avatarID, 9, 4) || "-" || substr(avatarID, 13, 4) || "-" || substr(avatarID, 17, 4) || "-" || substr(avatarID, 21, 12) - where avatarID not like '%-%'; - -update inventoryitems - set creatorsID = substr(creatorsID, 1, 8) || "-" || substr(creatorsID, 9, 4) || "-" || substr(creatorsID, 13, 4) || "-" || substr(creatorsID, 17, 4) || "-" || substr(creatorsID, 21, 12) - where creatorsID not like '%-%'; - - -update inventoryfolders - set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12) - where UUID not like '%-%'; - -update inventoryfolders - set agentID = substr(agentID, 1, 8) || "-" || substr(agentID, 9, 4) || "-" || substr(agentID, 13, 4) || "-" || substr(agentID, 17, 4) || "-" || substr(agentID, 21, 12) - where agentID not like '%-%'; - -update inventoryfolders - set parentID = substr(parentID, 1, 8) || "-" || substr(parentID, 9, 4) || "-" || substr(parentID, 13, 4) || "-" || substr(parentID, 17, 4) || "-" || substr(parentID, 21, 12) - where parentID not like '%-%'; - -COMMIT; diff --git a/OpenSim/Data/SQLite/Resources/RegionStore.migrations b/OpenSim/Data/SQLite/Resources/RegionStore.migrations index 901068f..fb154cf 100644 --- a/OpenSim/Data/SQLite/Resources/RegionStore.migrations +++ b/OpenSim/Data/SQLite/Resources/RegionStore.migrations @@ -1,56 +1,99 @@ -:VERSION 1 +:VERSION 31 BEGIN TRANSACTION; -CREATE TABLE prims( - UUID varchar(255) primary key, - RegionUUID varchar(255), - ParentID integer, - CreationDate integer, - Name varchar(255), - SceneGroupID varchar(255), - Text varchar(255), - Description varchar(255), - SitName varchar(255), - TouchName varchar(255), - CreatorID varchar(255), - OwnerID varchar(255), - GroupID varchar(255), - LastOwnerID varchar(255), - OwnerMask integer, - NextOwnerMask integer, - GroupMask integer, - EveryoneMask integer, - BaseMask integer, - PositionX float, - PositionY float, - PositionZ float, - GroupPositionX float, - GroupPositionY float, - GroupPositionZ float, - VelocityX float, - VelocityY float, - VelocityZ float, - AngularVelocityX float, - AngularVelocityY float, - AngularVelocityZ float, - AccelerationX float, - AccelerationY float, - AccelerationZ float, - RotationX float, - RotationY float, - RotationZ float, - RotationW float, - ObjectFlags integer, - SitTargetOffsetX float NOT NULL default 0, - SitTargetOffsetY float NOT NULL default 0, - SitTargetOffsetZ float NOT NULL default 0, - SitTargetOrientW float NOT NULL default 0, - SitTargetOrientX float NOT NULL default 0, - SitTargetOrientY float NOT NULL default 0, - SitTargetOrientZ float NOT NULL default 0); - -CREATE TABLE primshapes( +CREATE TABLE IF NOT EXISTS prims( + UUID varchar(255) primary key, + RegionUUID varchar(255), + CreationDate integer, + Name varchar(255), + SceneGroupID varchar(255), + Text varchar(255), + Description varchar(255), + SitName varchar(255), + TouchName varchar(255), + CreatorID varchar(255), + OwnerID varchar(255), + GroupID varchar(255), + LastOwnerID varchar(255), + OwnerMask integer, + NextOwnerMask integer, + GroupMask integer, + EveryoneMask integer, + BaseMask integer, + PositionX float, + PositionY float, + PositionZ float, + GroupPositionX float, + GroupPositionY float, + GroupPositionZ float, + VelocityX float, + VelocityY float, + VelocityZ float, + AngularVelocityX float, + AngularVelocityY float, + AngularVelocityZ float, + AccelerationX float, + AccelerationY float, + AccelerationZ float, + RotationX float, + RotationY float, + RotationZ float, + RotationW float, + ObjectFlags integer, + SitTargetOffsetX float NOT NULL default 0, + SitTargetOffsetY float NOT NULL default 0, + SitTargetOffsetZ float NOT NULL default 0, + SitTargetOrientW float NOT NULL default 0, + SitTargetOrientX float NOT NULL default 0, + SitTargetOrientY float NOT NULL default 0, + SitTargetOrientZ float NOT NULL default 0, + ColorR integer not null default 0, + ColorG integer not null default 0, + ColorB integer not null default 0, + ColorA integer not null default 0, + ClickAction integer not null default 0, + PayPrice integer not null default 0, + PayButton1 integer not null default 0, + PayButton2 integer not null default 0, + PayButton3 integer not null default 0, + PayButton4 integer not null default 0, + LoopedSound varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000', + LoopedSoundGain float NOT NULL default 0, + TextureAnimation string, + ParticleSystem string, + OmegaX float NOT NULL default 0, + OmegaY float NOT NULL default 0, + OmegaZ float NOT NULL default 0, + CameraEyeOffsetX float NOT NULL default 0, + CameraEyeOffsetY float NOT NULL default 0, + CameraEyeOffsetZ float NOT NULL default 0, + CameraAtOffsetX float NOT NULL default 0, + CameraAtOffsetY float NOT NULL default 0, + CameraAtOffsetZ float NOT NULL default 0, + ForceMouselook string NOT NULL default 0, + ScriptAccessPin INTEGER NOT NULL default 0, + AllowedDrop INTEGER NOT NULL default 0, + DieAtEdge string NOT NULL default 0, + SalePrice INTEGER NOT NULL default 0, + SaleType string NOT NULL default 0, + Material INTEGER NOT NULL default 3, + CollisionSound varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000', + CollisionSoundVolume float NOT NULL default 0, + VolumeDetect INTEGER NOT NULL DEFAULT 0, + MediaURL varchar(255), + DynAttrs TEXT, + `PhysicsShapeType` tinyint(4) NOT NULL default '0', + `Density` double NOT NULL default '1000', + `GravityModifier` double NOT NULL default '1', + `Friction` double NOT NULL default '0.6', + `Restitution` double NOT NULL default '0.5', + `KeyframeMotion` blob, + AttachedPosX double default '0', + AttachedPosY double default '0', + AttachedPosZ double default '0'); + +CREATE TABLE IF NOT EXISTS primshapes( UUID varchar(255) primary key, Shape integer, ScaleX float, @@ -76,10 +119,12 @@ CREATE TABLE primshapes( ProfileCurve integer, ProfileHollow integer, Texture blob, - ExtraParams blob, - State Integer NOT NULL default 0); + ExtraParams blob, + State Integer NOT NULL default 0, + Media TEXT, + LastAttachPoint int not null default '0'); -CREATE TABLE primitems( +CREATE TABLE IF NOT EXISTS primitems( itemID varchar(255) primary key, primID varchar(255), assetID varchar(255), @@ -97,14 +142,15 @@ CREATE TABLE primitems( currentPermissions string, basePermissions string, everyonePermissions string, - groupPermissions string); + groupPermissions string, + flags integer not null default 0); -CREATE TABLE terrain( +CREATE TABLE IF NOT EXISTS terrain( RegionUUID varchar(255), Revision integer, Heightfield blob); -CREATE TABLE land( +CREATE TABLE IF NOT EXISTS land( UUID varchar(255) primary key, RegionUUID varchar(255), LocalLandID string, @@ -135,92 +181,30 @@ CREATE TABLE land( UserLocationZ float, UserLookAtX float, UserLookAtY float, - UserLookAtZ float, - AuthbuyerID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000'); - -CREATE TABLE landaccesslist( + UserLookAtZ float, + AuthbuyerID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000', + OtherCleanTime INTEGER NOT NULL default 0, + Dwell INTEGER NOT NULL default 0, + `MediaType` VARCHAR(32) NOT NULL DEFAULT 'none/none', + `MediaDescription` VARCHAR(255) NOT NULL DEFAULT '', + `MediaSize` VARCHAR(16) NOT NULL DEFAULT '0,0', + `MediaLoop` BOOLEAN NOT NULL DEFAULT FALSE, + `ObscureMusic` BOOLEAN NOT NULL DEFAULT FALSE, + `ObscureMedia` BOOLEAN NOT NULL DEFAULT FALSE); + +CREATE TABLE IF NOT EXISTS landaccesslist( LandUUID varchar(255), AccessUUID varchar(255), Flags string); -COMMIT; - -:VERSION 2 - -BEGIN TRANSACTION; - -CREATE TABLE regionban( - regionUUID varchar (255), - bannedUUID varchar (255), - bannedIp varchar (255), - bannedIpHostMask varchar (255) - ); - -COMMIT; - -:VERSION 3 - -BEGIN; - -ALTER TABLE primitems add flags integer not null default 0; - -COMMIT; - -:VERSION 4 - -BEGIN; - -create table regionsettings ( - regionUUID char(36) not null, - block_terraform integer not null, - block_fly integer not null, - allow_damage integer not null, - restrict_pushing integer not null, - allow_land_resell integer not null, - allow_land_join_divide integer not null, - block_show_in_search integer not null, - agent_limit integer not null, - object_bonus float not null, - maturity integer not null, - disable_scripts integer not null, - disable_collisions integer not null, - disable_physics integer not null, - terrain_texture_1 char(36) not null, - terrain_texture_2 char(36) not null, - terrain_texture_3 char(36) not null, - terrain_texture_4 char(36) not null, - elevation_1_nw float not null, - elevation_2_nw float not null, - elevation_1_ne float not null, - elevation_2_ne float not null, - elevation_1_se float not null, - elevation_2_se float not null, - elevation_1_sw float not null, - elevation_2_sw float not null, - water_height float not null, - terrain_raise_limit float not null, - terrain_lower_limit float not null, - use_estate_sun integer not null, - fixed_sun integer not null, - sun_position float not null, - covenant char(36)); - -COMMIT; - -:VERSION 5 - -BEGIN; - -delete from regionsettings; - -COMMIT; - -:VERSION 6 +CREATE TABLE IF NOT EXISTS regionban( + regionUUID varchar (255), + bannedUUID varchar (255), + bannedIp varchar (255), + bannedIpHostMask varchar (255) + ); -BEGIN TRANSACTION; - -drop table regionsettings; -CREATE TABLE regionsettings ( +CREATE TABLE IF NOT EXISTS regionsettings ( regionUUID char(36) NOT NULL, block_terraform int(11) NOT NULL, block_fly int(11) NOT NULL, @@ -254,228 +238,18 @@ CREATE TABLE regionsettings ( fixed_sun int(11) NOT NULL, sun_position float NOT NULL, covenant char(36) default NULL, - sandbox tinyint(4) NOT NULL, + sandbox tinyint(4) NOT NULL, + sunvectorx double NOT NULL default 0, + sunvectory double NOT NULL default 0, + sunvectorz double NOT NULL default 0, + map_tile_ID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000', + covenant_datetime INTEGER NOT NULL default 0, + `TelehubObject` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', PRIMARY KEY (regionUUID) ); -COMMIT; - -:VERSION 9 - -BEGIN; - -ALTER TABLE prims ADD COLUMN ColorR integer not null default 0; -ALTER TABLE prims ADD COLUMN ColorG integer not null default 0; -ALTER TABLE prims ADD COLUMN ColorB integer not null default 0; -ALTER TABLE prims ADD COLUMN ColorA integer not null default 0; - -COMMIT; - -:VERSION 10 - -BEGIN; - -ALTER TABLE prims ADD COLUMN ClickAction INTEGER NOT NULL default 0; - -COMMIT; - -:VERSION 11 - -BEGIN; - -ALTER TABLE prims ADD COLUMN PayPrice INTEGER NOT NULL default 0; -ALTER TABLE prims ADD COLUMN PayButton1 INTEGER NOT NULL default 0; -ALTER TABLE prims ADD COLUMN PayButton2 INTEGER NOT NULL default 0; -ALTER TABLE prims ADD COLUMN PayButton3 INTEGER NOT NULL default 0; -ALTER TABLE prims ADD COLUMN PayButton4 INTEGER NOT NULL default 0; -ALTER TABLE prims ADD COLUMN LoopedSound varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000'; -ALTER TABLE prims ADD COLUMN LoopedSoundGain float NOT NULL default 0; -ALTER TABLE prims ADD COLUMN TextureAnimation string; -ALTER TABLE prims ADD COLUMN ParticleSystem string; -ALTER TABLE prims ADD COLUMN OmegaX float NOT NULL default 0; -ALTER TABLE prims ADD COLUMN OmegaY float NOT NULL default 0; -ALTER TABLE prims ADD COLUMN OmegaZ float NOT NULL default 0; -ALTER TABLE prims ADD COLUMN CameraEyeOffsetX float NOT NULL default 0; -ALTER TABLE prims ADD COLUMN CameraEyeOffsetY float NOT NULL default 0; -ALTER TABLE prims ADD COLUMN CameraEyeOffsetZ float NOT NULL default 0; -ALTER TABLE prims ADD COLUMN CameraAtOffsetX float NOT NULL default 0; -ALTER TABLE prims ADD COLUMN CameraAtOffsetY float NOT NULL default 0; -ALTER TABLE prims ADD COLUMN CameraAtOffsetZ float NOT NULL default 0; -ALTER TABLE prims ADD COLUMN ForceMouselook string NOT NULL default 0; -ALTER TABLE prims ADD COLUMN ScriptAccessPin INTEGER NOT NULL default 0; -ALTER TABLE prims ADD COLUMN AllowedDrop INTEGER NOT NULL default 0; -ALTER TABLE prims ADD COLUMN DieAtEdge string NOT NULL default 0; -ALTER TABLE prims ADD COLUMN SalePrice INTEGER NOT NULL default 0; -ALTER TABLE prims ADD COLUMN SaleType string NOT NULL default 0; - -COMMIT; - -:VERSION 12 - -BEGIN; - -ALTER TABLE prims ADD COLUMN Material INTEGER NOT NULL default 3; - -COMMIT; - -:VERSION 13 - -BEGIN; - -ALTER TABLE land ADD COLUMN OtherCleanTime INTEGER NOT NULL default 0; -ALTER TABLE land ADD COLUMN Dwell INTEGER NOT NULL default 0; - -COMMIT; - -:VERSION 14 - -begin; - -ALTER TABLE regionsettings ADD COLUMN sunvectorx double NOT NULL default 0; -ALTER TABLE regionsettings ADD COLUMN sunvectory double NOT NULL default 0; -ALTER TABLE regionsettings ADD COLUMN sunvectorz double NOT NULL default 0; - -commit; - -:VERSION 15 - -BEGIN; - -ALTER TABLE prims ADD COLUMN CollisionSound varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000'; -ALTER TABLE prims ADD COLUMN CollisionSoundVolume float NOT NULL default 0; - -COMMIT; - -:VERSION 16 - -BEGIN; - -ALTER TABLE prims ADD COLUMN VolumeDetect INTEGER NOT NULL DEFAULT 0; - -COMMIT; - -:VERSION 17 - -BEGIN; -CREATE TEMPORARY TABLE prims_backup(UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect); -INSERT INTO prims_backup SELECT UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect FROM prims; -DROP TABLE prims; -CREATE TABLE prims(UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect); -INSERT INTO prims SELECT UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect FROM prims_backup; -DROP TABLE prims_backup; -COMMIT; - -:VERSION 18 - -BEGIN; - -update terrain - set RegionUUID = substr(RegionUUID, 1, 8) || "-" || substr(RegionUUID, 9, 4) || "-" || substr(RegionUUID, 13, 4) || "-" || substr(RegionUUID, 17, 4) || "-" || substr(RegionUUID, 21, 12) - where RegionUUID not like '%-%'; - - -update landaccesslist - set LandUUID = substr(LandUUID, 1, 8) || "-" || substr(LandUUID, 9, 4) || "-" || substr(LandUUID, 13, 4) || "-" || substr(LandUUID, 17, 4) || "-" || substr(LandUUID, 21, 12) - where LandUUID not like '%-%'; - -update landaccesslist - set AccessUUID = substr(AccessUUID, 1, 8) || "-" || substr(AccessUUID, 9, 4) || "-" || substr(AccessUUID, 13, 4) || "-" || substr(AccessUUID, 17, 4) || "-" || substr(AccessUUID, 21, 12) - where AccessUUID not like '%-%'; - - -update prims - set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12) - where UUID not like '%-%'; - -update prims - set RegionUUID = substr(RegionUUID, 1, 8) || "-" || substr(RegionUUID, 9, 4) || "-" || substr(RegionUUID, 13, 4) || "-" || substr(RegionUUID, 17, 4) || "-" || substr(RegionUUID, 21, 12) - where RegionUUID not like '%-%'; - -update prims - set SceneGroupID = substr(SceneGroupID, 1, 8) || "-" || substr(SceneGroupID, 9, 4) || "-" || substr(SceneGroupID, 13, 4) || "-" || substr(SceneGroupID, 17, 4) || "-" || substr(SceneGroupID, 21, 12) - where SceneGroupID not like '%-%'; - -update prims - set CreatorID = substr(CreatorID, 1, 8) || "-" || substr(CreatorID, 9, 4) || "-" || substr(CreatorID, 13, 4) || "-" || substr(CreatorID, 17, 4) || "-" || substr(CreatorID, 21, 12) - where CreatorID not like '%-%'; - -update prims - set OwnerID = substr(OwnerID, 1, 8) || "-" || substr(OwnerID, 9, 4) || "-" || substr(OwnerID, 13, 4) || "-" || substr(OwnerID, 17, 4) || "-" || substr(OwnerID, 21, 12) - where OwnerID not like '%-%'; - -update prims - set GroupID = substr(GroupID, 1, 8) || "-" || substr(GroupID, 9, 4) || "-" || substr(GroupID, 13, 4) || "-" || substr(GroupID, 17, 4) || "-" || substr(GroupID, 21, 12) - where GroupID not like '%-%'; - -update prims - set LastOwnerID = substr(LastOwnerID, 1, 8) || "-" || substr(LastOwnerID, 9, 4) || "-" || substr(LastOwnerID, 13, 4) || "-" || substr(LastOwnerID, 17, 4) || "-" || substr(LastOwnerID, 21, 12) - where LastOwnerID not like '%-%'; - - -update primshapes - set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12) - where UUID not like '%-%'; - - -update land - set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12) - where UUID not like '%-%'; - -update land - set RegionUUID = substr(RegionUUID, 1, 8) || "-" || substr(RegionUUID, 9, 4) || "-" || substr(RegionUUID, 13, 4) || "-" || substr(RegionUUID, 17, 4) || "-" || substr(RegionUUID, 21, 12) - where RegionUUID not like '%-%'; - -update land - set OwnerUUID = substr(OwnerUUID, 1, 8) || "-" || substr(OwnerUUID, 9, 4) || "-" || substr(OwnerUUID, 13, 4) || "-" || substr(OwnerUUID, 17, 4) || "-" || substr(OwnerUUID, 21, 12) - where OwnerUUID not like '%-%'; - -update land - set GroupUUID = substr(GroupUUID, 1, 8) || "-" || substr(GroupUUID, 9, 4) || "-" || substr(GroupUUID, 13, 4) || "-" || substr(GroupUUID, 17, 4) || "-" || substr(GroupUUID, 21, 12) - where GroupUUID not like '%-%'; - -update land - set MediaTextureUUID = substr(MediaTextureUUID, 1, 8) || "-" || substr(MediaTextureUUID, 9, 4) || "-" || substr(MediaTextureUUID, 13, 4) || "-" || substr(MediaTextureUUID, 17, 4) || "-" || substr(MediaTextureUUID, 21, 12) - where MediaTextureUUID not like '%-%'; - -update land - set SnapshotUUID = substr(SnapshotUUID, 1, 8) || "-" || substr(SnapshotUUID, 9, 4) || "-" || substr(SnapshotUUID, 13, 4) || "-" || substr(SnapshotUUID, 17, 4) || "-" || substr(SnapshotUUID, 21, 12) - where SnapshotUUID not like '%-%'; - -update land - set AuthbuyerID = substr(AuthbuyerID, 1, 8) || "-" || substr(AuthbuyerID, 9, 4) || "-" || substr(AuthbuyerID, 13, 4) || "-" || substr(AuthbuyerID, 17, 4) || "-" || substr(AuthbuyerID, 21, 12) - where AuthbuyerID not like '%-%'; - -COMMIT; - -:VERSION 19 -BEGIN; -ALTER TABLE regionsettings ADD COLUMN map_tile_ID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000'; -COMMIT; - -:VERSION 20 -BEGIN; -ALTER TABLE prims ADD COLUMN MediaURL varchar(255); -ALTER TABLE primshapes ADD COLUMN Media TEXT; -COMMIT; - -:VERSION 21 -BEGIN; -ALTER TABLE `land` ADD COLUMN `MediaType` VARCHAR(32) NOT NULL DEFAULT 'none/none'; -ALTER TABLE `land` ADD COLUMN `MediaDescription` VARCHAR(255) NOT NULL DEFAULT ''; -ALTER TABLE `land` ADD COLUMN `MediaSize` VARCHAR(16) NOT NULL DEFAULT '0,0'; -ALTER TABLE `land` ADD COLUMN `MediaLoop` BOOLEAN NOT NULL DEFAULT FALSE; -ALTER TABLE `land` ADD COLUMN `ObscureMusic` BOOLEAN NOT NULL DEFAULT FALSE; -ALTER TABLE `land` ADD COLUMN `ObscureMedia` BOOLEAN NOT NULL DEFAULT FALSE; -COMMIT; - -:VERSION 22 -BEGIN; -ALTER TABLE regionsettings ADD COLUMN covenant_datetime INTEGER NOT NULL default 0; -COMMIT; - -:VERSION 23 -BEGIN; -CREATE TABLE regionwindlight ( +CREATE TABLE IF NOT EXISTS regionwindlight ( region_id VARCHAR(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000' PRIMARY KEY, water_color_r FLOAT NOT NULL DEFAULT '4.000000', water_color_g FLOAT NOT NULL DEFAULT '38.000000', @@ -541,13 +315,6 @@ CREATE TABLE regionwindlight ( cloud_scroll_y_lock INTEGER NOT NULL DEFAULT '0', draw_classic_clouds INTEGER NOT NULL DEFAULT '1'); -COMMIT; - - -:VERSION 24 - -BEGIN; - CREATE TABLE IF NOT EXISTS `spawn_points` ( `RegionID` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000', `Yaw` float NOT NULL, @@ -555,60 +322,58 @@ CREATE TABLE IF NOT EXISTS `spawn_points` ( `Distance` float NOT NULL ); -ALTER TABLE `regionsettings` ADD COLUMN `TelehubObject` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; +CREATE TABLE IF NOT EXISTS `regionenvironment` ( + `region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000' PRIMARY KEY, + `llsd_settings` TEXT NOT NULL +); COMMIT; -:VERSION 25 - -BEGIN; -ALTER TABLE `regionsettings` ADD COLUMN `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; -COMMIT; -:VERSION 26 +:VERSION 32 #---- avination fields plus a few others BEGIN; -CREATE TABLE `regionenvironment` ( - `region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000' PRIMARY KEY, - `llsd_settings` TEXT NOT NULL -); +ALTER TABLE `prims` ADD COLUMN `PassTouches` BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE `prims` ADD COLUMN `PassCollisions`BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE `prims` ADD COLUMN `Vehicle` TEXT default NULL; +ALTER TABLE `regionsettings` ADD COLUMN `block_search` BOOLEAN NOT NULL DEFAULT FALSE;; +ALTER TABLE `regionsettings` ADD COLUMN `casino` BOOLEAN NOT NULL DEFAULT FALSE;; +ALTER TABLE `land` ADD COLUMN `SeeAVs` BOOLEAN NOT NULL DEFAULT TRUE; +ALTER TABLE `land` ADD COLUMN `AnyAVSounds` BOOLEAN NOT NULL DEFAULT TRUE; +ALTER TABLE `land` ADD COLUMN `GroupAVSounds` BOOLEAN NOT NULL DEFAULT TRUE; COMMIT; -:VERSION 27 -BEGIN; -ALTER TABLE prims ADD COLUMN DynAttrs TEXT; -COMMIT; - -:VERSION 28 +:VERSION 33 #---- Rotation axis locks BEGIN; -ALTER TABLE prims ADD COLUMN `PhysicsShapeType` tinyint(4) NOT NULL default '0'; -ALTER TABLE prims ADD COLUMN `Density` double NOT NULL default '1000'; -ALTER TABLE prims ADD COLUMN `GravityModifier` double NOT NULL default '1'; -ALTER TABLE prims ADD COLUMN `Friction` double NOT NULL default '0.6'; -ALTER TABLE prims ADD COLUMN `Restitution` double NOT NULL default '0.5'; +ALTER TABLE prims ADD COLUMN `RotationAxisLocks` tinyint(4) NOT NULL default '0'; COMMIT; -:VERSION 29 #---------------- Keyframes +:VERSION 34 #---- add baked terrain store BEGIN; -ALTER TABLE prims ADD COLUMN `KeyframeMotion` blob; +CREATE TABLE IF NOT EXISTS bakedterrain( + RegionUUID varchar(255), + Revision integer, + Heightfield blob); COMMIT; -:VERSION 30 #---------------- Save Attachment info +:VERSION 35 #----- Add RezzerID field in table prims BEGIN; -ALTER TABLE prims ADD COLUMN AttachedPosX double default '0'; -ALTER TABLE prims ADD COLUMN AttachedPosY double default '0'; -ALTER TABLE prims ADD COLUMN AttachedPosZ double default '0'; -ALTER TABLE primshapes ADD COLUMN LastAttachPoint int not null default '0'; +ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL; COMMIT; +:VERSION 36 #----- Add physics inertia data + +BEGIN; +ALTER TABLE `prims` ADD COLUMN `PhysInertia` TEXT default NULL; +COMMIT; diff --git a/OpenSim/Data/SQLite/Resources/UserAccount.migrations b/OpenSim/Data/SQLite/Resources/UserAccount.migrations index 854fe69..f37a222 100644 --- a/OpenSim/Data/SQLite/Resources/UserAccount.migrations +++ b/OpenSim/Data/SQLite/Resources/UserAccount.migrations @@ -25,3 +25,11 @@ BEGIN TRANSACTION; INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created) SELECT `UUID` AS PrincipalID, '00000000-0000-0000-0000-000000000000' AS ScopeID, username AS FirstName, surname AS LastName, '' as Email, '' AS ServiceURLs, created as Created FROM users; COMMIT; + +:VERSION 3 # ------------------------- + +BEGIN; + +ALTER TABLE `UserAccounts` ADD `active` BOOLEAN NOT NULL DEFAULT TRUE; + +COMMIT; \ No newline at end of file diff --git a/OpenSim/Data/SQLite/Resources/UserProfiles.migrations b/OpenSim/Data/SQLite/Resources/UserProfiles.migrations index 86434e8..207dde0 100644 --- a/OpenSim/Data/SQLite/Resources/UserProfiles.migrations +++ b/OpenSim/Data/SQLite/Resources/UserProfiles.migrations @@ -99,4 +99,4 @@ CREATE TABLE IF NOT EXISTS usersettings ( email varchar(254) NOT NULL, PRIMARY KEY (useruuid) ) -commit; \ No newline at end of file +commit; diff --git a/OpenSim/Data/SQLite/Resources/UserStore.migrations b/OpenSim/Data/SQLite/Resources/UserStore.migrations deleted file mode 100644 index 73d35e8..0000000 --- a/OpenSim/Data/SQLite/Resources/UserStore.migrations +++ /dev/null @@ -1,169 +0,0 @@ -:VERSION 1 - -BEGIN TRANSACTION; - --- users table -CREATE TABLE users( - UUID varchar(255) primary key, - username varchar(255), - surname varchar(255), - passwordHash varchar(255), - passwordSalt varchar(255), - homeRegionX integer, - homeRegionY integer, - homeLocationX float, - homeLocationY float, - homeLocationZ float, - homeLookAtX float, - homeLookAtY float, - homeLookAtZ float, - created integer, - lastLogin integer, - rootInventoryFolderID varchar(255), - userInventoryURI varchar(255), - userAssetURI varchar(255), - profileCanDoMask integer, - profileWantDoMask integer, - profileAboutText varchar(255), - profileFirstText varchar(255), - profileImage varchar(255), - profileFirstImage varchar(255), - webLoginKey text default '00000000-0000-0000-0000-000000000000'); --- friends table -CREATE TABLE userfriends( - ownerID varchar(255), - friendID varchar(255), - friendPerms integer, - ownerPerms integer, - datetimestamp integer); - -COMMIT; - -:VERSION 2 - -BEGIN; - -ALTER TABLE users add homeRegionID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000'; - -COMMIT; - -:VERSION 3 - -BEGIN; - -ALTER TABLE users add userFlags integer NOT NULL default 0; -ALTER TABLE users add godLevel integer NOT NULL default 0; - -COMMIT; - -:VERSION 4 - -BEGIN; - -ALTER TABLE users add customType varchar(32) not null default ''; -ALTER TABLE users add partner char(36) not null default '00000000-0000-0000-0000-000000000000'; - -COMMIT; - -:VERSION 5 - -BEGIN; - -CREATE TABLE `avatarattachments` (`UUID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', `attachpoint` int(11) NOT NULL DEFAULT 0, `item` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', `asset` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'); - -COMMIT; - -:VERSION 6 - -BEGIN TRANSACTION; - --- usersagents table -CREATE TABLE IF NOT EXISTS useragents( - UUID varchar(255) primary key, - agentIP varchar(255), - agentPort integer, - agentOnline boolean, - sessionID varchar(255), - secureSessionID varchar(255), - regionID varchar(255), - loginTime integer, - logoutTime integer, - currentRegion varchar(255), - currentHandle varchar(255), - currentPosX float, - currentPosY float, - currentPosZ float); - -COMMIT; - -:VERSION 7 - -BEGIN TRANSACTION; - -ALTER TABLE useragents add currentLookAtX float not null default 128; -ALTER TABLE useragents add currentLookAtY float not null default 128; -ALTER TABLE useragents add currentLookAtZ float not null default 70; - -COMMIT; - -:VERSION 8 - -BEGIN TRANSACTION; - -ALTER TABLE users add email varchar(250); - -COMMIT; - -:VERSION 9 - -BEGIN; - -update users - set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12) - where UUID not like '%-%'; - -update useragents - set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12) - where UUID not like '%-%'; - -COMMIT; - -:VERSION 10 - -BEGIN TRANSACTION; - -CREATE TABLE IF NOT EXISTS avatarappearance( - Owner varchar(36) NOT NULL primary key, - BodyItem varchar(36) DEFAULT NULL, - BodyAsset varchar(36) DEFAULT NULL, - SkinItem varchar(36) DEFAULT NULL, - SkinAsset varchar(36) DEFAULT NULL, - HairItem varchar(36) DEFAULT NULL, - HairAsset varchar(36) DEFAULT NULL, - EyesItem varchar(36) DEFAULT NULL, - EyesAsset varchar(36) DEFAULT NULL, - ShirtItem varchar(36) DEFAULT NULL, - ShirtAsset varchar(36) DEFAULT NULL, - PantsItem varchar(36) DEFAULT NULL, - PantsAsset varchar(36) DEFAULT NULL, - ShoesItem varchar(36) DEFAULT NULL, - ShoesAsset varchar(36) DEFAULT NULL, - SocksItem varchar(36) DEFAULT NULL, - SocksAsset varchar(36) DEFAULT NULL, - JacketItem varchar(36) DEFAULT NULL, - JacketAsset varchar(36) DEFAULT NULL, - GlovesItem varchar(36) DEFAULT NULL, - GlovesAsset varchar(36) DEFAULT NULL, - UnderShirtItem varchar(36) DEFAULT NULL, - UnderShirtAsset varchar(36) DEFAULT NULL, - UnderPantsItem varchar(36) DEFAULT NULL, - UnderPantsAsset varchar(36) DEFAULT NULL, - SkirtItem varchar(36) DEFAULT NULL, - SkirtAsset varchar(36) DEFAULT NULL, - Texture blob, - VisualParams blob, - Serial int DEFAULT NULL, - AvatarHeight float DEFAULT NULL -); - -COMMIT; diff --git a/OpenSim/Data/SQLite/SQLiteAssetData.cs b/OpenSim/Data/SQLite/SQLiteAssetData.cs index 30b26c4..966d0b8 100644 --- a/OpenSim/Data/SQLite/SQLiteAssetData.cs +++ b/OpenSim/Data/SQLite/SQLiteAssetData.cs @@ -86,7 +86,7 @@ namespace OpenSim.Data.SQLite if (dbconnect == string.Empty) { - dbconnect = "URI=file:../db/Asset.db,version=3"; + dbconnect = "URI=file:Asset.db,version=3"; } m_conn = new SqliteConnection(dbconnect); m_conn.Open(); @@ -131,14 +131,14 @@ namespace OpenSim.Data.SQLite /// Create an asset /// /// Asset Base - override public void StoreAsset(AssetBase asset) + override public bool StoreAsset(AssetBase asset) { string assetName = asset.Name; if (asset.Name.Length > AssetBase.MAX_ASSET_NAME) { assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME); m_log.WarnFormat( - "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", + "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", asset.Name, asset.ID, asset.Name.Length, assetName.Length); } @@ -147,7 +147,7 @@ namespace OpenSim.Data.SQLite { assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC); m_log.WarnFormat( - "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", + "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); } @@ -171,6 +171,7 @@ namespace OpenSim.Data.SQLite cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); cmd.ExecuteNonQuery(); + return true; } } } @@ -191,6 +192,7 @@ namespace OpenSim.Data.SQLite cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); cmd.ExecuteNonQuery(); + return true; } } } @@ -358,7 +360,7 @@ namespace OpenSim.Data.SQLite /// override public void Initialise() { - Initialise("URI=file:../db/Asset.db,version=3"); + Initialise("URI=file:Asset.db,version=3"); } /// diff --git a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs index 0428c11..8fb955c 100644 --- a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs +++ b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs @@ -45,7 +45,7 @@ namespace OpenSim.Data.SQLite public class SQLiteAuthenticationData : SQLiteFramework, IAuthenticationData { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + private string m_Realm; private List m_ColumnNames; private int m_LastExpire; @@ -223,7 +223,7 @@ namespace OpenSim.Data.SQLite if (System.Environment.TickCount - m_LastExpire > 30000) DoExpire(); - using (SqliteCommand cmd = new SqliteCommand("insert into tokens (UUID, token, validity) values ('" + principalID.ToString() + + using (SqliteCommand cmd = new SqliteCommand("insert into tokens (UUID, token, validity) values ('" + principalID.ToString() + "', '" + token + "', datetime('now', 'localtime', '+" + lifetime.ToString() + " minutes'))")) { if (ExecuteNonQuery(cmd, m_Connection) > 0) @@ -238,7 +238,7 @@ namespace OpenSim.Data.SQLite if (System.Environment.TickCount - m_LastExpire > 30000) DoExpire(); - using (SqliteCommand cmd = new SqliteCommand("update tokens set validity = datetime('now', 'localtime', '+" + lifetime.ToString() + + using (SqliteCommand cmd = new SqliteCommand("update tokens set validity = datetime('now', 'localtime', '+" + lifetime.ToString() + " minutes') where UUID = '" + principalID.ToString() + "' and token = '" + token + "' and validity > datetime('now', 'localtime')")) { if (ExecuteNonQuery(cmd, m_Connection) > 0) diff --git a/OpenSim/Data/SQLite/SQLiteEstateData.cs b/OpenSim/Data/SQLite/SQLiteEstateData.cs index d51f2d4..0fcab21 100644 --- a/OpenSim/Data/SQLite/SQLiteEstateData.cs +++ b/OpenSim/Data/SQLite/SQLiteEstateData.cs @@ -190,7 +190,7 @@ namespace OpenSim.Data.SQLite IDataReader r = null; using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) - { + { names.Remove("EstateID"); string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")"; @@ -386,15 +386,15 @@ namespace OpenSim.Data.SQLite return DoLoad(cmd, UUID.Zero, false); } } - + public List LoadEstateSettingsAll() { List estateSettings = new List(); - + List estateIds = GetEstatesAll(); foreach (int estateId in estateIds) estateSettings.Add(LoadEstateSettings(estateId)); - + return estateSettings; } @@ -421,7 +421,7 @@ namespace OpenSim.Data.SQLite return result; } - + public List GetEstatesAll() { List result = new List(); @@ -442,7 +442,7 @@ namespace OpenSim.Data.SQLite } r.Close(); - return result; + return result; } public List GetEstatesByOwner(UUID ownerID) diff --git a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs index 9fbeb10..a4b84b1 100644 --- a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs +++ b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs @@ -189,7 +189,7 @@ namespace OpenSim.Data.SQLite m_Fields[name].SetValue(row, reader[name]); } } - + if (m_DataField != null) { Dictionary data = @@ -268,7 +268,7 @@ namespace OpenSim.Data.SQLite public virtual bool Delete(string field, string key) { return Delete(new string[] { field }, new string[] { key }); - } + } public virtual bool Delete(string[] fields, string[] keys) { diff --git a/OpenSim/Data/SQLite/SQLiteGridUserData.cs b/OpenSim/Data/SQLite/SQLiteGridUserData.cs index d8c52f8..987240c 100644 --- a/OpenSim/Data/SQLite/SQLiteGridUserData.cs +++ b/OpenSim/Data/SQLite/SQLiteGridUserData.cs @@ -43,7 +43,7 @@ namespace OpenSim.Data.SQLite { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public SQLiteGridUserData(string connectionString, string realm) + public SQLiteGridUserData(string connectionString, string realm) : base(connectionString, realm, "GridUserStore") {} public new GridUserData Get(string userID) diff --git a/OpenSim/Data/SQLite/SQLiteHGTravelData.cs b/OpenSim/Data/SQLite/SQLiteHGTravelData.cs index db288b2..dd34710 100644 --- a/OpenSim/Data/SQLite/SQLiteHGTravelData.cs +++ b/OpenSim/Data/SQLite/SQLiteHGTravelData.cs @@ -44,7 +44,7 @@ namespace OpenSim.Data.SQLite { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public SQLiteHGTravelData(string connectionString, string realm) + public SQLiteHGTravelData(string connectionString, string realm) : base(connectionString, realm, "HGTravelStore") {} public HGTravelingData Get(UUID sessionID) diff --git a/OpenSim/Data/SQLite/SQLiteInventoryStore.cs b/OpenSim/Data/SQLite/SQLiteInventoryStore.cs deleted file mode 100644 index 7caf347..0000000 --- a/OpenSim/Data/SQLite/SQLiteInventoryStore.cs +++ /dev/null @@ -1,916 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Data; -using System.Reflection; -using log4net; -#if CSharpSqlite - using Community.CsharpSqlite.Sqlite; -#else - using Mono.Data.Sqlite; -#endif -using OpenMetaverse; -using OpenSim.Framework; - -namespace OpenSim.Data.SQLite -{ - /// - /// An Inventory Interface to the SQLite database - /// - public class SQLiteInventoryStore : SQLiteUtil, IInventoryDataPlugin - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private const string invItemsSelect = "select * from inventoryitems"; - private const string invFoldersSelect = "select * from inventoryfolders"; - - private static SqliteConnection conn; - private static DataSet ds; - private static SqliteDataAdapter invItemsDa; - private static SqliteDataAdapter invFoldersDa; - - private static bool m_Initialized = false; - - public void Initialise() - { - m_log.Info("[SQLiteInventoryData]: " + Name + " cannot be default-initialized!"); - throw new PluginNotInitialisedException(Name); - } - - /// - /// - /// Initialises Inventory interface - /// Loads and initialises a new SQLite connection and maintains it. - /// use default URI if connect string string is empty. - /// - /// - /// connect string - public void Initialise(string dbconnect) - { - if (!m_Initialized) - { - m_Initialized = true; - - if (Util.IsWindows()) - Util.LoadArchSpecificWindowsDll("sqlite3.dll"); - - if (dbconnect == string.Empty) - { - dbconnect = "URI=file:../db/inventoryStore.db,version=3"; - } - m_log.Info("[INVENTORY DB]: Sqlite - connecting: " + dbconnect); - conn = new SqliteConnection(dbconnect); - - conn.Open(); - - Assembly assem = GetType().Assembly; - Migration m = new Migration(conn, assem, "InventoryStore"); - m.Update(); - - SqliteCommand itemsSelectCmd = new SqliteCommand(invItemsSelect, conn); - invItemsDa = new SqliteDataAdapter(itemsSelectCmd); - // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa); - - SqliteCommand foldersSelectCmd = new SqliteCommand(invFoldersSelect, conn); - invFoldersDa = new SqliteDataAdapter(foldersSelectCmd); - - ds = new DataSet(); - - ds.Tables.Add(createInventoryFoldersTable()); - invFoldersDa.Fill(ds.Tables["inventoryfolders"]); - setupFoldersCommands(invFoldersDa, conn); - CreateDataSetMapping(invFoldersDa, "inventoryfolders"); - m_log.Info("[INVENTORY DB]: Populated Inventory Folders Definitions"); - - ds.Tables.Add(createInventoryItemsTable()); - invItemsDa.Fill(ds.Tables["inventoryitems"]); - setupItemsCommands(invItemsDa, conn); - CreateDataSetMapping(invItemsDa, "inventoryitems"); - m_log.Info("[INVENTORY DB]: Populated Inventory Items Definitions"); - - ds.AcceptChanges(); - } - } - - /// - /// Closes the inventory interface - /// - public void Dispose() - { - if (conn != null) - { - conn.Close(); - conn = null; - } - if (invItemsDa != null) - { - invItemsDa.Dispose(); - invItemsDa = null; - } - if (invFoldersDa != null) - { - invFoldersDa.Dispose(); - invFoldersDa = null; - } - if (ds != null) - { - ds.Dispose(); - ds = null; - } - } - - /// - /// - /// - /// - /// - public InventoryItemBase buildItem(DataRow row) - { - InventoryItemBase item = new InventoryItemBase(); - item.ID = new UUID((string) row["UUID"]); - item.AssetID = new UUID((string) row["assetID"]); - item.AssetType = Convert.ToInt32(row["assetType"]); - item.InvType = Convert.ToInt32(row["invType"]); - item.Folder = new UUID((string) row["parentFolderID"]); - item.Owner = new UUID((string) row["avatarID"]); - item.CreatorIdentification = (string)row["creatorsID"]; - item.Name = (string) row["inventoryName"]; - item.Description = (string) row["inventoryDescription"]; - - item.NextPermissions = Convert.ToUInt32(row["inventoryNextPermissions"]); - item.CurrentPermissions = Convert.ToUInt32(row["inventoryCurrentPermissions"]); - item.BasePermissions = Convert.ToUInt32(row["inventoryBasePermissions"]); - item.EveryOnePermissions = Convert.ToUInt32(row["inventoryEveryOnePermissions"]); - item.GroupPermissions = Convert.ToUInt32(row["inventoryGroupPermissions"]); - - // new fields - if (!Convert.IsDBNull(row["salePrice"])) - item.SalePrice = Convert.ToInt32(row["salePrice"]); - - if (!Convert.IsDBNull(row["saleType"])) - item.SaleType = Convert.ToByte(row["saleType"]); - - if (!Convert.IsDBNull(row["creationDate"])) - item.CreationDate = Convert.ToInt32(row["creationDate"]); - - if (!Convert.IsDBNull(row["groupID"])) - item.GroupID = new UUID((string)row["groupID"]); - - if (!Convert.IsDBNull(row["groupOwned"])) - item.GroupOwned = Convert.ToBoolean(row["groupOwned"]); - - if (!Convert.IsDBNull(row["Flags"])) - item.Flags = Convert.ToUInt32(row["Flags"]); - - return item; - } - - /// - /// Fill a database row with item data - /// - /// - /// - private static void fillItemRow(DataRow row, InventoryItemBase item) - { - row["UUID"] = item.ID.ToString(); - row["assetID"] = item.AssetID.ToString(); - row["assetType"] = item.AssetType; - row["invType"] = item.InvType; - row["parentFolderID"] = item.Folder.ToString(); - row["avatarID"] = item.Owner.ToString(); - row["creatorsID"] = item.CreatorIdentification.ToString(); - row["inventoryName"] = item.Name; - row["inventoryDescription"] = item.Description; - - row["inventoryNextPermissions"] = item.NextPermissions; - row["inventoryCurrentPermissions"] = item.CurrentPermissions; - row["inventoryBasePermissions"] = item.BasePermissions; - row["inventoryEveryOnePermissions"] = item.EveryOnePermissions; - row["inventoryGroupPermissions"] = item.GroupPermissions; - - // new fields - row["salePrice"] = item.SalePrice; - row["saleType"] = item.SaleType; - row["creationDate"] = item.CreationDate; - row["groupID"] = item.GroupID.ToString(); - row["groupOwned"] = item.GroupOwned; - row["flags"] = item.Flags; - } - - /// - /// Add inventory folder - /// - /// Folder base - /// true=create folder. false=update existing folder - /// nasty - private void addFolder(InventoryFolderBase folder, bool add) - { - lock (ds) - { - DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; - - DataRow inventoryRow = inventoryFolderTable.Rows.Find(folder.ID.ToString()); - if (inventoryRow == null) - { - if (! add) - m_log.ErrorFormat("Interface Misuse: Attempting to Update non-existent inventory folder: {0}", folder.ID); - - inventoryRow = inventoryFolderTable.NewRow(); - fillFolderRow(inventoryRow, folder); - inventoryFolderTable.Rows.Add(inventoryRow); - } - else - { - if (add) - m_log.ErrorFormat("Interface Misuse: Attempting to Add inventory folder that already exists: {0}", folder.ID); - - fillFolderRow(inventoryRow, folder); - } - - invFoldersDa.Update(ds, "inventoryfolders"); - } - } - - /// - /// Move an inventory folder - /// - /// folder base - private void moveFolder(InventoryFolderBase folder) - { - lock (ds) - { - DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; - - DataRow inventoryRow = inventoryFolderTable.Rows.Find(folder.ID.ToString()); - if (inventoryRow == null) - { - inventoryRow = inventoryFolderTable.NewRow(); - fillFolderRow(inventoryRow, folder); - inventoryFolderTable.Rows.Add(inventoryRow); - } - else - { - moveFolderRow(inventoryRow, folder); - } - - invFoldersDa.Update(ds, "inventoryfolders"); - } - } - - /// - /// add an item in inventory - /// - /// the item - /// true=add item ; false=update existing item - private void addItem(InventoryItemBase item, bool add) - { - lock (ds) - { - DataTable inventoryItemTable = ds.Tables["inventoryitems"]; - - DataRow inventoryRow = inventoryItemTable.Rows.Find(item.ID.ToString()); - if (inventoryRow == null) - { - if (!add) - m_log.ErrorFormat("[INVENTORY DB]: Interface Misuse: Attempting to Update non-existent inventory item: {0}", item.ID); - - inventoryRow = inventoryItemTable.NewRow(); - fillItemRow(inventoryRow, item); - inventoryItemTable.Rows.Add(inventoryRow); - } - else - { - if (add) - m_log.ErrorFormat("[INVENTORY DB]: Interface Misuse: Attempting to Add inventory item that already exists: {0}", item.ID); - - fillItemRow(inventoryRow, item); - } - - invItemsDa.Update(ds, "inventoryitems"); - - DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; - - inventoryRow = inventoryFolderTable.Rows.Find(item.Folder.ToString()); - if (inventoryRow != null) //MySQL doesn't throw an exception here, so sqlite shouldn't either. - inventoryRow["version"] = (int)inventoryRow["version"] + 1; - - invFoldersDa.Update(ds, "inventoryfolders"); - } - } - - /// - /// TODO : DataSet commit - /// - public void Shutdown() - { - // TODO: DataSet commit - } - - /// - /// The name of this DB provider - /// - /// Name of DB provider - public string Name - { - get { return "SQLite Inventory Data Interface"; } - } - - /// - /// Returns the version of this DB provider - /// - /// A string containing the DB provider version - public string Version - { - get - { - Module module = GetType().Module; - // string dllName = module.Assembly.ManifestModule.Name; - Version dllVersion = module.Assembly.GetName().Version; - - - return - string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build, - dllVersion.Revision); - } - } - - /// - /// Returns a list of inventory items contained within the specified folder - /// - /// The UUID of the target folder - /// A List of InventoryItemBase items - public List getInventoryInFolder(UUID folderID) - { - lock (ds) - { - List retval = new List(); - DataTable inventoryItemTable = ds.Tables["inventoryitems"]; - string selectExp = "parentFolderID = '" + folderID + "'"; - DataRow[] rows = inventoryItemTable.Select(selectExp); - foreach (DataRow row in rows) - { - retval.Add(buildItem(row)); - } - - return retval; - } - } - - /// - /// Returns a list of the root folders within a users inventory - /// - /// The user whos inventory is to be searched - /// A list of folder objects - public List getUserRootFolders(UUID user) - { - return new List(); - } - - // see InventoryItemBase.getUserRootFolder - public InventoryFolderBase getUserRootFolder(UUID user) - { - lock (ds) - { - List folders = new List(); - DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; - string selectExp = "agentID = '" + user + "' AND parentID = '" + UUID.Zero + "'"; - DataRow[] rows = inventoryFolderTable.Select(selectExp); - foreach (DataRow row in rows) - { - folders.Add(buildFolder(row)); - } - - // There should only ever be one root folder for a user. However, if there's more - // than one we'll simply use the first one rather than failing. It would be even - // nicer to print some message to this effect, but this feels like it's too low a - // to put such a message out, and it's too minor right now to spare the time to - // suitably refactor. - if (folders.Count > 0) - { - return folders[0]; - } - - return null; - } - } - - /// - /// Append a list of all the child folders of a parent folder - /// - /// list where folders will be appended - /// ID of parent - protected void getInventoryFolders(ref List folders, UUID parentID) - { - lock (ds) - { - DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; - string selectExp = "parentID = '" + parentID + "'"; - DataRow[] rows = inventoryFolderTable.Select(selectExp); - foreach (DataRow row in rows) - { - folders.Add(buildFolder(row)); - } - - } - } - - /// - /// Returns a list of inventory folders contained in the folder 'parentID' - /// - /// The folder to get subfolders for - /// A list of inventory folders - public List getInventoryFolders(UUID parentID) - { - List folders = new List(); - getInventoryFolders(ref folders, parentID); - return folders; - } - - /// - /// See IInventoryDataPlugin - /// - /// - /// - public List getFolderHierarchy(UUID parentID) - { - /* Note: There are subtle changes between this implementation of getFolderHierarchy and the previous one - * - We will only need to hit the database twice instead of n times. - * - We assume the database is well-formed - no stranded/dangling folders, all folders in heirarchy owned - * by the same person, each user only has 1 inventory heirarchy - * - The returned list is not ordered, instead of breadth-first ordered - There are basically 2 usage cases for getFolderHeirarchy: - 1) Getting the user's entire inventory heirarchy when they log in - 2) Finding a subfolder heirarchy to delete when emptying the trash. - This implementation will pull all inventory folders from the database, and then prune away any folder that - is not part of the requested sub-heirarchy. The theory is that it is cheaper to make 1 request from the - database than to make n requests. This pays off only if requested heirarchy is large. - By making this choice, we are making the worst case better at the cost of making the best case worse - - Francis - */ - - List folders = new List(); - DataRow[] folderRows = null, parentRow; - InventoryFolderBase parentFolder = null; - lock (ds) - { - /* Fetch the parent folder from the database to determine the agent ID. - * Then fetch all inventory folders for that agent from the agent ID. - */ - DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; - string selectExp = "UUID = '" + parentID + "'"; - parentRow = inventoryFolderTable.Select(selectExp); // Assume at most 1 result - if (parentRow.GetLength(0) >= 1) // No result means parent folder does not exist - { - parentFolder = buildFolder(parentRow[0]); - UUID agentID = parentFolder.Owner; - selectExp = "agentID = '" + agentID + "'"; - folderRows = inventoryFolderTable.Select(selectExp); - } - - if (folderRows != null && folderRows.GetLength(0) >= 1) // No result means parent folder does not exist - { // or has no children - /* if we're querying the root folder, just return an unordered list of all folders in the user's - * inventory - */ - if (parentFolder.ParentID == UUID.Zero) - { - foreach (DataRow row in folderRows) - { - InventoryFolderBase curFolder = buildFolder(row); - if (curFolder.ID != parentID) // Return all folders except the parent folder of heirarchy - folders.Add(buildFolder(row)); - } - } // If requesting root folder - /* else we are querying a non-root folder. We currently have a list of all of the user's folders, - * we must construct a list of all folders in the heirarchy below parentID. - * Our first step will be to construct a hash table of all folders, indexed by parent ID. - * Once we have constructed the hash table, we will do a breadth-first traversal on the tree using the - * hash table to find child folders. - */ - else - { // Querying a non-root folder - - // Build a hash table of all user's inventory folders, indexed by each folder's parent ID - Dictionary> hashtable = - new Dictionary>(folderRows.GetLength(0)); - - foreach (DataRow row in folderRows) - { - InventoryFolderBase curFolder = buildFolder(row); - if (curFolder.ParentID != UUID.Zero) // Discard root of tree - not needed - { - if (hashtable.ContainsKey(curFolder.ParentID)) - { - // Current folder already has a sibling - append to sibling list - hashtable[curFolder.ParentID].Add(curFolder); - } - else - { - List siblingList = new List(); - siblingList.Add(curFolder); - // Current folder has no known (yet) siblings - hashtable.Add(curFolder.ParentID, siblingList); - } - } - } // For all inventory folders - - // Note: Could release the ds lock here - we don't access folderRows or the database anymore. - // This is somewhat of a moot point as the callers of this function usually lock db anyways. - - if (hashtable.ContainsKey(parentID)) // if requested folder does have children - folders.AddRange(hashtable[parentID]); - - // BreadthFirstSearch build inventory tree **Note: folders.Count is *not* static - for (int i = 0; i < folders.Count; i++) - if (hashtable.ContainsKey(folders[i].ID)) - folders.AddRange(hashtable[folders[i].ID]); - - } // if requesting a subfolder heirarchy - } // if folder parentID exists and has children - } // lock ds - return folders; - } - - /// - /// Returns an inventory item by its UUID - /// - /// The UUID of the item to be returned - /// A class containing item information - public InventoryItemBase getInventoryItem(UUID item) - { - lock (ds) - { - DataRow row = ds.Tables["inventoryitems"].Rows.Find(item.ToString()); - if (row != null) - { - return buildItem(row); - } - else - { - return null; - } - } - } - - /// - /// Returns a specified inventory folder by its UUID - /// - /// The UUID of the folder to be returned - /// A class containing folder information - public InventoryFolderBase getInventoryFolder(UUID folder) - { - // TODO: Deep voodoo here. If you enable this code then - // multi region breaks. No idea why, but I figured it was - // better to leave multi region at this point. It does mean - // that you don't get to see system textures why creating - // clothes and the like. :( - lock (ds) - { - DataRow row = ds.Tables["inventoryfolders"].Rows.Find(folder.ToString()); - if (row != null) - { - return buildFolder(row); - } - else - { - return null; - } - } - } - - /// - /// Creates a new inventory item based on item - /// - /// The item to be created - public void addInventoryItem(InventoryItemBase item) - { - addItem(item, true); - } - - /// - /// Updates an inventory item with item (updates based on ID) - /// - /// The updated item - public void updateInventoryItem(InventoryItemBase item) - { - addItem(item, false); - } - - /// - /// Delete an inventory item - /// - /// The item UUID - public void deleteInventoryItem(UUID itemID) - { - lock (ds) - { - DataTable inventoryItemTable = ds.Tables["inventoryitems"]; - - DataRow inventoryRow = inventoryItemTable.Rows.Find(itemID.ToString()); - if (inventoryRow != null) - { - inventoryRow.Delete(); - } - - invItemsDa.Update(ds, "inventoryitems"); - } - } - - public InventoryItemBase queryInventoryItem(UUID itemID) - { - return getInventoryItem(itemID); - } - - public InventoryFolderBase queryInventoryFolder(UUID folderID) - { - return getInventoryFolder(folderID); - } - - /// - /// Delete all items in the specified folder - /// - /// id of the folder, whose item content should be deleted - /// this is horribly inefficient, but I don't want to ruin the overall structure of this implementation - private void deleteItemsInFolder(UUID folderId) - { - List items = getInventoryInFolder(folderId); - - foreach (InventoryItemBase i in items) - deleteInventoryItem(i.ID); - } - - /// - /// Adds a new folder specified by folder - /// - /// The inventory folder - public void addInventoryFolder(InventoryFolderBase folder) - { - addFolder(folder, true); - } - - /// - /// Updates a folder based on its ID with folder - /// - /// The inventory folder - public void updateInventoryFolder(InventoryFolderBase folder) - { - addFolder(folder, false); - } - - /// - /// Moves a folder based on its ID with folder - /// - /// The inventory folder - public void moveInventoryFolder(InventoryFolderBase folder) - { - moveFolder(folder); - } - - /// - /// Delete a folder - /// - /// - /// This will clean-up any child folders and child items as well - /// - /// the folder UUID - public void deleteInventoryFolder(UUID folderID) - { - lock (ds) - { - List subFolders = getFolderHierarchy(folderID); - - DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; - DataRow inventoryRow; - - //Delete all sub-folders - foreach (InventoryFolderBase f in subFolders) - { - inventoryRow = inventoryFolderTable.Rows.Find(f.ID.ToString()); - if (inventoryRow != null) - { - deleteItemsInFolder(f.ID); - inventoryRow.Delete(); - } - } - - //Delete the actual row - inventoryRow = inventoryFolderTable.Rows.Find(folderID.ToString()); - if (inventoryRow != null) - { - deleteItemsInFolder(folderID); - inventoryRow.Delete(); - } - - invFoldersDa.Update(ds, "inventoryfolders"); - } - } - - /*********************************************************************** - * - * Data Table definitions - * - **********************************************************************/ - - protected void CreateDataSetMapping(IDataAdapter da, string tableName) - { - ITableMapping dbMapping = da.TableMappings.Add(tableName, tableName); - foreach (DataColumn col in ds.Tables[tableName].Columns) - { - dbMapping.ColumnMappings.Add(col.ColumnName, col.ColumnName); - } - } - - /// - /// Create the "inventoryitems" table - /// - private static DataTable createInventoryItemsTable() - { - DataTable inv = new DataTable("inventoryitems"); - - createCol(inv, "UUID", typeof (String)); //inventoryID - createCol(inv, "assetID", typeof (String)); - createCol(inv, "assetType", typeof (Int32)); - createCol(inv, "invType", typeof (Int32)); - createCol(inv, "parentFolderID", typeof (String)); - createCol(inv, "avatarID", typeof (String)); - createCol(inv, "creatorsID", typeof (String)); - - createCol(inv, "inventoryName", typeof (String)); - createCol(inv, "inventoryDescription", typeof (String)); - // permissions - createCol(inv, "inventoryNextPermissions", typeof (Int32)); - createCol(inv, "inventoryCurrentPermissions", typeof (Int32)); - createCol(inv, "inventoryBasePermissions", typeof (Int32)); - createCol(inv, "inventoryEveryOnePermissions", typeof (Int32)); - createCol(inv, "inventoryGroupPermissions", typeof (Int32)); - - // sale info - createCol(inv, "salePrice", typeof(Int32)); - createCol(inv, "saleType", typeof(Byte)); - - // creation date - createCol(inv, "creationDate", typeof(Int32)); - - // group info - createCol(inv, "groupID", typeof(String)); - createCol(inv, "groupOwned", typeof(Boolean)); - - // Flags - createCol(inv, "flags", typeof(UInt32)); - - inv.PrimaryKey = new DataColumn[] { inv.Columns["UUID"] }; - return inv; - } - - /// - /// Creates the "inventoryfolders" table - /// - /// - private static DataTable createInventoryFoldersTable() - { - DataTable fol = new DataTable("inventoryfolders"); - - createCol(fol, "UUID", typeof (String)); //folderID - createCol(fol, "name", typeof (String)); - createCol(fol, "agentID", typeof (String)); - createCol(fol, "parentID", typeof (String)); - createCol(fol, "type", typeof (Int32)); - createCol(fol, "version", typeof (Int32)); - - fol.PrimaryKey = new DataColumn[] {fol.Columns["UUID"]}; - return fol; - } - - /// - /// - /// - /// - /// - private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn) - { - lock (ds) - { - da.InsertCommand = createInsertCommand("inventoryitems", ds.Tables["inventoryitems"]); - da.InsertCommand.Connection = conn; - - da.UpdateCommand = createUpdateCommand("inventoryitems", "UUID=:UUID", ds.Tables["inventoryitems"]); - da.UpdateCommand.Connection = conn; - - SqliteCommand delete = new SqliteCommand("delete from inventoryitems where UUID = :UUID"); - delete.Parameters.Add(createSqliteParameter("UUID", typeof(String))); - delete.Connection = conn; - da.DeleteCommand = delete; - } - } - - /// - /// - /// - /// - /// - private void setupFoldersCommands(SqliteDataAdapter da, SqliteConnection conn) - { - lock (ds) - { - da.InsertCommand = createInsertCommand("inventoryfolders", ds.Tables["inventoryfolders"]); - da.InsertCommand.Connection = conn; - - da.UpdateCommand = createUpdateCommand("inventoryfolders", "UUID=:UUID", ds.Tables["inventoryfolders"]); - da.UpdateCommand.Connection = conn; - - SqliteCommand delete = new SqliteCommand("delete from inventoryfolders where UUID = :UUID"); - delete.Parameters.Add(createSqliteParameter("UUID", typeof(String))); - delete.Connection = conn; - da.DeleteCommand = delete; - } - } - - /// - /// - /// - /// - /// - private static InventoryFolderBase buildFolder(DataRow row) - { - InventoryFolderBase folder = new InventoryFolderBase(); - folder.ID = new UUID((string) row["UUID"]); - folder.Name = (string) row["name"]; - folder.Owner = new UUID((string) row["agentID"]); - folder.ParentID = new UUID((string) row["parentID"]); - folder.Type = Convert.ToInt16(row["type"]); - folder.Version = Convert.ToUInt16(row["version"]); - return folder; - } - - /// - /// - /// - /// - /// - private static void fillFolderRow(DataRow row, InventoryFolderBase folder) - { - row["UUID"] = folder.ID.ToString(); - row["name"] = folder.Name; - row["agentID"] = folder.Owner.ToString(); - row["parentID"] = folder.ParentID.ToString(); - row["type"] = folder.Type; - row["version"] = folder.Version; - } - - /// - /// - /// - /// - /// - private static void moveFolderRow(DataRow row, InventoryFolderBase folder) - { - row["UUID"] = folder.ID.ToString(); - row["parentID"] = folder.ParentID.ToString(); - } - - public List fetchActiveGestures (UUID avatarID) - { - lock (ds) - { - List items = new List(); - - DataTable inventoryItemTable = ds.Tables["inventoryitems"]; - string selectExp - = "avatarID = '" + avatarID + "' AND assetType = " + (int)AssetType.Gesture + " AND flags = 1"; - //m_log.DebugFormat("[SQL]: sql = " + selectExp); - DataRow[] rows = inventoryItemTable.Select(selectExp); - foreach (DataRow row in rows) - { - items.Add(buildItem(row)); - } - return items; - } - } - } -} diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index 6ed3d40..19880de 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs @@ -707,7 +707,7 @@ namespace OpenSim.Data.SQLite DataRow[] primsForRegion = prims.Select(byRegion); // m_log.Info("[SQLITE REGION DB]: Loaded " + primsForRegion.Length + " prims for region: " + regionUUID); - // First, create all groups + // First, create all groups foreach (DataRow primRow in primsForRegion) { try @@ -733,12 +733,12 @@ namespace OpenSim.Data.SQLite } SceneObjectGroup group = new SceneObjectGroup(prim); - + createdObjects.Add(group.UUID, group); retvals.Add(group); LoadItems(prim); - + } } catch (Exception e) @@ -827,7 +827,7 @@ namespace OpenSim.Data.SQLite } /// - /// Store a terrain revision in region storage + /// Store a terrain in region storage /// /// terrain heightfield /// region UUID @@ -851,7 +851,44 @@ namespace OpenSim.Data.SQLite Array terrainDBblob; terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); - m_log.DebugFormat("{0} Storing terrain revision r {1}", LogHeader, terrainDBRevision); + m_log.DebugFormat("{0} Storing terrain format {1}", LogHeader, terrainDBRevision); + + using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); + cmd.Parameters.Add(new SqliteParameter(":Revision", terrainDBRevision)); + cmd.Parameters.Add(new SqliteParameter(":Heightfield", terrainDBblob)); + cmd.ExecuteNonQuery(); + } + } + } + + /// + /// Store baked terrain in region storage + /// + /// terrain heightfield + /// region UUID + public void StoreBakedTerrain(TerrainData terrData, UUID regionID) + { + lock (ds) + { + using ( + SqliteCommand cmd = new SqliteCommand("delete from bakedterrain where RegionUUID=:RegionUUID", m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); + cmd.ExecuteNonQuery(); + } + + // the following is an work around for .NET. The perf + // issues associated with it aren't as bad as you think. + String sql = "insert into bakedterrain(RegionUUID, Revision, Heightfield)" + + " values(:RegionUUID, :Revision, :Heightfield)"; + + int terrainDBRevision; + Array terrainDBblob; + terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); + + m_log.DebugFormat("{0} Storing bakedterrain format {1}", LogHeader, terrainDBRevision); using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) { @@ -913,6 +950,34 @@ namespace OpenSim.Data.SQLite return terrData; } + public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) + { + TerrainData terrData = null; + + lock (ds) + { + String sql = "select RegionUUID, Revision, Heightfield from bakedterrain" + + " where RegionUUID=:RegionUUID"; + + using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); + + using (IDataReader row = cmd.ExecuteReader()) + { + int rev = 0; + if (row.Read()) + { + rev = Convert.ToInt32(row["Revision"]); + byte[] blob = (byte[])row["Heightfield"]; + terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); + } + } + } + } + return terrData; + } + public void RemoveLandObject(UUID globalID) { lock (ds) @@ -1151,6 +1216,7 @@ namespace OpenSim.Data.SQLite createCol(prims, "OwnerID", typeof(String)); createCol(prims, "GroupID", typeof(String)); createCol(prims, "LastOwnerID", typeof(String)); + createCol(prims, "RezzerID", typeof(String)); createCol(prims, "OwnerMask", typeof(Int32)); createCol(prims, "NextOwnerMask", typeof(Int32)); createCol(prims, "GroupMask", typeof(Int32)); @@ -1232,7 +1298,7 @@ namespace OpenSim.Data.SQLite createCol(prims, "VolumeDetect", typeof(Int16)); createCol(prims, "MediaURL", typeof(String)); - + createCol(prims, "AttachedPosX", typeof(Double)); createCol(prims, "AttachedPosY", typeof(Double)); createCol(prims, "AttachedPosZ", typeof(Double)); @@ -1246,6 +1312,7 @@ namespace OpenSim.Data.SQLite createCol(prims, "Restitution", typeof(Double)); createCol(prims, "KeyframeMotion", typeof(Byte[])); + // Add in contraints prims.PrimaryKey = new DataColumn[] { prims.Columns["UUID"] }; @@ -1353,7 +1420,7 @@ namespace OpenSim.Data.SQLite createCol(land, "Name", typeof(String)); createCol(land, "Desc", typeof(String)); createCol(land, "OwnerUUID", typeof(String)); - createCol(land, "IsGroupOwned", typeof(Boolean)); + createCol(land, "IsGroupOwned", typeof(string)); createCol(land, "Area", typeof(Int32)); createCol(land, "AuctionID", typeof(Int32)); //Unemplemented createCol(land, "Category", typeof(Int32)); //Enum OpenMetaverse.Parcel.ParcelCategory @@ -1386,6 +1453,9 @@ namespace OpenSim.Data.SQLite createCol(land, "MediaLoop", typeof(Boolean)); createCol(land, "ObscureMedia", typeof(Boolean)); createCol(land, "ObscureMusic", typeof(Boolean)); + createCol(land, "SeeAVs", typeof(Boolean)); + createCol(land, "AnyAVSounds", typeof(Boolean)); + createCol(land, "GroupAVSounds", typeof(Boolean)); land.PrimaryKey = new DataColumn[] { land.Columns["UUID"] }; @@ -1610,6 +1680,7 @@ namespace OpenSim.Data.SQLite prim.OwnerID = new UUID((String)row["OwnerID"]); prim.GroupID = new UUID((String)row["GroupID"]); prim.LastOwnerID = new UUID((String)row["LastOwnerID"]); + prim.RezzerID = row["RezzerID"] == DBNull.Value ? UUID.Zero : new UUID((String)row["RezzerID"]); prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]); prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]); prim.GroupMask = Convert.ToUInt32(row["GroupMask"]); @@ -1724,7 +1795,7 @@ namespace OpenSim.Data.SQLite // m_log.DebugFormat("[SQLITE]: MediaUrl type [{0}]", row["MediaURL"].GetType()); prim.MediaUrl = (string)row["MediaURL"]; } - + prim.AttachedPos = new Vector3( Convert.ToSingle(row["AttachedPosX"]), Convert.ToSingle(row["AttachedPosY"]), @@ -1735,7 +1806,7 @@ namespace OpenSim.Data.SQLite { //m_log.DebugFormat("[SQLITE]: DynAttrs type [{0}]", row["DynAttrs"].GetType()); prim.DynAttrs = DAMap.FromXml((string)row["DynAttrs"]); - } + } else { prim.DynAttrs = new DAMap(); @@ -1747,7 +1818,7 @@ namespace OpenSim.Data.SQLite prim.Friction = Convert.ToSingle(row["Friction"]); prim.Restitution = Convert.ToSingle(row["Restitution"]); - + if (!(row["KeyframeMotion"] is DBNull)) { Byte[] data = (byte[])row["KeyframeMotion"]; @@ -1760,7 +1831,24 @@ namespace OpenSim.Data.SQLite { prim.KeyframeMotion = null; } - + + prim.PassCollisions = Convert.ToBoolean(row["PassCollisions"]); + prim.PassTouches = Convert.ToBoolean(row["PassTouches"]); + prim.RotationAxisLocks = Convert.ToByte(row["RotationAxisLocks"]); + + SOPVehicle vehicle = null; + if (!(row["Vehicle"] is DBNull) && row["Vehicle"].ToString() != String.Empty) + { + vehicle = SOPVehicle.FromXml2(row["Vehicle"].ToString()); + if (vehicle != null) + prim.VehicleParams = vehicle; + } + + PhysicsInertiaData pdata = null; + if (!(row["PhysInertia"] is DBNull) && row["PhysInertia"].ToString() != String.Empty) + pdata = PhysicsInertiaData.FromXml2(row["PhysInertia"].ToString()); + prim.PhysicsInertia = pdata; + return prim; } @@ -1817,7 +1905,7 @@ namespace OpenSim.Data.SQLite newData.Name = (String)row["Name"]; newData.Description = (String)row["Desc"]; newData.OwnerID = (UUID)(String)row["OwnerUUID"]; - newData.IsGroupOwned = (Boolean)row["IsGroupOwned"]; + newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); newData.Area = Convert.ToInt32(row["Area"]); newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented newData.Category = (ParcelCategory)Convert.ToInt32(row["Category"]); @@ -1845,6 +1933,10 @@ namespace OpenSim.Data.SQLite newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]); newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]); newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]); + newData.SeeAVs = Convert.ToBoolean(row["SeeAVs"]); + newData.AnyAVSounds = Convert.ToBoolean(row["AnyAVSounds"]); + newData.GroupAVSounds = Convert.ToBoolean(row["GroupAVSounds"]); + try { newData.UserLocation = @@ -1918,7 +2010,8 @@ namespace OpenSim.Data.SQLite newSettings.TerrainImageID = new UUID((String)row["map_tile_ID"]); newSettings.TelehubObject = new UUID((String)row["TelehubObject"]); newSettings.ParcelImageID = new UUID((String)row["parcel_tile_ID"]); - + newSettings.GodBlockSearch = Convert.ToBoolean(row["block_search"]); + newSettings.Casino = Convert.ToBoolean(row["casino"]); return newSettings; } @@ -2013,6 +2106,7 @@ namespace OpenSim.Data.SQLite return entry; } + /// /// /// @@ -2039,6 +2133,7 @@ namespace OpenSim.Data.SQLite row["OwnerID"] = prim.OwnerID.ToString(); row["GroupID"] = prim.GroupID.ToString(); row["LastOwnerID"] = prim.LastOwnerID.ToString(); + row["RezzerID"] = prim.RezzerID.ToString(); row["OwnerMask"] = prim.OwnerMask; row["NextOwnerMask"] = prim.NextOwnerMask; row["GroupMask"] = prim.GroupMask; @@ -2137,7 +2232,6 @@ namespace OpenSim.Data.SQLite // click action row["ClickAction"] = prim.ClickAction; - row["SalePrice"] = prim.SalePrice; row["Material"] = prim.Material; row["CollisionSound"] = prim.CollisionSound.ToString(); @@ -2168,8 +2262,21 @@ namespace OpenSim.Data.SQLite row["KeyframeMotion"] = prim.KeyframeMotion.Serialize(); else row["KeyframeMotion"] = new Byte[0]; - - + + row["PassTouches"] = prim.PassTouches; + row["PassCollisions"] = prim.PassCollisions; + row["RotationAxisLocks"] = prim.RotationAxisLocks; + + if (prim.VehicleParams != null) + row["Vehicle"] = prim.VehicleParams.ToXml2(); + else + row["Vehicle"] = String.Empty; + + if (prim.PhysicsInertia != null) + row["PhysInertia"] = prim.PhysicsInertia.ToXml2(); + else + row["PhysInertia"] = String.Empty; + } /// @@ -2220,7 +2327,7 @@ namespace OpenSim.Data.SQLite row["Name"] = land.Name; row["Desc"] = land.Description; row["OwnerUUID"] = land.OwnerID.ToString(); - row["IsGroupOwned"] = land.IsGroupOwned; + row["IsGroupOwned"] = land.IsGroupOwned.ToString(); row["Area"] = land.Area; row["AuctionID"] = land.AuctionID; //Unemplemented row["Category"] = land.Category; //Enum OpenMetaverse.Parcel.ParcelCategory @@ -2253,6 +2360,10 @@ namespace OpenSim.Data.SQLite row["MediaLoop"] = land.MediaLoop; row["ObscureMusic"] = land.ObscureMusic; row["ObscureMedia"] = land.ObscureMedia; + row["SeeAVs"] = land.SeeAVs; + row["AnyAVSounds"] = land.AnyAVSounds; + row["GroupAVSounds"] = land.GroupAVSounds; + } /// @@ -2311,6 +2422,8 @@ namespace OpenSim.Data.SQLite row["map_tile_ID"] = settings.TerrainImageID.ToString(); row["TelehubObject"] = settings.TelehubObject.ToString(); row["parcel_tile_ID"] = settings.ParcelImageID.ToString(); + row["block_search"] = settings.GodBlockSearch; + row["casino"] = settings.Casino; } /// @@ -2430,7 +2543,7 @@ namespace OpenSim.Data.SQLite if (!(row["Media"] is System.DBNull)) s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]); - + return s; } @@ -2908,6 +3021,10 @@ namespace OpenSim.Data.SQLite { return DbType.Binary; } + else if (type == typeof(Boolean)) + { + return DbType.Boolean; + } else { return DbType.String; @@ -2944,6 +3061,11 @@ namespace OpenSim.Data.SQLite } } + public UUID[] GetObjectIDs(UUID regionID) + { + return new UUID[0]; + } + public void SaveExtra(UUID regionID, string name, string value) { } diff --git a/OpenSim/Data/SQLite/SQLiteUserAccountData.cs b/OpenSim/Data/SQLite/SQLiteUserAccountData.cs index f98d376..1b79185 100644 --- a/OpenSim/Data/SQLite/SQLiteUserAccountData.cs +++ b/OpenSim/Data/SQLite/SQLiteUserAccountData.cs @@ -75,12 +75,17 @@ namespace OpenSim.Data.SQLite } else { - cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{3}%')", + cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{3}%')", m_Realm, scopeID.ToString(), words[0], words[1]); } return DoQuery(cmd); } } + + public UserAccountData[] GetUsersWhere(UUID scopeID, string where) + { + return null; + } } } diff --git a/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs b/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs index cd3e8b6..13aac79 100644 --- a/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs +++ b/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs @@ -46,43 +46,43 @@ namespace OpenSim.Data.SQLite { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + private SqliteConnection m_connection; private string m_connectionString; - + private Dictionary m_FieldMap = new Dictionary(); - + protected virtual Assembly Assembly { get { return GetType().Assembly; } } - + public SQLiteUserProfilesData() { } - + public SQLiteUserProfilesData(string connectionString) { Initialise(connectionString); } - + public void Initialise(string connectionString) { if (Util.IsWindows()) Util.LoadArchSpecificWindowsDll("sqlite3.dll"); - + m_connectionString = connectionString; - + m_log.Info("[PROFILES_DATA]: Sqlite - connecting: "+m_connectionString); - + m_connection = new SqliteConnection(m_connectionString); m_connection.Open(); - + Migration m = new Migration(m_connection, Assembly, "UserProfiles"); m.Update(); } - + private string[] FieldList { get { return new List(m_FieldMap.Keys).ToArray(); } @@ -123,7 +123,7 @@ namespace OpenSim.Data.SQLite } reader.Close(); - + return data; } public bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result) @@ -162,21 +162,21 @@ namespace OpenSim.Data.SQLite query += ":ParcelName,"; query += ":Flags,"; query += ":ListingPrice ) "; - + if(string.IsNullOrEmpty(ad.ParcelName)) ad.ParcelName = "Unknown"; if(ad.ParcelId == null) ad.ParcelId = UUID.Zero; if(string.IsNullOrEmpty(ad.Description)) ad.Description = "No Description"; - + DateTime epoch = new DateTime(1970, 1, 1); DateTime now = DateTime.Now; TimeSpan epochnow = now - epoch; TimeSpan duration; DateTime expiration; TimeSpan epochexp; - + if(ad.Flags == 2) { duration = new TimeSpan(7,0,0,0); @@ -211,7 +211,7 @@ namespace OpenSim.Data.SQLite cmd.Parameters.AddWithValue(":ParcelName", ad.ParcelName.ToString()); cmd.Parameters.AddWithValue(":Flags", ad.Flags.ToString()); cmd.Parameters.AddWithValue(":ListingPrice", ad.Price.ToString ()); - + cmd.ExecuteNonQuery(); } } @@ -227,17 +227,17 @@ namespace OpenSim.Data.SQLite public bool DeleteClassifiedRecord(UUID recordId) { string query = string.Empty; - + query += "DELETE FROM classifieds WHERE "; query += "classifieduuid = :ClasifiedId"; - + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) { cmd.CommandText = query; cmd.Parameters.AddWithValue(":ClassifiedId", recordId.ToString()); - + cmd.ExecuteNonQuery(); } } @@ -254,17 +254,17 @@ namespace OpenSim.Data.SQLite { IDataReader reader = null; string query = string.Empty; - + query += "SELECT * FROM classifieds WHERE "; query += "classifieduuid = :AdId"; - + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) { cmd.CommandText = query; cmd.Parameters.AddWithValue(":AdId", ad.ClassifiedId.ToString()); - + using (reader = cmd.ExecuteReader()) { if(reader.Read ()) @@ -299,24 +299,24 @@ namespace OpenSim.Data.SQLite { IDataReader reader = null; string query = string.Empty; - + query += "SELECT `pickuuid`,`name` FROM userpicks WHERE "; query += "creatoruuid = :Id"; OSDArray data = new OSDArray(); - + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) { cmd.CommandText = query; cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); - + using (reader = cmd.ExecuteReader()) { while (reader.Read()) { OSDMap record = new OSDMap(); - + record.Add("pickuuid",OSD.FromString((string)reader["pickuuid"])); record.Add("name",OSD.FromString((string)reader["name"])); data.Add(record); @@ -336,11 +336,11 @@ namespace OpenSim.Data.SQLite IDataReader reader = null; string query = string.Empty; UserProfilePick pick = new UserProfilePick(); - + query += "SELECT * FROM userpicks WHERE "; query += "creatoruuid = :CreatorId AND "; query += "pickuuid = :PickId"; - + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) @@ -348,17 +348,17 @@ namespace OpenSim.Data.SQLite cmd.CommandText = query; cmd.Parameters.AddWithValue(":CreatorId", avatarId.ToString()); cmd.Parameters.AddWithValue(":PickId", pickId.ToString()); - + using (reader = cmd.ExecuteReader()) { - + while (reader.Read()) { string description = (string)reader["description"]; - + if (string.IsNullOrEmpty(description)) description = "No description given."; - + UUID.TryParse((string)reader["pickuuid"], out pick.PickId); UUID.TryParse((string)reader["creatoruuid"], out pick.CreatorId); UUID.TryParse((string)reader["parceluuid"], out pick.ParcelId); @@ -385,7 +385,7 @@ namespace OpenSim.Data.SQLite } public bool UpdatePicksRecord(UserProfilePick pick) - { + { string query = string.Empty; query += "INSERT OR REPLACE INTO userpicks ("; @@ -416,7 +416,7 @@ namespace OpenSim.Data.SQLite query += ":GlobalPos,"; query += ":SortOrder,"; query += ":Enabled) "; - + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) @@ -456,10 +456,10 @@ namespace OpenSim.Data.SQLite public bool DeletePicksRecord(UUID pickId) { string query = string.Empty; - + query += "DELETE FROM userpicks WHERE "; query += "pickuuid = :PickId"; - + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) @@ -479,15 +479,15 @@ namespace OpenSim.Data.SQLite } public bool GetAvatarNotes(ref UserProfileNotes notes) - { + { IDataReader reader = null; string query = string.Empty; - + query += "SELECT `notes` FROM usernotes WHERE "; query += "useruuid = :Id AND "; query += "targetuuid = :TargetId"; OSDArray data = new OSDArray(); - + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) @@ -495,7 +495,7 @@ namespace OpenSim.Data.SQLite cmd.CommandText = query; cmd.Parameters.AddWithValue(":Id", notes.UserId.ToString()); cmd.Parameters.AddWithValue(":TargetId", notes.TargetId.ToString()); - + using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { while (reader.Read()) @@ -514,10 +514,10 @@ namespace OpenSim.Data.SQLite } public bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result) - { + { string query = string.Empty; bool remove; - + if(string.IsNullOrEmpty(note.Notes)) { remove = true; @@ -533,7 +533,7 @@ namespace OpenSim.Data.SQLite query += ":TargetId,"; query += ":Notes )"; } - + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) @@ -544,7 +544,7 @@ namespace OpenSim.Data.SQLite cmd.Parameters.AddWithValue(":Notes", note.Notes); cmd.Parameters.AddWithValue(":TargetId", note.TargetId.ToString ()); cmd.Parameters.AddWithValue(":UserId", note.UserId.ToString()); - + cmd.ExecuteNonQuery(); } } @@ -561,7 +561,7 @@ namespace OpenSim.Data.SQLite { IDataReader reader = null; string query = string.Empty; - + query += "SELECT * FROM userprofile WHERE "; query += "useruuid = :Id"; @@ -569,7 +569,7 @@ namespace OpenSim.Data.SQLite { cmd.CommandText = query; cmd.Parameters.AddWithValue(":Id", props.UserId.ToString()); - + try { @@ -611,7 +611,7 @@ namespace OpenSim.Data.SQLite props.Language = string.Empty; props.PublishProfile = false; props.PublishMature = false; - + query = "INSERT INTO userprofile ("; query += "useruuid, "; query += "profilePartner, "; @@ -659,7 +659,7 @@ namespace OpenSim.Data.SQLite put.Parameters.AddWithValue(":profileAboutText", props.AboutText); put.Parameters.AddWithValue(":profileFirstImage", props.FirstLifeImageId.ToString()); put.Parameters.AddWithValue(":profileFirstText", props.FirstLifeText); - + put.ExecuteNonQuery(); } } @@ -668,9 +668,9 @@ namespace OpenSim.Data.SQLite } public bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result) - { + { string query = string.Empty; - + query += "UPDATE userprofile SET "; query += "profileURL=:profileURL, "; query += "profileImage=:image, "; @@ -678,7 +678,7 @@ namespace OpenSim.Data.SQLite query += "profileFirstImage=:firstlifeimage,"; query += "profileFirstText=:firstlifetext "; query += "WHERE useruuid=:uuid"; - + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) @@ -690,7 +690,7 @@ namespace OpenSim.Data.SQLite cmd.Parameters.AddWithValue(":firstlifeimage", props.FirstLifeImageId.ToString()); cmd.Parameters.AddWithValue(":firstlifetext", props.FirstLifeText); cmd.Parameters.AddWithValue(":uuid", props.UserId.ToString()); - + cmd.ExecuteNonQuery(); } } @@ -698,16 +698,16 @@ namespace OpenSim.Data.SQLite { m_log.ErrorFormat("[PROFILES_DATA]" + ": AgentPropertiesUpdate exception {0}", e.Message); - + return false; } return true; } public bool UpdateAvatarInterests(UserProfileProperties up, ref string result) - { + { string query = string.Empty; - + query += "UPDATE userprofile SET "; query += "profileWantToMask=:WantMask, "; query += "profileWantToText=:WantText,"; @@ -715,7 +715,7 @@ namespace OpenSim.Data.SQLite query += "profileSkillsText=:SkillsText, "; query += "profileLanguages=:Languages "; query += "WHERE useruuid=:uuid"; - + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) @@ -727,7 +727,7 @@ namespace OpenSim.Data.SQLite cmd.Parameters.AddWithValue(":SkillsText", up.SkillsText); cmd.Parameters.AddWithValue(":Languages", up.Language); cmd.Parameters.AddWithValue(":uuid", up.UserId.ToString()); - + cmd.ExecuteNonQuery(); } } @@ -741,16 +741,17 @@ namespace OpenSim.Data.SQLite return true; } + public bool UpdateUserPreferences(ref UserPreferences pref, ref string result) - { + { string query = string.Empty; - + query += "UPDATE usersettings SET "; query += "imviaemail=:ImViaEmail, "; query += "visible=:Visible, "; query += "email=:EMail "; query += "WHERE useruuid=:uuid"; - + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) @@ -760,7 +761,7 @@ namespace OpenSim.Data.SQLite cmd.Parameters.AddWithValue(":Visible", pref.Visible); cmd.Parameters.AddWithValue(":EMail", pref.EMail); cmd.Parameters.AddWithValue(":uuid", pref.UserId.ToString()); - + cmd.ExecuteNonQuery(); } } @@ -778,20 +779,20 @@ namespace OpenSim.Data.SQLite { IDataReader reader = null; string query = string.Empty; - + query += "SELECT imviaemail,visible,email FROM "; query += "usersettings WHERE "; query += "useruuid = :Id"; - + OSDArray data = new OSDArray(); - + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) { cmd.CommandText = query; cmd.Parameters.AddWithValue("?Id", pref.UserId.ToString()); - + using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { if(reader.Read()) @@ -804,13 +805,13 @@ namespace OpenSim.Data.SQLite { query = "INSERT INTO usersettings VALUES "; query += "(:Id,'false','false', :Email)"; - + using (SqliteCommand put = (SqliteCommand)m_connection.CreateCommand()) { put.Parameters.AddWithValue(":Id", pref.UserId.ToString()); put.Parameters.AddWithValue(":Email", pref.EMail); put.ExecuteNonQuery(); - + } } } @@ -830,11 +831,11 @@ namespace OpenSim.Data.SQLite { IDataReader reader = null; string query = string.Empty; - + query += "SELECT * FROM `userdata` WHERE "; query += "UserId = :Id AND "; query += "TagId = :TagId"; - + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) @@ -842,7 +843,7 @@ namespace OpenSim.Data.SQLite cmd.CommandText = query; cmd.Parameters.AddWithValue(":Id", props.UserId.ToString()); cmd.Parameters.AddWithValue (":TagId", props.TagId.ToString()); - + using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { if(reader.Read()) @@ -857,7 +858,7 @@ namespace OpenSim.Data.SQLite query += ":TagId,"; query += ":DataKey,"; query += ":DataVal) "; - + using (SqliteCommand put = (SqliteCommand)m_connection.CreateCommand()) { put.Parameters.AddWithValue(":Id", props.UserId.ToString()); @@ -881,16 +882,16 @@ namespace OpenSim.Data.SQLite return true; } public bool SetUserAppData(UserAppData props, ref string result) - { + { string query = string.Empty; - + query += "UPDATE userdata SET "; query += "TagId = :TagId, "; query += "DataKey = :DataKey, "; query += "DataVal = :DataVal WHERE "; query += "UserId = :UserId AND "; query += "TagId = :TagId"; - + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) @@ -917,17 +918,17 @@ namespace OpenSim.Data.SQLite IDataReader reader = null; OSDArray data = new OSDArray(); string query = "SELECT `snapshotuuid` FROM {0} WHERE `creatoruuid` = :Id"; - + // Get classified image assets - - + + try { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) { cmd.CommandText = query; cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); - + using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { while(reader.Read()) @@ -941,7 +942,7 @@ namespace OpenSim.Data.SQLite { cmd.CommandText = query; cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); - + using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { if(reader.Read()) @@ -950,14 +951,14 @@ namespace OpenSim.Data.SQLite } } } - + query = "SELECT `profileImage`, `profileFirstImage` FROM `userprofile` WHERE `useruuid` = :Id"; - + using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) { cmd.CommandText = query; cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); - + using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { if(reader.Read()) diff --git a/OpenSim/Data/SQLite/SQLiteUtils.cs b/OpenSim/Data/SQLite/SQLiteUtils.cs index ca5861f..1218ebb 100644 --- a/OpenSim/Data/SQLite/SQLiteUtils.cs +++ b/OpenSim/Data/SQLite/SQLiteUtils.cs @@ -49,7 +49,7 @@ namespace OpenSim.Data.SQLite **********************************************************************/ /// - /// + /// /// /// /// @@ -147,7 +147,7 @@ namespace OpenSim.Data.SQLite } /// - /// + /// /// /// Data Table /// @@ -191,7 +191,7 @@ namespace OpenSim.Data.SQLite /// lines for defining SqliteParameters to 2 parameters: /// column name and database type. /// - /// + /// /// /// It assumes certain conventions like :param as the param /// name to replace in parametrized queries, and that source diff --git a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs index 2a0a8f6..4ef1f30 100644 --- a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs +++ b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs @@ -107,7 +107,7 @@ namespace OpenSim.Data.SQLite public bool DeleteItems(string[] fields, string[] vals) { return m_Items.Delete(fields, vals); - } + } public bool MoveItem(string id, string newParent) { @@ -302,20 +302,14 @@ namespace OpenSim.Data.SQLite { // m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID); // Util.PrintCallStack(); - + using (SqliteCommand cmd = new SqliteCommand()) { - cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = ?folderID"; + cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = :folderID"; cmd.Parameters.Add(new SqliteParameter(":folderID", folderID)); - try - { - cmd.ExecuteNonQuery(); - } - catch (Exception) - { + if(ExecuteNonQuery(cmd, m_Connection) == 0) return false; - } } return true; diff --git a/OpenSim/Data/Tests/AssetTests.cs b/OpenSim/Data/Tests/AssetTests.cs index 5d7b169..70880cf 100644 --- a/OpenSim/Data/Tests/AssetTests.cs +++ b/OpenSim/Data/Tests/AssetTests.cs @@ -110,7 +110,7 @@ namespace OpenSim.Data.Tests public void T010_StoreReadVerifyAssets() { TestHelpers.InMethod(); - + AssetBase a1 = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture, critter1.ToString()); AssetBase a2 = new AssetBase(uuid2, "asset two", (sbyte)AssetType.Texture, critter2.ToString()); AssetBase a3 = new AssetBase(uuid3, "asset three", (sbyte)AssetType.Texture, critter3.ToString()); @@ -125,14 +125,20 @@ namespace OpenSim.Data.Tests m_db.StoreAsset(a1); m_db.StoreAsset(a2); m_db.StoreAsset(a3); - + a1.UploadAttempts = 0; + a2.UploadAttempts = 0; + a3.UploadAttempts = 0; + AssetBase a1a = m_db.GetAsset(uuid1); + a1a.UploadAttempts = 0; Assert.That(a1a, Constraints.PropertyCompareConstraint(a1)); AssetBase a2a = m_db.GetAsset(uuid2); + a2a.UploadAttempts = 0; Assert.That(a2a, Constraints.PropertyCompareConstraint(a2)); AssetBase a3a = m_db.GetAsset(uuid3); + a3a.UploadAttempts = 0; Assert.That(a3a, Constraints.PropertyCompareConstraint(a3)); scrambler.Scramble(a1a); @@ -142,14 +148,20 @@ namespace OpenSim.Data.Tests m_db.StoreAsset(a1a); m_db.StoreAsset(a2a); m_db.StoreAsset(a3a); + a1a.UploadAttempts = 0; + a2a.UploadAttempts = 0; + a3a.UploadAttempts = 0; AssetBase a1b = m_db.GetAsset(uuid1); + a1b.UploadAttempts = 0; Assert.That(a1b, Constraints.PropertyCompareConstraint(a1a)); AssetBase a2b = m_db.GetAsset(uuid2); + a2b.UploadAttempts = 0; Assert.That(a2b, Constraints.PropertyCompareConstraint(a2a)); AssetBase a3b = m_db.GetAsset(uuid3); + a3b.UploadAttempts = 0; Assert.That(a3b, Constraints.PropertyCompareConstraint(a3a)); bool[] exist = m_db.AssetsExist(new[] { uuid1, uuid2, uuid3 }); @@ -178,7 +190,7 @@ namespace OpenSim.Data.Tests public void T020_CheckForWeirdCreatorID() { TestHelpers.InMethod(); - + // It is expected that eventually the CreatorID might be an arbitrary string (an URI) // rather than a valid UUID (?). This test is to make sure that the database layer does not // attempt to convert CreatorID to GUID, but just passes it both ways as a string. @@ -190,16 +202,22 @@ namespace OpenSim.Data.Tests a3.Data = data1; m_db.StoreAsset(a1); + a1.UploadAttempts = 0; m_db.StoreAsset(a2); + a2.UploadAttempts = 0; m_db.StoreAsset(a3); + a3.UploadAttempts = 0; AssetBase a1a = m_db.GetAsset(uuid1); + a1a.UploadAttempts = 0; Assert.That(a1a, Constraints.PropertyCompareConstraint(a1)); AssetBase a2a = m_db.GetAsset(uuid2); + a2a.UploadAttempts = 0; Assert.That(a2a, Constraints.PropertyCompareConstraint(a2)); AssetBase a3a = m_db.GetAsset(uuid3); + a3a.UploadAttempts = 0; Assert.That(a3a, Constraints.PropertyCompareConstraint(a3)); } } diff --git a/OpenSim/Data/Tests/BasicDataServiceTest.cs b/OpenSim/Data/Tests/BasicDataServiceTest.cs index 8c296b9..79691e4 100644 --- a/OpenSim/Data/Tests/BasicDataServiceTest.cs +++ b/OpenSim/Data/Tests/BasicDataServiceTest.cs @@ -41,11 +41,11 @@ using System.Reflection; namespace OpenSim.Data.Tests { - /// This is a base class for testing any Data service for any DBMS. + /// This is a base class for testing any Data service for any DBMS. /// Requires NUnit 2.5 or better (to support the generics). /// /// - /// FIXME: Should extend OpenSimTestCase but compile on mono 2.4.3 currently fails with + /// FIXME: Should extend OpenSimTestCase but compile on mono 2.4.3 currently fails with /// AssetTests`2 : System.MemberAccessException : Cannot create an instance of OpenSim.Data.Tests.AssetTests`2[TConn,TAssetData] because Type.ContainsGenericParameters is true. /// and similar on EstateTests, InventoryTests and RegionTests. /// Runs fine with mono 2.10.8.1, so easiest thing is to wait until min Mono version uplifts. @@ -60,7 +60,7 @@ namespace OpenSim.Data.Tests private TService m_service; private string m_file; - // TODO: Is this in the right place here? + // TODO: Is this in the right place here? // Later: apparently it's not, but does it matter here? // protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -68,7 +68,7 @@ namespace OpenSim.Data.Tests public BasicDataServiceTest() : this("") - { + { } public BasicDataServiceTest(string conn) @@ -106,7 +106,7 @@ namespace OpenSim.Data.Tests if (String.IsNullOrEmpty(m_connStr)) { m_file = Path.GetTempFileName() + ".db"; - m_connStr = "URI=file:../db/" + m_file + ",version=3"; + m_connStr = "URI=file:" + m_file + ",version=3"; } } @@ -226,7 +226,7 @@ namespace OpenSim.Data.Tests } } - /// Clear tables listed as parameters (without dropping them). + /// Clear tables listed as parameters (without dropping them). /// /// protected virtual void ResetMigrations(params string[] stores) @@ -251,7 +251,7 @@ namespace OpenSim.Data.Tests } } - /// Clear tables listed as parameters (without dropping them). + /// Clear tables listed as parameters (without dropping them). /// /// protected virtual void ClearTables(params string[] tables) diff --git a/OpenSim/Data/Tests/DefaultTestConns.cs b/OpenSim/Data/Tests/DefaultTestConns.cs index 7c47bdd..5ad238b 100644 --- a/OpenSim/Data/Tests/DefaultTestConns.cs +++ b/OpenSim/Data/Tests/DefaultTestConns.cs @@ -39,16 +39,16 @@ namespace OpenSim.Data.Tests /// a connection string for testing one of the supported databases. /// The connections must be in the section [TestConnections] with names matching the connection class /// name for the specific database, e.g.: - /// + /// /// [TestConnections] /// MySqlConnection="..." /// SqlConnection="..." /// SqliteConnection="..." - /// + /// /// Note that the conn string may also be set explicitly in the [TestCase()] attribute of test classes /// based on BasicDataServiceTest.cs. /// - + static class DefaultTestConns { private static Dictionary conns = new Dictionary(); @@ -63,8 +63,8 @@ namespace OpenSim.Data.Tests Assembly asm = Assembly.GetExecutingAssembly(); string sType = connType.Name; - // Note: when running from NUnit, the DLL is located in some temp dir, so how do we get - // to the INI file? Ok, so put it into the resources! + // Note: when running from NUnit, the DLL is located in some temp dir, so how do we get + // to the INI file? Ok, so put it into the resources! // string iniName = Path.Combine(Path.GetDirectoryName(asm.Location), "TestDataConnections.ini"); string[] allres = asm.GetManifestResourceNames(); diff --git a/OpenSim/Data/Tests/EstateTests.cs b/OpenSim/Data/Tests/EstateTests.cs index e2b2d12..cf3f2b4 100644 --- a/OpenSim/Data/Tests/EstateTests.cs +++ b/OpenSim/Data/Tests/EstateTests.cs @@ -100,7 +100,7 @@ namespace OpenSim.Data.Tests public void T010_EstateSettingsSimpleStorage_MinimumParameterSet() { TestHelpers.InMethod(); - + EstateSettingsSimpleStorage( REGION_ID, DataTestUtil.STRING_MIN, @@ -133,7 +133,7 @@ namespace OpenSim.Data.Tests public void T011_EstateSettingsSimpleStorage_MaximumParameterSet() { TestHelpers.InMethod(); - + EstateSettingsSimpleStorage( REGION_ID, DataTestUtil.STRING_MAX(64), @@ -166,7 +166,7 @@ namespace OpenSim.Data.Tests public void T012_EstateSettingsSimpleStorage_AccurateParameterSet() { TestHelpers.InMethod(); - + EstateSettingsSimpleStorage( REGION_ID, DataTestUtil.STRING_MAX(1), @@ -199,7 +199,7 @@ namespace OpenSim.Data.Tests public void T012_EstateSettingsRandomStorage() { TestHelpers.InMethod(); - + // Letting estate store generate rows to database for us EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); new PropertyScrambler() @@ -220,7 +220,7 @@ namespace OpenSim.Data.Tests public void T020_EstateSettingsManagerList() { TestHelpers.InMethod(); - + // Letting estate store generate rows to database for us EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); @@ -241,7 +241,7 @@ namespace OpenSim.Data.Tests public void T021_EstateSettingsUserList() { TestHelpers.InMethod(); - + // Letting estate store generate rows to database for us EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); @@ -262,7 +262,7 @@ namespace OpenSim.Data.Tests public void T022_EstateSettingsGroupList() { TestHelpers.InMethod(); - + // Letting estate store generate rows to database for us EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); @@ -283,7 +283,7 @@ namespace OpenSim.Data.Tests public void T022_EstateSettingsBanList() { TestHelpers.InMethod(); - + // Letting estate store generate rows to database for us EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); @@ -310,7 +310,7 @@ namespace OpenSim.Data.Tests #endregion - #region Parametrizable Test Implementations + #region Parametrizable Test Implementations private void EstateSettingsSimpleStorage( UUID regionId, diff --git a/OpenSim/Data/Tests/InventoryTests.cs b/OpenSim/Data/Tests/InventoryTests.cs index 3edf89d..da6e7d4 100644 --- a/OpenSim/Data/Tests/InventoryTests.cs +++ b/OpenSim/Data/Tests/InventoryTests.cs @@ -44,14 +44,9 @@ using OpenSim.Data.SQLite; namespace OpenSim.Data.Tests { - [TestFixture(Description = "Inventory store tests (SQLite)")] - public class SQLiteInventoryTests : InventoryTests - { - } - [TestFixture(Description = "Inventory store tests (MySQL)")] public class MySqlInventoryTests : InventoryTests - { + { } public class InventoryTests : BasicDataServiceTest @@ -107,7 +102,7 @@ namespace OpenSim.Data.Tests public void T001_LoadEmpty() { TestHelpers.InMethod(); - + Assert.That(db.getInventoryFolder(zero), Is.Null); Assert.That(db.getInventoryFolder(folder1), Is.Null); Assert.That(db.getInventoryFolder(folder2), Is.Null); @@ -127,7 +122,7 @@ namespace OpenSim.Data.Tests public void T010_FolderNonParent() { TestHelpers.InMethod(); - + InventoryFolderBase f1 = NewFolder(folder2, folder1, owner1, name2); // the folder will go in db.addInventoryFolder(f1); @@ -139,7 +134,7 @@ namespace OpenSim.Data.Tests public void T011_FolderCreate() { TestHelpers.InMethod(); - + InventoryFolderBase f1 = NewFolder(folder1, zero, owner1, name1); // TODO: this is probably wrong behavior, but is what we have // db.updateInventoryFolder(f1); @@ -164,7 +159,7 @@ namespace OpenSim.Data.Tests public void T012_FolderList() { TestHelpers.InMethod(); - + InventoryFolderBase f2 = NewFolder(folder3, folder1, owner1, name3); db.addInventoryFolder(f2); @@ -180,7 +175,7 @@ namespace OpenSim.Data.Tests public void T013_FolderHierarchy() { TestHelpers.InMethod(); - + int n = db.getFolderHierarchy(zero).Count; // (for dbg - easier to see what's returned) Assert.That(n, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0))"); n = db.getFolderHierarchy(folder1).Count; @@ -195,7 +190,7 @@ namespace OpenSim.Data.Tests public void T014_MoveFolder() { TestHelpers.InMethod(); - + InventoryFolderBase f2 = db.getInventoryFolder(folder2); f2.ParentID = folder3; db.moveInventoryFolder(f2); @@ -211,7 +206,7 @@ namespace OpenSim.Data.Tests public void T015_FolderHierarchy() { TestHelpers.InMethod(); - + Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0))"); Assert.That(db.getFolderHierarchy(folder1).Count, Is.EqualTo(2), "Assert.That(db.getFolderHierarchy(folder1).Count, Is.EqualTo(2))"); Assert.That(db.getFolderHierarchy(folder2).Count, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(folder2).Count, Is.EqualTo(0))"); @@ -224,7 +219,7 @@ namespace OpenSim.Data.Tests public void T100_NoItems() { TestHelpers.InMethod(); - + Assert.That(db.getInventoryInFolder(zero).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(zero).Count, Is.EqualTo(0))"); Assert.That(db.getInventoryInFolder(folder1).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(folder1).Count, Is.EqualTo(0))"); Assert.That(db.getInventoryInFolder(folder2).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(folder2).Count, Is.EqualTo(0))"); @@ -238,7 +233,7 @@ namespace OpenSim.Data.Tests public void T101_CreatItems() { TestHelpers.InMethod(); - + db.addInventoryItem(NewItem(item1, folder3, owner1, iname1, asset1)); db.addInventoryItem(NewItem(item2, folder3, owner1, iname2, asset2)); db.addInventoryItem(NewItem(item3, folder3, owner1, iname3, asset3)); @@ -249,7 +244,7 @@ namespace OpenSim.Data.Tests public void T102_CompareItems() { TestHelpers.InMethod(); - + InventoryItemBase i1 = db.getInventoryItem(item1); InventoryItemBase i2 = db.getInventoryItem(item2); InventoryItemBase i3 = db.getInventoryItem(item3); @@ -268,7 +263,7 @@ namespace OpenSim.Data.Tests public void T103_UpdateItem() { TestHelpers.InMethod(); - + // TODO: probably shouldn't have the ability to have an // owner of an item in a folder not owned by the user @@ -288,7 +283,7 @@ namespace OpenSim.Data.Tests public void T104_RandomUpdateItem() { TestHelpers.InMethod(); - + PropertyScrambler folderScrambler = new PropertyScrambler() .DontScramble(x => x.Owner) @@ -347,7 +342,7 @@ namespace OpenSim.Data.Tests public void T999_StillNull() { TestHelpers.InMethod(); - + // After all tests are run, these should still return no results Assert.That(db.getInventoryFolder(zero), Is.Null); Assert.That(db.getInventoryItem(zero), Is.Null); diff --git a/OpenSim/Data/Tests/PropertyScrambler.cs b/OpenSim/Data/Tests/PropertyScrambler.cs index e0f5862..0d291df 100644 --- a/OpenSim/Data/Tests/PropertyScrambler.cs +++ b/OpenSim/Data/Tests/PropertyScrambler.cs @@ -42,7 +42,7 @@ namespace OpenSim.Data.Tests public class PropertyScrambler { readonly System.Collections.Generic.List membersToNotScramble = new List(); - + private void AddExpressionToNotScrableList(Expression expression) { UnaryExpression unaryExpression = expression as UnaryExpression; diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs index 8d4249a..4f81594 100644 --- a/OpenSim/Data/Tests/RegionTests.cs +++ b/OpenSim/Data/Tests/RegionTests.cs @@ -39,6 +39,7 @@ using OpenSim.Tests.Common; using log4net; using System.Reflection; using System.Data.Common; +using System.Threading; // DBMS-specific: using MySql.Data.MySqlClient; @@ -82,7 +83,7 @@ namespace OpenSim.Data.Tests public UUID item3 = UUID.Random(); public static Random random = new Random(); - + public string itemname1 = "item1"; public uint localID = 1; @@ -110,10 +111,10 @@ namespace OpenSim.Data.Tests private void ClearDB() { - string[] reg_tables = new string[] { - "prims", "primshapes", "primitems", "terrain", "land", "landaccesslist", "regionban", "regionsettings" + string[] reg_tables = new string[] { + "prims", "primshapes", "primitems", "terrain", "land", "landaccesslist", "regionban", "regionsettings" }; - + if (m_rebuildDB) { DropTables(reg_tables); @@ -144,7 +145,7 @@ namespace OpenSim.Data.Tests public void T001_LoadEmpty() { TestHelpers.InMethod(); - + List objs = db.LoadObjects(region1); List objs3 = db.LoadObjects(region3); List land = db.LoadLandObjects(region1); @@ -153,21 +154,21 @@ namespace OpenSim.Data.Tests Assert.That(objs3.Count, Is.EqualTo(0), "Assert.That(objs3.Count, Is.EqualTo(0))"); Assert.That(land.Count, Is.EqualTo(0), "Assert.That(land.Count, Is.EqualTo(0))"); } - + // SOG round trips // * store objects, make sure they save - // * update + // * update [Test] public void T010_StoreSimpleObject() { TestHelpers.InMethod(); - + SceneObjectGroup sog = NewSOG("object1", prim1, region1); SceneObjectGroup sog2 = NewSOG("object2", prim2, region1); // in case the objects don't store - try + try { db.StoreObject(sog, region1); } @@ -176,8 +177,8 @@ namespace OpenSim.Data.Tests m_log.Error(e.ToString()); Assert.Fail(); } - - try + + try { db.StoreObject(sog2, region1); } @@ -189,15 +190,15 @@ namespace OpenSim.Data.Tests // This tests the ADO.NET driver List objs = db.LoadObjects(region1); - + Assert.That(objs.Count, Is.EqualTo(2), "Assert.That(objs.Count, Is.EqualTo(2))"); } - + [Test] public void T011_ObjectNames() { TestHelpers.InMethod(); - + List objs = db.LoadObjects(region1); foreach (SceneObjectGroup sog in objs) { @@ -206,12 +207,12 @@ namespace OpenSim.Data.Tests Assert.That(p.Name, Is.EqualTo(p.Description), "Assert.That(p.Name, Is.EqualTo(p.Description))"); } } - + [Test] public void T012_SceneParts() { TestHelpers.InMethod(); - + UUID tmp0 = UUID.Random(); UUID tmp1 = UUID.Random(); UUID tmp2 = UUID.Random(); @@ -224,10 +225,10 @@ namespace OpenSim.Data.Tests sog.AddPart(p1); sog.AddPart(p2); sog.AddPart(p3); - + SceneObjectPart[] parts = sog.Parts; Assert.That(parts.Length,Is.EqualTo(4), "Assert.That(parts.Length,Is.EqualTo(4))"); - + db.StoreObject(sog, newregion); List sogs = db.LoadObjects(newregion); Assert.That(sogs.Count,Is.EqualTo(1), "Assert.That(sogs.Count,Is.EqualTo(1))"); @@ -235,18 +236,18 @@ namespace OpenSim.Data.Tests SceneObjectPart[] newparts = newsog.Parts; Assert.That(newparts.Length,Is.EqualTo(4), "Assert.That(newparts.Length,Is.EqualTo(4))"); - + Assert.That(newsog.ContainsPart(tmp0), "Assert.That(newsog.ContainsPart(tmp0))"); Assert.That(newsog.ContainsPart(tmp1), "Assert.That(newsog.ContainsPart(tmp1))"); Assert.That(newsog.ContainsPart(tmp2), "Assert.That(newsog.ContainsPart(tmp2))"); Assert.That(newsog.ContainsPart(tmp3), "Assert.That(newsog.ContainsPart(tmp3))"); } - + [Test] public void T013_DatabasePersistency() { TestHelpers.InMethod(); - + // Sets all ScenePart parameters, stores and retrieves them, then check for consistency with initial data // The commented Asserts are the ones that are unchangeable (when storing on the database, their "Set" values are ignored // The ObjectFlags is an exception, if it is entered incorrectly, the object IS REJECTED on the database silently. @@ -259,7 +260,7 @@ namespace OpenSim.Data.Tests uint localid = localID+1; localID = localID + 1; string name = "Adam West"; - byte material = (byte) random.Next(127); + byte material = (byte) random.Next((int)SOPMaterialData.MaxMaterial); ulong regionh = (ulong)random.NextDouble() * (ulong)random.Next(); int pin = random.Next(); Byte[] partsys = new byte[8]; @@ -297,7 +298,7 @@ namespace OpenSim.Data.Tests SceneObjectPart sop = new SceneObjectPart(); SceneObjectGroup sog = new SceneObjectGroup(sop); - + sop.RegionHandle = regionh; sop.UUID = uuid; sop.LocalId = localid; @@ -359,10 +360,10 @@ namespace OpenSim.Data.Tests Assert.That(linknum,Is.EqualTo(sop.LinkNum), "Assert.That(linknum,Is.EqualTo(sop.LinkNum))"); Assert.That(clickaction,Is.EqualTo(sop.ClickAction), "Assert.That(clickaction,Is.EqualTo(sop.ClickAction))"); Assert.That(scale,Is.EqualTo(sop.Scale), "Assert.That(scale,Is.EqualTo(sop.Scale))"); - + // This is necessary or object will not be inserted in DB sop.Flags = PrimFlags.None; - + // Inserts group in DB db.StoreObject(sog,region3); List sogs = db.LoadObjects(region3); @@ -371,7 +372,7 @@ namespace OpenSim.Data.Tests db.StoreObject(sog,region3); sogs = db.LoadObjects(region3); Assert.That(sogs.Count, Is.EqualTo(1), "Assert.That(sogs.Count, Is.EqualTo(1))"); - + // Tests if the parameters were inserted correctly SceneObjectPart p = sogs[0].RootPart; @@ -413,12 +414,12 @@ namespace OpenSim.Data.Tests Assert.That(pbshap.ProfileEnd, Is.EqualTo(p.Shape.ProfileEnd), "Assert.That(pbshap.ProfileEnd, Is.EqualTo(p.Shape.ProfileEnd))"); Assert.That(pbshap.ProfileHollow, Is.EqualTo(p.Shape.ProfileHollow), "Assert.That(pbshap.ProfileHollow, Is.EqualTo(p.Shape.ProfileHollow))"); } - + [Test] public void T014_UpdateObject() { TestHelpers.InMethod(); - + string text1 = "object1 text"; SceneObjectGroup sog = FindSOG("object1", region1); sog.RootPart.Text = text1; @@ -433,7 +434,7 @@ namespace OpenSim.Data.Tests TaskInventoryDictionary dic = new TaskInventoryDictionary(); localID = localID + 1; string name = "West Adam"; - byte material = (byte) random.Next(127); + byte material = (byte) random.Next((int)SOPMaterialData.MaxMaterial); ulong regionh = (ulong)random.NextDouble() * (ulong)random.Next(); int pin = random.Next(); Byte[] partsys = new byte[8]; @@ -458,7 +459,7 @@ namespace OpenSim.Data.Tests PrimitiveBaseShape pbshap = new PrimitiveBaseShape(); pbshap = PrimitiveBaseShape.Default; Vector3 scale = new Vector3(random.Next(),random.Next(),random.Next()); - + // Updates the region with new values SceneObjectGroup sog2 = FindSOG("Adam West", region3); Assert.That(sog2,Is.Not.Null); @@ -487,11 +488,11 @@ namespace OpenSim.Data.Tests sog2.RootPart.LinkNum = linknum; sog2.RootPart.ClickAction = clickaction; sog2.RootPart.Scale = scale; - + db.StoreObject(sog2, region3); List sogs = db.LoadObjects(region3); Assert.That(sogs.Count, Is.EqualTo(1), "Assert.That(sogs.Count, Is.EqualTo(1))"); - + SceneObjectGroup retsog = FindSOG("West Adam", region3); Assert.That(retsog,Is.Not.Null); SceneObjectPart p = retsog.RootPart; @@ -518,7 +519,7 @@ namespace OpenSim.Data.Tests Assert.That(clickaction,Is.EqualTo(p.ClickAction), "Assert.That(clickaction,Is.EqualTo(p.ClickAction))"); Assert.That(scale,Is.EqualTo(p.Scale), "Assert.That(scale,Is.EqualTo(p.Scale))"); } - + /// /// Test storage and retrieval of a scene object with a large number of parts. /// @@ -526,12 +527,12 @@ namespace OpenSim.Data.Tests public void T015_LargeSceneObjects() { TestHelpers.InMethod(); - + UUID id = UUID.Random(); Dictionary mydic = new Dictionary(); SceneObjectGroup sog = NewSOG("Test SOG", id, region4); mydic.Add(sog.RootPart.UUID,sog.RootPart); - for (int i = 0; i < 30; i++) + for (int i = 0; i < 30; i++) { UUID tmp = UUID.Random(); SceneObjectPart sop = NewSOP(("Test SOP " + i.ToString()),tmp); @@ -541,20 +542,20 @@ namespace OpenSim.Data.Tests Vector3 velocity = new Vector3(random.Next(),random.Next(),random.Next()); Vector3 angvelo = new Vector3(random.Next(),random.Next(),random.Next()); Vector3 accel = new Vector3(random.Next(),random.Next(),random.Next()); - + sop.GroupPosition = groupos; sop.RotationOffset = rotoff; sop.OffsetPosition = offset; sop.Velocity = velocity; sop.AngularVelocity = angvelo; sop.Acceleration = accel; - + mydic.Add(tmp,sop); - sog.AddPart(sop); + sog.AddPart(sop); } - + db.StoreObject(sog, region4); - + SceneObjectGroup retsog = FindSOG("Test SOG", region4); SceneObjectPart[] parts = retsog.Parts; for (int i = 0; i < 30; i++) @@ -573,7 +574,7 @@ namespace OpenSim.Data.Tests public void T016_RandomSogWithSceneParts() { TestHelpers.InMethod(); - + PropertyScrambler scrambler = new PropertyScrambler() .DontScramble(x => x.UUID); @@ -633,22 +634,22 @@ namespace OpenSim.Data.Tests SceneObjectGroup sog = FindSOG(name, region1); if (sog == null) { - sog = NewSOG(name, prim1, region1); + sog = NewSOG(name, prim1, region1); db.StoreObject(sog, region1); } return sog; } - + // NOTE: it is a bad practice to rely on some of the previous tests having been run before. // If the tests are run manually, one at a time, each starts with full class init (DB cleared). // Even when all tests are run, NUnit 2.5+ no longer guarantee a specific test order. // We shouldn't expect to find anything in the DB if we haven't put it there *in the same test*! - + [Test] public void T020_PrimInventoryEmpty() { TestHelpers.InMethod(); - + SceneObjectGroup sog = GetMySOG("object1"); TaskInventoryItem t = sog.GetInventoryItem(sog.RootPart.LocalId, item1); Assert.That(t, Is.Null); @@ -672,14 +673,14 @@ namespace OpenSim.Data.Tests public void T021_PrimInventoryBasic() { TestHelpers.InMethod(); - + SceneObjectGroup sog = GetMySOG("object1"); InventoryItemBase i = NewItem(item1, zero, zero, itemname1, zero); Assert.That(sog.AddInventoryItem(zero, sog.RootPart.LocalId, i, zero), Is.True); TaskInventoryItem t = sog.GetInventoryItem(sog.RootPart.LocalId, item1); Assert.That(t.Name, Is.EqualTo(itemname1), "Assert.That(t.Name, Is.EqualTo(itemname1))"); - + StoreInventory(sog); SceneObjectGroup sog1 = FindSOG("object1", region1); @@ -707,12 +708,12 @@ namespace OpenSim.Data.Tests t = sog.GetInventoryItem(sog.RootPart.LocalId, item1); Assert.That(t, Is.Null); } - + [Test] public void T025_PrimInventoryPersistency() { TestHelpers.InMethod(); - + InventoryItemBase i = new InventoryItemBase(); UUID id = UUID.Random(); i.ID = id; @@ -751,11 +752,11 @@ namespace OpenSim.Data.Tests i.Flags = flags; int creationd = random.Next(); i.CreationDate = creationd; - + SceneObjectGroup sog = GetMySOG("object1"); Assert.That(sog.AddInventoryItem(zero, sog.RootPart.LocalId, i, zero), Is.True); TaskInventoryItem t = sog.GetInventoryItem(sog.RootPart.LocalId, id); - + Assert.That(t.Name, Is.EqualTo(name), "Assert.That(t.Name, Is.EqualTo(name))"); Assert.That(t.AssetID,Is.EqualTo(assetid), "Assert.That(t.AssetID,Is.EqualTo(assetid))"); Assert.That(t.BasePermissions,Is.EqualTo(baseperm), "Assert.That(t.BasePermissions,Is.EqualTo(baseperm))"); @@ -779,13 +780,13 @@ namespace OpenSim.Data.Tests Assert.That(t.ParentID,Is.EqualTo(sog.RootPart.FolderID), "Assert.That(t.ParentID,Is.EqualTo(sog.RootPart.FolderID))"); Assert.That(t.ParentPartID,Is.EqualTo(sog.RootPart.UUID), "Assert.That(t.ParentPartID,Is.EqualTo(sog.RootPart.UUID))"); } - + [Test] [ExpectedException(typeof(ArgumentException))] public void T026_PrimInventoryMany() { TestHelpers.InMethod(); - + UUID i1,i2,i3,i4; i1 = UUID.Random(); i2 = UUID.Random(); @@ -795,14 +796,14 @@ namespace OpenSim.Data.Tests InventoryItemBase ib2 = NewItem(i2, zero, zero, RandomName(), zero); InventoryItemBase ib3 = NewItem(i3, zero, zero, RandomName(), zero); InventoryItemBase ib4 = NewItem(i4, zero, zero, RandomName(), zero); - + SceneObjectGroup sog = FindSOG("object1", region1); Assert.That(sog.AddInventoryItem(zero, sog.RootPart.LocalId, ib1, zero), Is.True); Assert.That(sog.AddInventoryItem(zero, sog.RootPart.LocalId, ib2, zero), Is.True); Assert.That(sog.AddInventoryItem(zero, sog.RootPart.LocalId, ib3, zero), Is.True); Assert.That(sog.AddInventoryItem(zero, sog.RootPart.LocalId, ib4, zero), Is.True); - + TaskInventoryItem t1 = sog.GetInventoryItem(sog.RootPart.LocalId, i1); Assert.That(t1.Name, Is.EqualTo(ib1.Name), "Assert.That(t1.Name, Is.EqualTo(ib1.Name))"); TaskInventoryItem t2 = sog.GetInventoryItem(sog.RootPart.LocalId, i2); @@ -817,7 +818,7 @@ namespace OpenSim.Data.Tests public void T052_RemoveObject() { TestHelpers.InMethod(); - + db.RemoveObject(prim1, region1); SceneObjectGroup sog = FindSOG("object1", region1); Assert.That(sog, Is.Null); @@ -827,7 +828,7 @@ namespace OpenSim.Data.Tests public void T100_DefaultRegionInfo() { TestHelpers.InMethod(); - + RegionSettings r1 = db.LoadRegionSettings(region1); Assert.That(r1.RegionUUID, Is.EqualTo(region1), "Assert.That(r1.RegionUUID, Is.EqualTo(region1))"); @@ -839,7 +840,7 @@ namespace OpenSim.Data.Tests public void T101_UpdateRegionInfo() { TestHelpers.InMethod(); - + int agentlimit = random.Next(); double objectbonus = random.Next(); int maturity = random.Next(); @@ -899,9 +900,9 @@ namespace OpenSim.Data.Tests r1.FixedSun = true; r1.SunPosition = sunpos; r1.Covenant = cov; - + db.StoreRegionSettings(r1); - + RegionSettings r1a = db.LoadRegionSettings(region1); Assert.That(r1a.RegionUUID, Is.EqualTo(region1), "Assert.That(r1a.RegionUUID, Is.EqualTo(region1))"); Assert.That(r1a.BlockTerraform,Is.True); @@ -938,14 +939,14 @@ namespace OpenSim.Data.Tests //Assert.That(r1a.TerrainImageID,Is.EqualTo(terimgid), "Assert.That(r1a.TerrainImageID,Is.EqualTo(terimgid))"); Assert.That(r1a.FixedSun,Is.True); Assert.That(r1a.SunPosition, Is.EqualTo(sunpos), "Assert.That(r1a.SunPosition, Is.EqualTo(sunpos))"); - Assert.That(r1a.Covenant, Is.EqualTo(cov), "Assert.That(r1a.Covenant, Is.EqualTo(cov))"); + Assert.That(r1a.Covenant, Is.EqualTo(cov), "Assert.That(r1a.Covenant, Is.EqualTo(cov))"); } [Test] public void T300_NoTerrain() { TestHelpers.InMethod(); - + Assert.That(db.LoadTerrain(zero), Is.Null); Assert.That(db.LoadTerrain(region1), Is.Null); Assert.That(db.LoadTerrain(region2), Is.Null); @@ -956,10 +957,13 @@ namespace OpenSim.Data.Tests public void T301_CreateTerrain() { TestHelpers.InMethod(); - + double[,] t1 = GenTerrain(height1); db.StoreTerrain(t1, region1); - + + // store terrain is async + Thread.Sleep(1000); + Assert.That(db.LoadTerrain(zero), Is.Null); Assert.That(db.LoadTerrain(region1), Is.Not.Null); Assert.That(db.LoadTerrain(region2), Is.Null); @@ -970,7 +974,7 @@ namespace OpenSim.Data.Tests public void T302_FetchTerrain() { TestHelpers.InMethod(); - + double[,] baseterrain1 = GenTerrain(height1); double[,] baseterrain2 = GenTerrain(height2); double[,] t1 = db.LoadTerrain(region1); @@ -982,11 +986,14 @@ namespace OpenSim.Data.Tests public void T303_UpdateTerrain() { TestHelpers.InMethod(); - + double[,] baseterrain1 = GenTerrain(height1); double[,] baseterrain2 = GenTerrain(height2); db.StoreTerrain(baseterrain2, region1); + // store terrain is async + Thread.Sleep(1000); + double[,] t1 = db.LoadTerrain(region1); Assert.That(CompareTerrain(t1, baseterrain1), Is.False); Assert.That(CompareTerrain(t1, baseterrain2), Is.True); @@ -996,7 +1003,7 @@ namespace OpenSim.Data.Tests public void T400_EmptyLand() { TestHelpers.InMethod(); - + Assert.That(db.LoadLandObjects(zero).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(zero).Count, Is.EqualTo(0))"); Assert.That(db.LoadLandObjects(region1).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(region1).Count, Is.EqualTo(0))"); Assert.That(db.LoadLandObjects(region2).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(region2).Count, Is.EqualTo(0))"); @@ -1018,15 +1025,15 @@ namespace OpenSim.Data.Tests for (int x = 0; x < Constants.RegionSize; x++) for (int y = 0; y < Constants.RegionSize; y++) terret[x,y] = value; - + return terret; } - + private bool CompareTerrain(double[,] one, double[,] two) { for (int x = 0; x < Constants.RegionSize; x++) for (int y = 0; y < Constants.RegionSize; y++) - if (one[x,y] != two[x,y]) + if (one[x,y] != two[x,y]) return false; return true; @@ -1046,12 +1053,12 @@ namespace OpenSim.Data.Tests // common failure case is people adding new fields that aren't // initialized, but have non-null db constraints. We should // honestly be passing more and more null things in here. - // - // Please note that in Sqlite.BuildPrim there is a commented out inline version + // + // Please note that in Sqlite.BuildPrim there is a commented out inline version // of this so you can debug and step through the build process and check the fields - // + // // Real World Value: Tests for situation where extending a SceneObjectGroup/SceneObjectPart - // causes the application to crash at the database layer because of null values + // causes the application to crash at the database layer because of null values // in NOT NULL fields // private SceneObjectGroup NewSOG(string name, UUID uuid, UUID regionId) @@ -1075,7 +1082,7 @@ namespace OpenSim.Data.Tests return sog; } - + private SceneObjectPart NewSOP(string name, UUID uuid) { SceneObjectPart sop = new SceneObjectPart(); @@ -1089,7 +1096,7 @@ namespace OpenSim.Data.Tests return sop; } - // These are copied from the Inventory Item tests + // These are copied from the Inventory Item tests private InventoryItemBase NewItem(UUID id, UUID parent, UUID owner, string name, UUID asset) { @@ -1107,7 +1114,7 @@ namespace OpenSim.Data.Tests private static string RandomName() { StringBuilder name = new StringBuilder(); - int size = random.Next(5,12); + int size = random.Next(5,12); char ch ; for (int i=0; i - /// Number given to the client when they log-in that they provide + /// Number given to the client when they log-in that they provide /// as credentials to the UDP server /// public uint circuitcode; @@ -184,7 +184,7 @@ namespace OpenSim.Framework /// Pack AgentCircuitData into an OSDMap for transmission over LLSD XML or LLSD json /// /// map of the agent circuit data - public OSDMap PackAgentCircuitData() + public OSDMap PackAgentCircuitData(EntityTransferContext ctx) { OSDMap args = new OSDMap(); args["agent_id"] = OSD.FromUUID(AgentID); @@ -224,7 +224,7 @@ namespace OpenSim.Framework { args["appearance_serial"] = OSD.FromInteger(Appearance.Serial); - OSDMap appmap = Appearance.Pack(); + OSDMap appmap = Appearance.Pack(ctx); args["packed_appearance"] = appmap; } @@ -328,7 +328,7 @@ namespace OpenSim.Framework Vector3.TryParse(args["start_pos"].AsString(), out startpos); //m_log.InfoFormat("[AGENTCIRCUITDATA]: agentid={0}, child={1}, startpos={2}", AgentID, child, startpos); - + try { // Unpack various appearance elements @@ -353,7 +353,7 @@ namespace OpenSim.Framework { m_log.ErrorFormat("[AGENTCIRCUITDATA] failed to unpack appearance; {0}",e.Message); } - + ServiceURLs = new Dictionary(); // Try parse the new way, OSDMap if (args.ContainsKey("serviceurls") && args["serviceurls"] != null && (args["serviceurls"]).Type == OSDType.Map) diff --git a/OpenSim/Framework/AgentUpdateArgs.cs b/OpenSim/Framework/AgentUpdateArgs.cs index 660bc32..f04d692 100644 --- a/OpenSim/Framework/AgentUpdateArgs.cs +++ b/OpenSim/Framework/AgentUpdateArgs.cs @@ -81,6 +81,8 @@ namespace OpenSim.Framework public Vector3 ClientAgentPosition; public bool UseClientAgentPosition; + public bool NeedsCameraCollision; + public uint lastpacketSequence; public AgentUpdateArgs() { diff --git a/OpenSim/Framework/AnimationSet.cs b/OpenSim/Framework/AnimationSet.cs new file mode 100644 index 0000000..8753088 --- /dev/null +++ b/OpenSim/Framework/AnimationSet.cs @@ -0,0 +1,186 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; + +namespace OpenSim.Framework +{ +// public delegate bool AnimationSetValidator(UUID animID); + public delegate uint AnimationSetValidator(UUID animID); + + public class AnimationSet + { + private bool m_parseError = false; + + public const uint createBasePermitions = (uint)(PermissionMask.All); // no export ? + public const uint createNextPermitions = (uint)(PermissionMask.Copy | PermissionMask.Modify); + + public const uint allowedBasePermitions = (uint)(PermissionMask.Copy | PermissionMask.Modify); + public const uint allowedNextPermitions = 0; + + public static void setCreateItemPermitions(InventoryItemBase it) + { + if (it == null) + return; + + it.BasePermissions = createBasePermitions; + it.CurrentPermissions = createBasePermitions; + // it.GroupPermissions &= allowedPermitions; + it.NextPermissions = createNextPermitions; + // it.EveryOnePermissions &= allowedPermitions; + it.GroupPermissions = 0; + it.EveryOnePermissions = 0; + } + + public static void enforceItemPermitions(InventoryItemBase it, bool IsCreator) + { + if (it == null) + return; + + uint bp; + uint np; + + if (IsCreator) + { + bp = createBasePermitions; + np = createNextPermitions; + } + else + { + bp = allowedBasePermitions; + np = allowedNextPermitions; + } + + it.BasePermissions &= bp; + it.CurrentPermissions &= bp; + // it.GroupPermissions &= allowedPermitions; + it.NextPermissions &= np; + // it.EveryOnePermissions &= allowedPermitions; + it.GroupPermissions = 0; + it.EveryOnePermissions = 0; + } + + public int AnimationCount { get; private set; } + private Dictionary> m_animations = new Dictionary>(); + + public UUID GetAnimation(string index) + { + KeyValuePair val; + if (m_animations.TryGetValue(index, out val)) + return val.Value; + + return UUID.Zero; + } + + public string GetAnimationName(string index) + { + KeyValuePair val; + if (m_animations.TryGetValue(index, out val)) + return val.Key; + + return String.Empty; + } + + public void SetAnimation(string index, string name, UUID anim) + { + if (anim == UUID.Zero) + { + m_animations.Remove(index); + return; + } + + m_animations[index] = new KeyValuePair(name, anim); + } + + public AnimationSet(Byte[] data) + { + string assetData = System.Text.Encoding.ASCII.GetString(data); + Console.WriteLine("--------------------"); + Console.WriteLine("AnimationSet length {0} bytes", assetData.Length); + Console.WriteLine(assetData); + Console.WriteLine("--------------------"); + } + + public Byte[] ToBytes() + { + // If there was an error parsing the input, we give back an + // empty set rather than the original data. + if (m_parseError) + { + string dummy = "version 1\ncount 0\n"; + return System.Text.Encoding.ASCII.GetBytes(dummy); + } + + string assetData = String.Format("version 1\ncount {0}\n", m_animations.Count); + foreach (KeyValuePair> kvp in m_animations) + assetData += String.Format("{0} {1} {2}\n", kvp.Key, kvp.Value.Value.ToString(), kvp.Value.Key); + return System.Text.Encoding.ASCII.GetBytes(assetData); + } +/* + public bool Validate(AnimationSetValidator val) + { + if (m_parseError) + return false; + + List badAnims = new List(); + + bool allOk = true; + foreach (KeyValuePair> kvp in m_animations) + { + if (!val(kvp.Value.Value)) + { + allOk = false; + badAnims.Add(kvp.Key); + } + } + + foreach (string idx in badAnims) + m_animations.Remove(idx); + + return allOk; + } +*/ + public uint Validate(AnimationSetValidator val) + { + if (m_parseError) + return 0; + + uint ret = 0x7fffffff; + uint t; + foreach (KeyValuePair> kvp in m_animations) + { + t = val(kvp.Value.Value); + if (t == 0) + return 0; + ret &= t; + } + return ret; + } + } +} diff --git a/OpenSim/Framework/AssemblyInfo.cs b/OpenSim/Framework/AssemblyInfo.cs index a797424..c4835be 100644 --- a/OpenSim/Framework/AssemblyInfo.cs +++ b/OpenSim/Framework/AssemblyInfo.cs @@ -59,4 +59,4 @@ using System.Runtime.InteropServices; // Revision // -[assembly : AssemblyVersion("0.8.2.*")] +[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] diff --git a/OpenSim/Framework/AssetBase.cs b/OpenSim/Framework/AssetBase.cs index 2f04d2e..88edf2f 100644 --- a/OpenSim/Framework/AssetBase.cs +++ b/OpenSim/Framework/AssetBase.cs @@ -63,6 +63,8 @@ namespace OpenSim.Framework /// private AssetMetadata m_metadata; + private int m_uploadAttempts; + // This is needed for .NET serialization!!! // Do NOT "Optimize" away! public AssetBase() @@ -110,7 +112,7 @@ namespace OpenSim.Framework { get { - return + return IsTextualAsset && ( Type != (sbyte)AssetType.Notecard && Type != (sbyte)AssetType.CallingCard @@ -135,7 +137,7 @@ namespace OpenSim.Framework { get { - return + return (Type == (sbyte)AssetType.Animation || Type == (sbyte)AssetType.Gesture || Type == (sbyte)AssetType.Simstate || @@ -148,11 +150,12 @@ namespace OpenSim.Framework Type == (sbyte)AssetType.Folder || Type == (sbyte)AssetType.ImageJPEG || Type == (sbyte)AssetType.ImageTGA || - Type == (sbyte)AssetType.LSLBytecode); + Type == (sbyte)AssetType.Mesh || + Type == (sbyte) AssetType.LSLBytecode); } } - public virtual byte[] Data + public byte[] Data { get { return m_data; } set { m_data = value; } @@ -197,6 +200,12 @@ namespace OpenSim.Framework set { m_metadata.Type = value; } } + public int UploadAttempts + { + get { return m_uploadAttempts; } + set { m_uploadAttempts = value; } + } + /// /// Is this a region only asset, or does this exist on the asset server also /// @@ -273,7 +282,7 @@ namespace OpenSim.Framework return m_id; } - + set { UUID uuid = UUID.Zero; diff --git a/OpenSim/Framework/AssetLoader/Filesystem/Properties/AssemblyInfo.cs b/OpenSim/Framework/AssetLoader/Filesystem/Properties/AssemblyInfo.cs index 76df564..b6ea077 100644 --- a/OpenSim/Framework/AssetLoader/Filesystem/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/AssetLoader/Filesystem/Properties/AssemblyInfo.cs @@ -2,7 +2,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("OpenSim.Framework.AssetLoader.Filesystem")] @@ -14,8 +14,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] @@ -25,9 +25,9 @@ using System.Runtime.InteropServices; // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("0.8.3.*")] +[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] diff --git a/OpenSim/Framework/AssetRequestToClient.cs b/OpenSim/Framework/AssetRequestToClient.cs index d602c1f..3dfbb91 100644 --- a/OpenSim/Framework/AssetRequestToClient.cs +++ b/OpenSim/Framework/AssetRequestToClient.cs @@ -31,10 +31,10 @@ namespace OpenSim.Framework { /// /// This class was created to refactor OutPacket out of AssetCache - /// There is a conflict between + /// There is a conflict between /// OpenSim.Framework.Communications.Cache.AssetRequest and OpenSim.Framework.AssetRequest - /// and unifying them results in a prebuild chicken and egg problem with OpenSim.Framework requiring - /// OpenSim.Framework.Communications.Cache while OpenSim.Framework.Communications.Cache + /// and unifying them results in a prebuild chicken and egg problem with OpenSim.Framework requiring + /// OpenSim.Framework.Communications.Cache while OpenSim.Framework.Communications.Cache /// requiring OpenSim.Framework /// public class AssetRequestToClient diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 26dd5df..77a7621 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -53,7 +53,11 @@ namespace OpenSim.Framework // should be only used as initial default value ( V1 viewers ) public readonly static int VISUALPARAM_COUNT = 218; - public readonly static int TEXTURE_COUNT = 21; +// public readonly static int TEXTURE_COUNT = 21 + // 21 bad, make it be updated as libovm gets update + // also keeping in sync with it + public readonly static int TEXTURE_COUNT = Primitive.TextureEntry.MAX_FACES; + public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; protected int m_serial = 0; @@ -69,8 +73,6 @@ namespace OpenSim.Framework protected WearableCacheItem[] m_cacheitems; protected bool m_cacheItemsDirty = true; - - public bool PackLegacyWearables {get; set; } public virtual int Serial { get { return m_serial; } @@ -119,7 +121,7 @@ namespace OpenSim.Framework get { return m_avatarHeight; } set { m_avatarHeight = value; } } - + public virtual WearableCacheItem[] WearableCacheItems { get { return m_cacheitems; } @@ -135,7 +137,7 @@ namespace OpenSim.Framework public AvatarAppearance() { // m_log.WarnFormat("[AVATAR APPEARANCE]: create empty appearance"); - PackLegacyWearables = false; + m_serial = 0; SetDefaultWearables(); SetDefaultTexture(); @@ -181,11 +183,16 @@ namespace OpenSim.Framework m_attachments = new Dictionary>(); } - public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true) + public AvatarAppearance(AvatarAppearance appearance): this(appearance, true,true) { } public AvatarAppearance(AvatarAppearance appearance, bool copyWearables) + : this(appearance, copyWearables, true) + { + } + + public AvatarAppearance(AvatarAppearance appearance, bool copyWearables, bool copyBaked) { // m_log.WarnFormat("[AVATAR APPEARANCE] create from an existing appearance"); @@ -204,24 +211,29 @@ namespace OpenSim.Framework m_serial = appearance.Serial; - m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; - for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) - m_wearables[i] = new AvatarWearable(); - if (copyWearables && (appearance.Wearables != null)) { - int len = appearance.Wearables.Length; - if(len > AvatarWearable.MAX_WEARABLES) - len = AvatarWearable.MAX_WEARABLES; - for (int i = 0; i < len; i++) - SetWearable(i,appearance.Wearables[i]); + m_wearables = new AvatarWearable[appearance.Wearables.Length]; + for (int i = 0; i < appearance.Wearables.Length; i++) + { + m_wearables[i] = new AvatarWearable(); + AvatarWearable wearable = appearance.Wearables[i]; + for (int j = 0; j < wearable.Count; j++) + m_wearables[i].Add(wearable[j].ItemID, wearable[j].AssetID); + } } + else + ClearWearables(); m_texture = null; if (appearance.Texture != null) { byte[] tbytes = appearance.Texture.GetBytes(); m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length); + if (copyBaked && appearance.m_cacheitems != null) + m_cacheitems = (WearableCacheItem[])appearance.m_cacheitems.Clone(); + else + m_cacheitems = null; } m_visualparams = null; @@ -239,9 +251,17 @@ namespace OpenSim.Framework public void GetAssetsFrom(AvatarAppearance app) { - for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) + int len = m_wearables.Length; + if(len > app.m_wearables.Length) + len = app.m_wearables.Length; + + for (int i = 0; i < len; i++) { - for (int j = 0; j < m_wearables[i].Count; j++) + int count = m_wearables[i].Count; + if(count > app.m_wearables[i].Count) + count = app.m_wearables[i].Count; + + for (int j = 0; j < count; j++) { UUID itemID = m_wearables[i][j].ItemID; UUID assetID = app.Wearables[i].GetAsset(itemID); @@ -254,8 +274,8 @@ namespace OpenSim.Framework public void ClearWearables() { - m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; - for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) + m_wearables = new AvatarWearable[AvatarWearable.LEGACY_VERSION_MAX_WEARABLES]; + for (int i = 0; i < AvatarWearable.LEGACY_VERSION_MAX_WEARABLES; i++) m_wearables[i] = new AvatarWearable(); } @@ -271,18 +291,18 @@ namespace OpenSim.Framework public virtual void ResetAppearance() { // m_log.WarnFormat("[AVATAR APPEARANCE]: Reset appearance"); - + m_serial = 0; SetDefaultTexture(); - + //for (int i = 0; i < BAKE_INDICES.Length; i++) // { // int idx = BAKE_INDICES[i]; // m_texture.FaceTextures[idx].TextureID = UUID.Zero; // } } - + protected virtual void SetDefaultParams() { m_visualparams = new byte[] { 33,61,85,23,58,127,63,85,63,42,0,85,63,36,85,95,153,63,34,0,63,109,88,132,63,136,81,85,103,136,127,0,150,150,150,127,0,0,0,0,0,127,0,0,255,127,114,127,99,63,127,140,127,127,0,0,0,191,0,104,0,0,0,0,0,0,0,0,0,145,216,133,0,127,0,127,170,0,0,127,127,109,85,127,127,63,85,42,150,150,150,150,150,150,150,25,150,150,150,0,127,0,0,144,85,127,132,127,85,0,127,127,127,127,127,127,59,127,85,127,127,106,47,79,127,127,204,2,141,66,0,0,127,127,0,0,0,0,127,0,159,0,0,178,127,36,85,131,127,127,127,153,95,0,140,75,27,127,127,0,150,150,198,0,0,63,30,127,165,209,198,127,127,153,204,51,51,255,255,255,204,0,255,150,150,150,150,150,150,150,150,150,150,0,150,150,150,150,150,0,127,127,150,150,150,150,150,150,150,150,0,0,150,51,132,150,150,150 }; @@ -299,14 +319,14 @@ namespace OpenSim.Framework public virtual void ResetBakedTextures() { SetDefaultTexture(); - + //for (int i = 0; i < BAKE_INDICES.Length; i++) // { // int idx = BAKE_INDICES[i]; // m_texture.FaceTextures[idx].TextureID = UUID.Zero; // } } - + protected virtual void SetDefaultTexture() { m_texture = new Primitive.TextureEntry(new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE)); @@ -351,7 +371,7 @@ namespace OpenSim.Framework } m_texture = textureEntry; - + return changed; } @@ -462,12 +482,16 @@ namespace OpenSim.Framework // DEBUG ON // m_log.WarnFormat("[AVATARAPPEARANCE] set wearable {0} --> {1}:{2}",wearableId,wearable.ItemID,wearable.AssetID); // DEBUG OFF + if (wearableId >= m_wearables.Length) + { + int currentLength = m_wearables.Length; + Array.Resize(ref m_wearables, wearableId + 1); + for (int i = currentLength ; i < m_wearables.Length ; i++) + m_wearables[i] = new AvatarWearable(); + } m_wearables[wearableId].Clear(); - int count = wearable.Count; - if (count > AvatarWearable.MAX_WEARABLES) - count = AvatarWearable.MAX_WEARABLES; - for (int i = 0; i < count; i++) - m_wearables[wearableId].Add(wearable[i].ItemID, wearable[i].AssetID); + for (int i = 0; i < wearable.Count; i++) + m_wearables[wearableId].Add(wearable[i].ItemID, wearable[i].AssetID); } // DEBUG ON @@ -507,14 +531,14 @@ namespace OpenSim.Framework { lock (m_attachments) { - List alist = new List(); + List alist = new List(); foreach (KeyValuePair> kvp in m_attachments) { foreach (AvatarAttachment attach in kvp.Value) alist.Add(new AvatarAttachment(attach)); } - return alist; - } + return alist; + } } internal void AppendAttachment(AvatarAttachment attach) @@ -527,7 +551,7 @@ namespace OpenSim.Framework { if (!m_attachments.ContainsKey(attach.AttachPoint)) m_attachments[attach.AttachPoint] = new List(); - + foreach (AvatarAttachment prev in m_attachments[attach.AttachPoint]) { if (prev.ItemID == attach.ItemID) @@ -584,7 +608,7 @@ namespace OpenSim.Framework m_attachments.Remove(attachpoint); return true; } - + return false; } @@ -598,13 +622,13 @@ namespace OpenSim.Framework if (existingAttachment != null) { // m_log.DebugFormat( -// "[AVATAR APPEARANCE]: Found existing attachment for {0}, asset {1} at point {2}", +// "[AVATAR APPEARANCE]: Found existing attachment for {0}, asset {1} at point {2}", // existingAttachment.ItemID, existingAttachment.AssetID, existingAttachment.AttachPoint); if (existingAttachment.AssetID != UUID.Zero && existingAttachment.AttachPoint == (attachpoint & 0x7F)) { m_log.DebugFormat( - "[AVATAR APPEARANCE]: Ignoring attempt to attach an already attached item {0} at point {1}", + "[AVATAR APPEARANCE]: Ignoring attempt to attach an already attached item {0} at point {1}", item, attachpoint); return false; @@ -616,7 +640,7 @@ namespace OpenSim.Framework DetachAttachment(existingAttachment.ItemID); } } - + // check if this is an append or a replace, 0x80 marks it as an append if ((attachpoint & 0x80) > 0) { @@ -677,16 +701,16 @@ namespace OpenSim.Framework if (index >= 0) { // m_log.DebugFormat( -// "[AVATAR APPEARANCE]: Detaching attachment {0}, index {1}, point {2}", +// "[AVATAR APPEARANCE]: Detaching attachment {0}, index {1}, point {2}", // m_attachments[kvp.Key][index].ItemID, index, m_attachments[kvp.Key][index].AttachPoint); // Remove it from the list of attachments at that attach point m_attachments[kvp.Key].RemoveAt(index); - + // And remove the list if there are no more attachments here if (m_attachments[kvp.Key].Count == 0) m_attachments.Remove(kvp.Key); - + return true; } } @@ -706,7 +730,7 @@ namespace OpenSim.Framework /// /// Create an OSDMap from the appearance data /// - public OSDMap Pack() + public OSDMap Pack(EntityTransferContext ctx) { OSDMap data = new OSDMap(); @@ -714,16 +738,22 @@ namespace OpenSim.Framework data["height"] = OSD.FromReal(m_avatarHeight); // Wearables + // + // This will send as many or as few wearables as we have, unless a count + // is given. Used for legacy (pre 0.4) versions. + int count = ctx.WearablesCount; + if (ctx.WearablesCount == -1) + count = m_wearables.Length; + OSDArray wears = new OSDArray(count); + for (int i = 0; i < count; i++) + { + AvatarWearable dummyWearable = new AvatarWearable(); - int wearsCount; - if(PackLegacyWearables) - wearsCount = AvatarWearable.LEGACY_VERSION_MAX_WEARABLES; - else - wearsCount = AvatarWearable.MAX_WEARABLES; - - OSDArray wears = new OSDArray(wearsCount); - for (int i = 0; i < wearsCount; i++) - wears.Add(m_wearables[i].Pack()); + if (i < m_wearables.Length) + wears.Add(m_wearables[i].Pack()); + else + wears.Add(dummyWearable.Pack()); + } data["wearables"] = wears; // Avatar Textures @@ -737,6 +767,13 @@ namespace OpenSim.Framework } data["textures"] = textures; + if (m_cacheitems != null) + { + OSDArray baked = WearableCacheItem.BakedToOSD(m_cacheitems); + if (baked != null) + data["bakedcache"] = baked; + } + // Visual Parameters OSDBinary visualparams = new OSDBinary(m_visualparams); data["visualparams"] = visualparams; @@ -774,8 +811,8 @@ namespace OpenSim.Framework OSDArray wears = (OSDArray)(data["wearables"]); int count = wears.Count; - if (count > AvatarWearable.MAX_WEARABLES) - count = AvatarWearable.MAX_WEARABLES; + + m_wearables = new AvatarWearable[count]; for (int i = 0; i < count; i++) m_wearables[i] = new AvatarWearable((OSDArray)wears[i]); @@ -803,6 +840,12 @@ namespace OpenSim.Framework m_log.Warn("[AVATAR APPEARANCE]: failed to unpack textures"); } + if ((data != null) && (data["bakedcache"] != null) && (data["bakedcache"]).Type == OSDType.Array) + { + OSDArray bakedOSDArray = (OSDArray)(data["bakedcache"]); + m_cacheitems = WearableCacheItem.BakedFromOSD(bakedOSDArray); + } + // Visual Parameters SetDefaultParams(); if ((data != null) && (data["visualparams"] != null)) @@ -824,7 +867,7 @@ namespace OpenSim.Framework { AvatarAttachment att = new AvatarAttachment((OSDMap)attachs[i]); AppendAttachment(att); - + // m_log.DebugFormat( // "[AVATAR APPEARANCE]: Unpacked attachment itemID {0}, assetID {1}, point {2}", // att.ItemID, att.AssetID, att.AttachPoint); @@ -1601,14 +1644,14 @@ namespace OpenSim.Framework SHAPE_EYELID_INNER_CORNER_UP = 214, SKIRT_SKIRT_RED = 215, SKIRT_SKIRT_GREEN = 216, - SKIRT_SKIRT_BLUE = 217, + SKIRT_SKIRT_BLUE = 217, /// /// Avatar Physics section. These are 0 type visual params which get transmitted. /// /// - /// Breast Part 1 + /// Breast Part 1 /// BREAST_PHYSICS_MASS = 218, BREAST_PHYSICS_GRAVITY = 219, @@ -1652,7 +1695,12 @@ namespace OpenSim.Framework BREAST_PHYSICS_LEFTRIGHT_MAX_EFFECT = 247, BREAST_PHYSICS_LEFTRIGHT_SPRING= 248, BREAST_PHYSICS_LEFTRIGHT_GAIN = 249, - BREAST_PHYSICS_LEFTRIGHT_DAMPING = 250 + BREAST_PHYSICS_LEFTRIGHT_DAMPING = 250, + + // Ubit: 07/96/2013 new parameters + _APPEARANCEMESSAGE_VERSION = 251, //ID 11000 + + SHAPE_HOVER = 252, //ID 11001 } #endregion } diff --git a/OpenSim/Framework/AvatarWearable.cs b/OpenSim/Framework/AvatarWearable.cs index e7615f2..0e8f960 100644 --- a/OpenSim/Framework/AvatarWearable.cs +++ b/OpenSim/Framework/AvatarWearable.cs @@ -62,12 +62,16 @@ namespace OpenSim.Framework public static readonly int UNDERSHIRT = 10; public static readonly int UNDERPANTS = 11; public static readonly int SKIRT = 12; + + public static readonly int MAX_BASICWEARABLES = 13; + public static readonly int ALPHA = 13; public static readonly int TATTOO = 14; public static readonly int LEGACY_VERSION_MAX_WEARABLES = 15; - public static readonly int PHYSICS = 15; - public static readonly int MAX_WEARABLES = 16; +// public static readonly int PHYSICS = 15; +// public static int MAX_WEARABLES = 16; + public static readonly UUID DEFAULT_BODY_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9"); public static readonly UUID DEFAULT_BODY_ASSET = new UUID("66c41e39-38f9-f75a-024e-585989bfab73"); @@ -78,6 +82,9 @@ namespace OpenSim.Framework public static readonly UUID DEFAULT_SKIN_ITEM = new UUID("77c41e39-38f9-f75a-024e-585989bfabc9"); public static readonly UUID DEFAULT_SKIN_ASSET = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb"); + public static readonly UUID DEFAULT_EYES_ITEM = new UUID("cdc31054-eed8-4021-994f-4e0c6e861b50"); + public static readonly UUID DEFAULT_EYES_ASSET = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7"); + public static readonly UUID DEFAULT_SHIRT_ITEM = new UUID("77c41e39-38f9-f75a-0000-585989bf0000"); public static readonly UUID DEFAULT_SHIRT_ASSET = new UUID("00000000-38f9-1111-024e-222222111110"); @@ -89,7 +96,7 @@ namespace OpenSim.Framework // public static readonly UUID DEFAULT_TATTOO_ITEM = new UUID("c47e22bd-3021-4ba4-82aa-2b5cb34d35e1"); // public static readonly UUID DEFAULT_TATTOO_ASSET = new UUID("00000000-0000-2222-3333-100000001007"); - + protected Dictionary m_items = new Dictionary(); protected List m_ids = new List(); @@ -221,33 +228,40 @@ namespace OpenSim.Framework { get { - AvatarWearable[] defaultWearables = new AvatarWearable[MAX_WEARABLES]; //should be 15 of these - for (int i = 0; i < MAX_WEARABLES; i++) + // We use the legacy count here because this is just a fallback anyway + AvatarWearable[] defaultWearables = new AvatarWearable[LEGACY_VERSION_MAX_WEARABLES]; + for (int i = 0; i < LEGACY_VERSION_MAX_WEARABLES; i++) { defaultWearables[i] = new AvatarWearable(); } - + // Body defaultWearables[BODY].Add(DEFAULT_BODY_ITEM, DEFAULT_BODY_ASSET); - + // Hair defaultWearables[HAIR].Add(DEFAULT_HAIR_ITEM, DEFAULT_HAIR_ASSET); // Skin defaultWearables[SKIN].Add(DEFAULT_SKIN_ITEM, DEFAULT_SKIN_ASSET); + // Eyes + defaultWearables[EYES].Add(DEFAULT_EYES_ITEM, DEFAULT_EYES_ASSET); + // Shirt defaultWearables[SHIRT].Add(DEFAULT_SHIRT_ITEM, DEFAULT_SHIRT_ASSET); // Pants defaultWearables[PANTS].Add(DEFAULT_PANTS_ITEM, DEFAULT_PANTS_ASSET); - + // // Alpha // defaultWearables[ALPHA].Add(DEFAULT_ALPHA_ITEM, DEFAULT_ALPHA_ASSET); - -// // Tattoo -// defaultWearables[TATTOO].Add(DEFAULT_TATTOO_ITEM, DEFAULT_TATTOO_ASSET); - + + // // Tattoo + // defaultWearables[TATTOO].Add(DEFAULT_TATTOO_ITEM, DEFAULT_TATTOO_ASSET); + + // // Physics + // defaultWearables[PHYSICS].Add(DEFAULT_TATTOO_ITEM, DEFAULT_TATTOO_ASSET); + return defaultWearables; } } diff --git a/OpenSim/Framework/BasicDOSProtector.cs b/OpenSim/Framework/BasicDOSProtector.cs index 89bfa94..f1ff18f 100644 --- a/OpenSim/Framework/BasicDOSProtector.cs +++ b/OpenSim/Framework/BasicDOSProtector.cs @@ -31,7 +31,7 @@ using log4net; namespace OpenSim.Framework { - + public class BasicDOSProtector { public enum ThrottleAction @@ -43,7 +43,7 @@ namespace OpenSim.Framework private readonly BasicDosProtectorOptions _options; private readonly Dictionary> _deeperInspection; // per client request checker private readonly Dictionary _tempBlocked; // blocked list - private readonly Dictionary _sessions; + private readonly Dictionary _sessions; private readonly System.Timers.Timer _forgetTimer; // Cleanup timer private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly System.Threading.ReaderWriterLockSlim _blockLockSlim = new System.Threading.ReaderWriterLockSlim(); @@ -133,7 +133,7 @@ namespace OpenSim.Framework else throw new System.Security.SecurityException("Throttled"); } - + _blockLockSlim.ExitReadLock(); lock (_generalRequestTimes) @@ -169,10 +169,10 @@ namespace OpenSim.Framework _blockLockSlim.ExitWriteLock(); } - + } - else + else ProcessConcurrency(key, endpoint); } if (_generalRequestTimes.Size == _generalRequestTimes.Capacity && @@ -194,7 +194,7 @@ namespace OpenSim.Framework _sessionLockSlim.EnterWriteLock(); if (_sessions.ContainsKey(key)) _sessions[key] = _sessions[key] + 1; - else + else _sessions.Add(key,1); _sessionLockSlim.ExitWriteLock(); } @@ -209,7 +209,7 @@ namespace OpenSim.Framework } else _sessions.Add(key, 1); - + _sessionLockSlim.ExitWriteLock(); } diff --git a/OpenSim/Framework/BlockingQueue.cs b/OpenSim/Framework/BlockingQueue.cs index d11ad11..2461049 100644 --- a/OpenSim/Framework/BlockingQueue.cs +++ b/OpenSim/Framework/BlockingQueue.cs @@ -65,7 +65,7 @@ namespace OpenSim.Framework if (m_pqueue.Count > 0) return m_pqueue.Dequeue(); - + if (m_queue.Count > 0) return m_queue.Dequeue(); return default(T); @@ -76,10 +76,10 @@ namespace OpenSim.Framework { lock (m_queueSync) { - bool success = true; - while (m_queue.Count < 1 && m_pqueue.Count < 1 && success) + if (m_queue.Count < 1 && m_pqueue.Count < 1) { - success = Monitor.Wait(m_queueSync, msTimeout); + if(!Monitor.Wait(m_queueSync, msTimeout)) + return default(T); } if (m_pqueue.Count > 0) diff --git a/OpenSim/Framework/Cache.cs b/OpenSim/Framework/Cache.cs index 31cab4a..3ca85d7 100644 --- a/OpenSim/Framework/Cache.cs +++ b/OpenSim/Framework/Cache.cs @@ -89,14 +89,14 @@ namespace OpenSim.Framework public CacheItemBase(string index) { uuid = index; - entered = DateTime.Now; + entered = DateTime.UtcNow; lastUsed = entered; } public CacheItemBase(string index, DateTime ttl) { uuid = index; - entered = DateTime.Now; + entered = DateTime.UtcNow; lastUsed = entered; expires = ttl; } @@ -215,6 +215,8 @@ namespace OpenSim.Framework private CacheFlags m_Flags = 0; private int m_Size = 1024; private TimeSpan m_DefaultTTL = new TimeSpan(0); + private DateTime m_nextExpire; + private TimeSpan m_expiresTime = new TimeSpan(0,0,30); public ExpireDelegate OnExpire; // Comparison interfaces @@ -233,6 +235,21 @@ namespace OpenSim.Framework return(a.lastUsed.CompareTo(b.lastUsed)); } } + // same as above, reverse order + private class SortLRUrev : IComparer + { + public int Compare(CacheItemBase a, CacheItemBase b) + { + if (a == null && b == null) + return 0; + if (a == null) + return -1; + if (b == null) + return 1; + + return(b.lastUsed.CompareTo(a.lastUsed)); + } + } // Convenience constructors // @@ -241,6 +258,8 @@ namespace OpenSim.Framework m_Strategy = CacheStrategy.Balanced; m_Medium = CacheMedium.Memory; m_Flags = 0; + m_nextExpire = DateTime.UtcNow + m_expiresTime; + m_Strategy = CacheStrategy.Aggressive; } public Cache(CacheMedium medium) : @@ -295,19 +314,23 @@ namespace OpenSim.Framework { lock (m_Index) { - if (Count <= Size) - return; + int target = newSize; + if(m_Strategy == CacheStrategy.Aggressive) + target = (int)(newSize * 0.9); - m_Index.Sort(new SortLRU()); - m_Index.Reverse(); + if(Count > target) + { + m_Index.Sort(new SortLRUrev()); - m_Index.RemoveRange(newSize, Count - newSize); - m_Size = newSize; + m_Index.RemoveRange(newSize, Count - target); - m_Lookup.Clear(); + m_Lookup.Clear(); + + foreach (CacheItemBase item in m_Index) + m_Lookup[item.uuid] = item; + } + m_Size = newSize; - foreach (CacheItemBase item in m_Index) - m_Lookup[item.uuid] = item; } } @@ -333,10 +356,10 @@ namespace OpenSim.Framework Expire(true); return null; } - + item.hits++; - item.lastUsed = DateTime.Now; - + item.lastUsed = DateTime.UtcNow; + Expire(true); } @@ -361,14 +384,15 @@ namespace OpenSim.Framework // public virtual Object Get(string index, FetchDelegate fetch) { - Object item = Get(index); + CacheItemBase item = GetItem(index); if (item != null) - return item; + return item.Retrieve(); Object data = fetch(index); + if (data == null) { - if ((m_Flags & CacheFlags.CacheMissing) != 0) + if((m_Flags & CacheFlags.CacheMissing) != 0) { lock (m_Index) { @@ -384,7 +408,6 @@ namespace OpenSim.Framework } Store(index, data); - return data; } @@ -442,9 +465,9 @@ namespace OpenSim.Framework item = GetItem(index); item.hits++; - item.lastUsed = DateTime.Now; + item.lastUsed = DateTime.UtcNow; if (m_DefaultTTL.Ticks != 0) - item.expires = DateTime.Now + m_DefaultTTL; + item.expires = DateTime.UtcNow + m_DefaultTTL; item.Store(data); } @@ -455,7 +478,7 @@ namespace OpenSim.Framework parameters); if (m_DefaultTTL.Ticks != 0) - item.expires = DateTime.Now + m_DefaultTTL; + item.expires = DateTime.UtcNow + m_DefaultTTL; m_Index.Add(item); m_Lookup[index] = item; @@ -476,10 +499,14 @@ namespace OpenSim.Framework if (getting && (m_Strategy == CacheStrategy.Aggressive)) return; + DateTime now = DateTime.UtcNow; + if(now < m_nextExpire) + return; + + m_nextExpire = now + m_expiresTime; + if (m_DefaultTTL.Ticks != 0) { - DateTime now= DateTime.Now; - foreach (CacheItemBase item in new List(m_Index)) { if (item.expires.Ticks == 0 || @@ -494,15 +521,13 @@ namespace OpenSim.Framework switch (m_Strategy) { case CacheStrategy.Aggressive: - if (Count < Size) + int target = (int)((float)Size * 0.9); + if (Count < target) // Cover ridiculous cache sizes return; - m_Index.Sort(new SortLRU()); - m_Index.Reverse(); + target = (int)((float)Size * 0.8); - int target = (int)((float)Size * 0.9); - if (target == Count) // Cover ridiculous cache sizes - return; + m_Index.Sort(new SortLRUrev()); ExpireDelegate doExpire = OnExpire; diff --git a/OpenSim/Framework/CapsUtil.cs b/OpenSim/Framework/CapsUtil.cs index 4baf505..020f6e2 100644 --- a/OpenSim/Framework/CapsUtil.cs +++ b/OpenSim/Framework/CapsUtil.cs @@ -43,7 +43,7 @@ namespace OpenSim.Framework { return "CAPS/" + capsObjectPath + "0000/"; } - + /// /// Get a random CAPS object path component that will be used as the identifying part of all future CAPS requests /// diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index 1504f21..ee5007a 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -61,8 +61,8 @@ namespace OpenSim.Framework { UUID AgentID { get; set; } - OSDMap Pack(); - void Unpack(OSDMap map, IScene scene); + OSDMap Pack(EntityTransferContext ctx); + void Unpack(OSDMap map, IScene scene, EntityTransferContext ctx); } /// @@ -89,13 +89,16 @@ namespace OpenSim.Framework public Vector3 AtAxis; public Vector3 LeftAxis; public Vector3 UpAxis; + //public int GodLevel; + public OSD GodData = null; public bool ChangedGrid; // This probably shouldn't be here public byte[] Throttles; + public Dictionary ChildrenCapSeeds = null; - public OSDMap Pack() + public OSDMap Pack(EntityTransferContext ctx) { OSDMap args = new OSDMap(); args["message_type"] = OSD.FromString("AgentPosition"); @@ -115,14 +118,37 @@ namespace OpenSim.Framework args["far"] = OSD.FromReal(Far); args["changed_grid"] = OSD.FromBoolean(ChangedGrid); + //args["god_level"] = OSD.FromString(GodLevel.ToString()); + if(GodData != null) + { + args["god_data"] = GodData; + OSDMap g = (OSDMap)GodData; + // Set legacy value + // TODO: remove after 0.9 is superseded + if (g.ContainsKey("ViewerUiIsGod")) + args["god_level"] = g["ViewerUiIsGod"].AsBoolean() ? 200 : 0; + } if ((Throttles != null) && (Throttles.Length > 0)) args["throttles"] = OSD.FromBinary(Throttles); + if (ChildrenCapSeeds != null && ChildrenCapSeeds.Count > 0) + { + OSDArray childrenSeeds = new OSDArray(ChildrenCapSeeds.Count); + foreach (KeyValuePair kvp in ChildrenCapSeeds) + { + OSDMap pair = new OSDMap(); + pair["handle"] = OSD.FromString(kvp.Key.ToString()); + pair["seed"] = OSD.FromString(kvp.Value); + childrenSeeds.Add(pair); + } + args["children_seeds"] = childrenSeeds; + } + return args; } - public void Unpack(OSDMap args, IScene scene) + public void Unpack(OSDMap args, IScene scene, EntityTransferContext ctx) { if (args.ContainsKey("region_handle")) UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle); @@ -160,11 +186,40 @@ namespace OpenSim.Framework if (args["changed_grid"] != null) ChangedGrid = args["changed_grid"].AsBoolean(); + //if (args["god_level"] != null) + // Int32.TryParse(args["god_level"].AsString(), out GodLevel); + if (args.ContainsKey("god_data") && args["god_data"] != null) + GodData = args["god_data"]; + if (args["far"] != null) Far = (float)(args["far"].AsReal()); if (args["throttles"] != null) Throttles = args["throttles"].AsBinary(); + + if (args.ContainsKey("children_seeds") && (args["children_seeds"] != null) && + (args["children_seeds"].Type == OSDType.Array)) + { + OSDArray childrenSeeds = (OSDArray)(args["children_seeds"]); + ChildrenCapSeeds = new Dictionary(); + foreach (OSD o in childrenSeeds) + { + if (o.Type == OSDType.Map) + { + ulong handle = 0; + string seed = ""; + OSDMap pair = (OSDMap)o; + if (pair["handle"] != null) + if (!UInt64.TryParse(pair["handle"].AsString(), out handle)) + continue; + if (pair["seed"] != null) + seed = pair["seed"].AsString(); + if (!ChildrenCapSeeds.ContainsKey(handle)) + ChildrenCapSeeds.Add(handle, seed); + } + } + } + } /// @@ -294,7 +349,7 @@ namespace OpenSim.Framework public Vector3 UpAxis; /// - /// Signal on a V2 teleport that Scene.IncomingChildAgentDataUpdate(AgentData ad) should wait for the + /// Signal on a V2 teleport that Scene.IncomingChildAgentDataUpdate(AgentData ad) should wait for the /// scene presence to become root (triggered when the viewer sends a CompleteAgentMovement UDP packet after /// establishing the connection triggered by it's receipt of a TeleportFinish EQ message). /// @@ -310,18 +365,24 @@ namespace OpenSim.Framework public Quaternion BodyRotation; public uint ControlFlags; public float EnergyLevel; - public Byte GodLevel; + public OSD GodData = null; + //public Byte GodLevel; public bool AlwaysRun; public UUID PreyAgent; public Byte AgentAccess; public UUID ActiveGroupID; + public string ActiveGroupName; + public string ActiveGroupTitle = null; + public UUID agentCOF; + public byte CrossingFlags; + public byte CrossExtraFlags; - public AgentGroupData[] Groups; + public Dictionary ChildrenCapSeeds = null; public Animation[] Anims; public Animation DefaultAnim = null; public Animation AnimState = null; + public Byte MotionState = 0; - public UUID GranterID; public UUID ParentPart; public Vector3 SitOffset; @@ -334,12 +395,6 @@ namespace OpenSim.Framework MethodBase.GetCurrentMethod().DeclaringType); // DEBUG OFF -/* - public byte[] AgentTextures; - public byte[] VisualParams; - public UUID[] Wearables; - public AvatarAttachment[] Attachments; -*/ // Scripted public ControllerData[] Controllers; @@ -349,7 +404,9 @@ namespace OpenSim.Framework public List AttachmentObjects; public List AttachmentObjectStates; - public virtual OSDMap Pack() + public Dictionary MovementAnimationOverRides = new Dictionary(); + + public virtual OSDMap Pack(EntityTransferContext ctx) { // m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data"); @@ -384,19 +441,39 @@ namespace OpenSim.Framework args["control_flags"] = OSD.FromString(ControlFlags.ToString()); args["energy_level"] = OSD.FromReal(EnergyLevel); - args["god_level"] = OSD.FromString(GodLevel.ToString()); + //args["god_level"] = OSD.FromString(GodLevel.ToString()); + if(GodData != null) + { + args["god_data"] = GodData; + OSDMap g = (OSDMap)GodData; + if (g.ContainsKey("ViewerUiIsGod")) + args["god_level"] = g["ViewerUiIsGod"].AsBoolean() ? 200 : 0;; + } args["always_run"] = OSD.FromBoolean(AlwaysRun); args["prey_agent"] = OSD.FromUUID(PreyAgent); args["agent_access"] = OSD.FromString(AgentAccess.ToString()); + args["agent_cof"] = OSD.FromUUID(agentCOF); + args["crossingflags"] = OSD.FromInteger(CrossingFlags); + if(CrossingFlags != 0) + args["crossExtraFlags"] = OSD.FromInteger(CrossExtraFlags); + args["active_group_id"] = OSD.FromUUID(ActiveGroupID); - - if ((Groups != null) && (Groups.Length > 0)) + args["active_group_name"] = OSD.FromString(ActiveGroupName); + if(ActiveGroupTitle != null) + args["active_group_title"] = OSD.FromString(ActiveGroupTitle); + + if (ChildrenCapSeeds != null && ChildrenCapSeeds.Count > 0) { - OSDArray groups = new OSDArray(Groups.Length); - foreach (AgentGroupData agd in Groups) - groups.Add(agd.PackUpdateMessage()); - args["groups"] = groups; + OSDArray childrenSeeds = new OSDArray(ChildrenCapSeeds.Count); + foreach (KeyValuePair kvp in ChildrenCapSeeds) + { + OSDMap pair = new OSDMap(); + pair["handle"] = OSD.FromString(kvp.Key.ToString()); + pair["seed"] = OSD.FromString(kvp.Value); + childrenSeeds.Add(pair); + } + args["children_seeds"] = childrenSeeds; } if ((Anims != null) && (Anims.Length > 0)) @@ -417,57 +494,28 @@ namespace OpenSim.Framework args["animation_state"] = AnimState.PackUpdateMessage(); } - if (Appearance != null) - args["packed_appearance"] = Appearance.Pack(); - - //if ((AgentTextures != null) && (AgentTextures.Length > 0)) - //{ - // OSDArray textures = new OSDArray(AgentTextures.Length); - // foreach (UUID uuid in AgentTextures) - // textures.Add(OSD.FromUUID(uuid)); - // args["agent_textures"] = textures; - //} - - // The code to pack textures, visuals, wearables and attachments - // should be removed; packed appearance contains the full appearance - // This is retained for backward compatibility only - if (Appearance.Texture != null) + if (MovementAnimationOverRides.Count > 0) { - byte[] rawtextures = Appearance.Texture.GetBytes(); - args["texture_entry"] = OSD.FromBinary(rawtextures); + OSDArray AOs = new OSDArray(MovementAnimationOverRides.Count); + { + foreach (KeyValuePair kvp in MovementAnimationOverRides) + { + OSDMap ao = new OSDMap(2); + ao["state"] = OSD.FromString(kvp.Key); + ao["uuid"] = OSD.FromUUID(kvp.Value); + AOs.Add(ao); + } + } + args["movementAO"] = AOs; } - if ((Appearance.VisualParams != null) && (Appearance.VisualParams.Length > 0)) - args["visual_params"] = OSD.FromBinary(Appearance.VisualParams); - - // We might not pass this in all cases... - if ((Appearance.Wearables != null) && (Appearance.Wearables.Length > 0)) + if (MotionState != 0) { - int wearsCount; - if(Appearance.PackLegacyWearables) - wearsCount = AvatarWearable.LEGACY_VERSION_MAX_WEARABLES; - else - wearsCount = AvatarWearable.MAX_WEARABLES; - - if(wearsCount > Appearance.Wearables.Length) - wearsCount = Appearance.Wearables.Length; - - OSDArray wears = new OSDArray(wearsCount); - for(int i = 0; i < wearsCount ; i++) - wears.Add(Appearance.Wearables[i].Pack()); - - args["wearables"] = wears; + args["motion_state"] = OSD.FromInteger(MotionState); } - List attachments = Appearance.GetAttachments(); - if ((attachments != null) && (attachments.Count > 0)) - { - OSDArray attachs = new OSDArray(attachments.Count); - foreach (AvatarAttachment att in attachments) - attachs.Add(att.Pack()); - args["attachments"] = attachs; - } - // End of code to remove + if (Appearance != null) + args["packed_appearance"] = Appearance.Pack(ctx); if ((Controllers != null) && (Controllers.Length > 0)) { @@ -516,7 +564,7 @@ namespace OpenSim.Framework /// Avoiding reflection makes it painful to write, but that's the price! /// /// - public virtual void Unpack(OSDMap args, IScene scene) + public virtual void Unpack(OSDMap args, IScene scene, EntityTransferContext ctx) { //m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data"); @@ -580,8 +628,11 @@ namespace OpenSim.Framework if (args["energy_level"] != null) EnergyLevel = (float)(args["energy_level"].AsReal()); - if (args["god_level"] != null) - Byte.TryParse(args["god_level"].AsString(), out GodLevel); + //if (args["god_level"] != null) + // Byte.TryParse(args["god_level"].AsString(), out GodLevel); + + if (args.ContainsKey("god_data") && args["god_data"] != null) + GodData = args["god_data"]; if (args["always_run"] != null) AlwaysRun = args["always_run"].AsBoolean(); @@ -592,19 +643,46 @@ namespace OpenSim.Framework if (args["agent_access"] != null) Byte.TryParse(args["agent_access"].AsString(), out AgentAccess); - if (args["active_group_id"] != null) + if (args.ContainsKey("agent_cof") && args["agent_cof"] != null) + agentCOF = args["agent_cof"].AsUUID(); + + if (args.ContainsKey("crossingflags") && args["crossingflags"] != null) + CrossingFlags = (byte)args["crossingflags"].AsInteger(); + + if(CrossingFlags != 0) + { + if (args.ContainsKey("crossExtraFlags") && args["crossExtraFlags"] != null) + CrossExtraFlags = (byte)args["crossExtraFlags"].AsInteger(); + } + + if (args.ContainsKey("active_group_id") && args["active_group_id"] != null) ActiveGroupID = args["active_group_id"].AsUUID(); - if ((args["groups"] != null) && (args["groups"]).Type == OSDType.Array) + if (args.ContainsKey("active_group_name") && args["active_group_name"] != null) + ActiveGroupName = args["active_group_name"].AsString(); + + if(args.ContainsKey("active_group_title") && args["active_group_title"] != null) + ActiveGroupTitle = args["active_group_title"].AsString(); + + if (args.ContainsKey("children_seeds") && (args["children_seeds"] != null) && + (args["children_seeds"].Type == OSDType.Array)) { - OSDArray groups = (OSDArray)(args["groups"]); - Groups = new AgentGroupData[groups.Count]; - int i = 0; - foreach (OSD o in groups) + OSDArray childrenSeeds = (OSDArray)(args["children_seeds"]); + ChildrenCapSeeds = new Dictionary(); + foreach (OSD o in childrenSeeds) { if (o.Type == OSDType.Map) { - Groups[i++] = new AgentGroupData((OSDMap)o); + ulong handle = 0; + string seed = ""; + OSDMap pair = (OSDMap)o; + if (pair["handle"] != null) + if (!UInt64.TryParse(pair["handle"].AsString(), out handle)) + continue; + if (pair["seed"] != null) + seed = pair["seed"].AsString(); + if (!ChildrenCapSeeds.ContainsKey(handle)) + ChildrenCapSeeds.Add(handle, seed); } } } @@ -647,6 +725,28 @@ namespace OpenSim.Framework } } + MovementAnimationOverRides.Clear(); + + if (args["movementAO"] != null && args["movementAO"].Type == OSDType.Array) + { + OSDArray AOs = (OSDArray)(args["movementAO"]); + int count = AOs.Count; + + for (int i = 0; i < count; i++) + { + OSDMap ao = (OSDMap)AOs[i]; + if (ao["state"] != null && ao["uuid"] != null) + { + string state = ao["state"].AsString(); + UUID id = ao["uuid"].AsUUID(); + MovementAnimationOverRides[state] = id; + } + } + } + + if (args.ContainsKey("motion_state")) + MotionState = (byte)args["motion_state"].AsInteger(); + //if ((args["agent_textures"] != null) && (args["agent_textures"]).Type == OSDType.Array) //{ // OSDArray textures = (OSDArray)(args["agent_textures"]); @@ -656,58 +756,67 @@ namespace OpenSim.Framework // AgentTextures[i++] = o.AsUUID(); //} - Appearance = new AvatarAppearance(); - // The code to unpack textures, visuals, wearables and attachments - // should be removed; packed appearance contains the full appearance - // This is retained for backward compatibility only - if (args["texture_entry"] != null) + // packed_appearence should contain all appearance information + if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map) { - byte[] rawtextures = args["texture_entry"].AsBinary(); - Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures,0,rawtextures.Length); - Appearance.SetTextureEntries(textures); + m_log.WarnFormat("[CHILDAGENTDATAUPDATE] got packed appearance"); + Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]); } + else + { + // if missing try the old pack method + m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance, checking old method"); - if (args["visual_params"] != null) - Appearance.SetVisualParams(args["visual_params"].AsBinary()); + Appearance = new AvatarAppearance(); - if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array) - { - OSDArray wears = (OSDArray)(args["wearables"]); + // The code to unpack textures, visuals, wearables and attachments + // should be removed; packed appearance contains the full appearance + // This is retained for backward compatibility only + if (args["texture_entry"] != null) + { + byte[] rawtextures = args["texture_entry"].AsBinary(); + Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures, 0, rawtextures.Length); + Appearance.SetTextureEntries(textures); + } - int count = wears.Count; - if (count > AvatarWearable.MAX_WEARABLES) - count = AvatarWearable.MAX_WEARABLES; + if (args["visual_params"] != null) + Appearance.SetVisualParams(args["visual_params"].AsBinary()); - for (int i = 0; i < count / 2; i++) + if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array) { - AvatarWearable awear = new AvatarWearable((OSDArray)wears[i]); - Appearance.SetWearable(i,awear); + OSDArray wears = (OSDArray)(args["wearables"]); + + for (int i = 0; i < wears.Count / 2; i++) + { + AvatarWearable awear = new AvatarWearable((OSDArray)wears[i]); + Appearance.SetWearable(i, awear); + } } - } - if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array) - { - OSDArray attachs = (OSDArray)(args["attachments"]); - foreach (OSD o in attachs) + if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array) { - if (o.Type == OSDType.Map) + OSDArray attachs = (OSDArray)(args["attachments"]); + foreach (OSD o in attachs) { - // We know all of these must end up as attachments so we - // append rather than replace to ensure multiple attachments - // per point continues to work -// m_log.DebugFormat("[CHILDAGENTDATAUPDATE]: Appending attachments for {0}", AgentID); - Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o)); + if (o.Type == OSDType.Map) + { + // We know all of these must end up as attachments so we + // append rather than replace to ensure multiple attachments + // per point continues to work + // m_log.DebugFormat("[CHILDAGENTDATAUPDATE]: Appending attachments for {0}", AgentID); + Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o)); + } } } + // end of code to remove } - // end of code to remove - +/* moved above if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map) Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]); else m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance"); - +*/ if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array) { OSDArray controls = (OSDArray)(args["controllers"]); @@ -771,14 +880,14 @@ namespace OpenSim.Framework public class CompleteAgentData : AgentData { - public override OSDMap Pack() + public override OSDMap Pack(EntityTransferContext ctx) { - return base.Pack(); + return base.Pack(ctx); } - public override void Unpack(OSDMap map, IScene scene) + public override void Unpack(OSDMap map, IScene scene, EntityTransferContext ctx) { - base.Unpack(map, scene); + base.Unpack(map, scene, ctx); } } } diff --git a/OpenSim/Framework/CircularBuffer.cs b/OpenSim/Framework/CircularBuffer.cs index e919337..e101938 100644 --- a/OpenSim/Framework/CircularBuffer.cs +++ b/OpenSim/Framework/CircularBuffer.cs @@ -1,21 +1,21 @@ /* -Copyright (c) 2012, Alex Regueiro +Copyright (c) 2012, Alex Regueiro All rights reserved. -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +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 +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. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR 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 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR 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; using System.Collections.Generic; diff --git a/OpenSim/Framework/Client/IClientIPEndpoint.cs b/OpenSim/Framework/Client/IClientIPEndpoint.cs index 2b99bf0..2194616 100644 --- a/OpenSim/Framework/Client/IClientIPEndpoint.cs +++ b/OpenSim/Framework/Client/IClientIPEndpoint.cs @@ -34,6 +34,6 @@ namespace OpenSim.Framework.Client { public interface IClientIPEndpoint { - IPAddress EndPoint { get; } + IPEndPoint RemoteEndPoint { get; } } } diff --git a/OpenSim/Framework/ClientInfo.cs b/OpenSim/Framework/ClientInfo.cs index 98e4465..a1ca9bc 100644 --- a/OpenSim/Framework/ClientInfo.cs +++ b/OpenSim/Framework/ClientInfo.cs @@ -36,14 +36,8 @@ namespace OpenSim.Framework public readonly DateTime StartedTime = DateTime.Now; public AgentCircuitData agentcircuit = null; - public Dictionary needAck; - - public List out_packets = new List(); - public Dictionary pendingAcks = new Dictionary(); public EndPoint proxyEP; - public uint sequence; - public byte[] usecircuit; public EndPoint userEP; public int resendThrottle; @@ -59,9 +53,5 @@ namespace OpenSim.Framework public int targetThrottle; public int maxThrottle; - - public Dictionary SyncRequests = new Dictionary(); - public Dictionary AsyncRequests = new Dictionary(); - public Dictionary GenericRequests = new Dictionary(); } } diff --git a/OpenSim/Framework/ClientManager.cs b/OpenSim/Framework/ClientManager.cs index baff2f4..45c54e4 100644 --- a/OpenSim/Framework/ClientManager.cs +++ b/OpenSim/Framework/ClientManager.cs @@ -27,10 +27,8 @@ using System; using System.Collections.Generic; -using System.Reflection; using System.Net; using OpenMetaverse; -using OpenMetaverse.Packets; namespace OpenSim.Framework { @@ -76,20 +74,16 @@ namespace OpenSim.Framework { lock (m_syncRoot) { - if (m_dict1.ContainsKey(value.AgentId) || m_dict2.ContainsKey(value.RemoteEndPoint)) - return false; + // allow self healing +// if (m_dict1.ContainsKey(value.AgentId) || m_dict2.ContainsKey(value.RemoteEndPoint)) +// return false; m_dict1[value.AgentId] = value; m_dict2[value.RemoteEndPoint] = value; - IClientAPI[] oldArray = m_array; - int oldLength = oldArray.Length; - - IClientAPI[] newArray = new IClientAPI[oldLength + 1]; - for (int i = 0; i < oldLength; i++) - newArray[i] = oldArray[i]; - newArray[oldLength] = value; - + // dict1 is the master + IClientAPI[] newArray = new IClientAPI[m_dict1.Count]; + m_dict1.Values.CopyTo(newArray, 0); m_array = newArray; } @@ -112,22 +106,12 @@ namespace OpenSim.Framework m_dict1.Remove(key); m_dict2.Remove(value.RemoteEndPoint); - IClientAPI[] oldArray = m_array; - int oldLength = oldArray.Length; - - IClientAPI[] newArray = new IClientAPI[oldLength - 1]; - int j = 0; - for (int i = 0; i < oldLength; i++) - { - if (oldArray[i] != value) - newArray[j++] = oldArray[i]; - } - + IClientAPI[] newArray = new IClientAPI[m_dict1.Count]; + m_dict1.Values.CopyTo(newArray, 0); m_array = newArray; return true; } } - return false; } @@ -197,25 +181,11 @@ namespace OpenSim.Framework } /// - /// Performs a given task in parallel for each of the elements in the - /// collection - /// - /// Action to perform on each element - public void ForEach(Action action) - { - IClientAPI[] localArray = m_array; - Parallel.For(0, localArray.Length, - delegate(int i) - { action(localArray[i]); } - ); - } - - /// /// Performs a given task synchronously for each of the elements in /// the collection /// /// Action to perform on each element - public void ForEachSync(Action action) + public void ForEach(Action action) { IClientAPI[] localArray = m_array; for (int i = 0; i < localArray.Length; i++) diff --git a/OpenSim/Framework/CnmMemoryCache.cs b/OpenSim/Framework/CnmMemoryCache.cs index 92af331..f996cb0 100644 --- a/OpenSim/Framework/CnmMemoryCache.cs +++ b/OpenSim/Framework/CnmMemoryCache.cs @@ -36,14 +36,14 @@ namespace OpenSim.Framework /// Cenome memory based cache to store key/value pairs (elements) limited time and/or limited size. /// /// - /// The type of keys in the cache. + /// The type of keys in the cache. /// /// - /// The type of values in the dictionary. + /// The type of values in the dictionary. /// /// /// - /// Cenome memory cache stores elements to hash table generations. When new element is being added to cache, and new size would exceed + /// Cenome memory cache stores elements to hash table generations. When new element is being added to cache, and new size would exceed /// maximal allowed size or maximal amount of allowed element count, then elements in oldest generation are deleted. Last access time /// is also tracked in generation level - thus it is possible that some elements are staying in cache far beyond their expiration time. /// If elements in older generations are accessed through method, they are moved to newest generation. @@ -176,7 +176,7 @@ namespace OpenSim.Framework } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// Maximal cache size. @@ -201,7 +201,7 @@ namespace OpenSim.Framework } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// Maximal cache size. @@ -218,7 +218,7 @@ namespace OpenSim.Framework } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// Maximal cache size. @@ -336,7 +336,7 @@ namespace OpenSim.Framework /// private void CheckExpired() { - // Do this only one in every m_operationsBetweenTimeChecks + // Do this only one in every m_operationsBetweenTimeChecks // Fetching time is using several millisecons - it is better not to do all time. m_operationsBetweenTimeChecks--; if (m_operationsBetweenTimeChecks <= 0) @@ -394,7 +394,7 @@ namespace OpenSim.Framework new IEnumerator>[2]; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The cache. @@ -456,7 +456,7 @@ namespace OpenSim.Framework /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. /// /// - /// The collection was modified after the enumerator was created. + /// The collection was modified after the enumerator was created. /// /// 2 public bool MoveNext() @@ -479,7 +479,7 @@ namespace OpenSim.Framework /// Sets the enumerator to its initial position, which is before the first element in the collection. /// /// - /// The collection was modified after the enumerator was created. + /// The collection was modified after the enumerator was created. /// /// 2 public void Reset() @@ -548,7 +548,7 @@ namespace OpenSim.Framework private DateTime m_expirationTime1; /// - /// Index to first free element. + /// Index to first free element. /// private int m_firstFreeElement; @@ -681,8 +681,8 @@ namespace OpenSim.Framework /// Next element in chain. /// /// - /// When element have value (something is stored to it), this is index of - /// next element with same bucket index. When element is free, this + /// When element have value (something is stored to it), this is index of + /// next element with same bucket index. When element is free, this /// is index of next element in free element's list. /// public int Next; @@ -696,7 +696,7 @@ namespace OpenSim.Framework public long Size; /// - /// Element's value. + /// Element's value. /// /// /// It is possible that this value is even when element @@ -812,7 +812,7 @@ namespace OpenSim.Framework /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection. /// /// - /// The collection was modified after the enumerator was created. + /// The collection was modified after the enumerator was created. /// public bool MoveNext() { @@ -841,7 +841,7 @@ namespace OpenSim.Framework /// Sets the enumerator to its initial position, which is before the first element in the collection. /// /// - /// The collection was modified after the enumerator was created. + /// The collection was modified after the enumerator was created. /// /// 2 public void Reset() @@ -931,7 +931,7 @@ namespace OpenSim.Framework /// The key to locate in the . /// /// - /// if the contains an element with the ; + /// if the contains an element with the ; /// otherwise . /// public bool Contains(int bucketIndex, TKey key) @@ -1014,7 +1014,7 @@ namespace OpenSim.Framework /// /// /// - /// If element was already existing in generation and new element size fits to collection limits, + /// If element was already existing in generation and new element size fits to collection limits, /// then it's value is replaced with new one and size information is updated. If element didn't /// exists in generation before, then generation must have empty space for a new element and /// size must fit generation's limits, before element is added to generation. @@ -1070,7 +1070,7 @@ namespace OpenSim.Framework if (Size - m_elements[ elementIndex ].Size + size > m_cache.m_generationMaxSize) { // Generation is full - // Remove existing element, because generation is going to be recycled to + // Remove existing element, because generation is going to be recycled to // old generation and element is stored to new generation RemoveElement(bucketIndex, elementIndex, previousIndex); return false; @@ -1110,12 +1110,12 @@ namespace OpenSim.Framework /// /// /// If element is not found from generation then and - /// are set to default value (default(TValue) and 0). + /// are set to default value (default(TValue) and 0). /// /// public bool TryGetValue(int bucketIndex, TKey key, out TValue value, out long size) { - // Find entry index, + // Find entry index, int previousIndex; int elementIndex = FindElementIndex(bucketIndex, key, m_newGeneration, out previousIndex); if (elementIndex == -1) @@ -1166,7 +1166,7 @@ namespace OpenSim.Framework /// /// /// There are two kind generations: "new generation" and "old generation(s)". All new elements - /// are added to "new generation". + /// are added to "new generation". /// /// protected interface IGeneration : IEnumerable> @@ -1211,7 +1211,7 @@ namespace OpenSim.Framework /// The key to locate in the . /// /// - /// if the contains an element with the ; + /// if the contains an element with the ; /// otherwise . /// bool Contains(int bucketIndex, TKey key); @@ -1259,7 +1259,7 @@ namespace OpenSim.Framework /// /// /// - /// If element was already existing in generation and new element size fits to collection limits, + /// If element was already existing in generation and new element size fits to collection limits, /// then it's value is replaced with new one and size information is updated. If element didn't /// exists in generation before, then generation must have empty space for a new element and /// size must fit generation's limits, before element is added to generation. @@ -1288,7 +1288,7 @@ namespace OpenSim.Framework /// /// /// If element is not found from generation then and - /// are set to default value (default(TValue) and 0). + /// are set to default value (default(TValue) and 0). /// /// bool TryGetValue(int bucketIndex, TKey key, out TValue value, out long size); @@ -1303,8 +1303,8 @@ namespace OpenSim.Framework /// /// /// - /// When adding an new element to that is limiting element count, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting element count, + /// will remove less recently used elements until it can fit an new element. /// /// /// @@ -1324,13 +1324,13 @@ namespace OpenSim.Framework /// /// /// - /// When element has been stored in longer than - /// and it is not accessed through method or element's value is - /// not replaced by method, then it is automatically removed from the + /// When element has been stored in longer than + /// and it is not accessed through method or element's value is + /// not replaced by method, then it is automatically removed from the /// . /// /// - /// It is possible that implementation removes element before it's expiration time, + /// It is possible that implementation removes element before it's expiration time, /// because total size or count of elements stored to cache is larger than or . /// /// @@ -1375,17 +1375,17 @@ namespace OpenSim.Framework /// Gets a value indicating whether is limiting count of elements. /// /// - /// if the count of elements is limited; - /// otherwise, . + /// if the count of elements is limited; + /// otherwise, . /// /// /// - /// When adding an new element to that is limiting element count, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting element count, + /// will remove less recently used elements until it can fit an new element. /// /// /// - /// + /// /// /// public bool IsCountLimited @@ -1397,13 +1397,13 @@ namespace OpenSim.Framework /// Gets a value indicating whether is limiting size of elements. /// /// - /// if the total size of elements is limited; - /// otherwise, . + /// if the total size of elements is limited; + /// otherwise, . /// /// /// - /// When adding an new element to that is limiting total size of elements, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting total size of elements, + /// will remove less recently used elements until it can fit an new element. /// /// /// @@ -1420,12 +1420,12 @@ namespace OpenSim.Framework /// Gets a value indicating whether or not access to the is synchronized (thread safe). /// /// - /// if access to the is synchronized (thread safe); - /// otherwise, . + /// if access to the is synchronized (thread safe); + /// otherwise, . /// /// /// - /// To get synchronized (thread safe) access to object, use + /// To get synchronized (thread safe) access to object, use /// in class /// to retrieve synchronized wrapper for object. /// @@ -1441,13 +1441,13 @@ namespace OpenSim.Framework /// Gets a value indicating whether elements stored to have limited inactivity time. /// /// - /// if the has a fixed total size of elements; - /// otherwise, . + /// if the has a fixed total size of elements; + /// otherwise, . /// /// /// If have limited inactivity time and element is not accessed through - /// or methods in , then element is automatically removed from - /// the cache. Depending on implementation of the , some of the elements may + /// or methods in , then element is automatically removed from + /// the cache. Depending on implementation of the , some of the elements may /// stay longer in cache. /// /// @@ -1463,13 +1463,13 @@ namespace OpenSim.Framework /// Gets or sets maximal allowed count of elements that can be stored to . /// /// - /// , if is not limited by count of elements; + /// , if is not limited by count of elements; /// otherwise maximal allowed count of elements. /// /// /// - /// When adding an new element to that is limiting element count, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting element count, + /// will remove less recently used elements until it can fit an new element. /// /// public int MaxCount @@ -1496,7 +1496,7 @@ namespace OpenSim.Framework /// /// /// - /// If element's size is larger than , then element is + /// If element's size is larger than , then element is /// not added to the . /// /// @@ -1522,8 +1522,8 @@ namespace OpenSim.Framework /// Normally size is total bytes used by elements in the cache. But it can be any other suitable unit of measure. /// /// - /// When adding an new element to that is limiting total size of elements, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting total size of elements, + /// will remove less recently used elements until it can fit an new element. /// /// /// @@ -1556,11 +1556,11 @@ namespace OpenSim.Framework /// Normally bytes, but can be any suitable unit of measure. /// /// - /// Element's size is given when element is added or replaced by method. + /// Element's size is given when element is added or replaced by method. /// /// - /// When adding an new element to that is limiting total size of elements, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting total size of elements, + /// will remove less recently used elements until it can fit an new element. /// /// /// @@ -1581,8 +1581,8 @@ namespace OpenSim.Framework /// /// /// - /// To get synchronized (thread safe) access to , use - /// method to retrieve synchronized wrapper interface to + /// To get synchronized (thread safe) access to , use + /// method to retrieve synchronized wrapper interface to /// . /// /// @@ -1735,7 +1735,7 @@ namespace OpenSim.Framework } /// - /// Add or replace an element with the provided , and to + /// Add or replace an element with the provided , and to /// . /// /// @@ -1748,7 +1748,7 @@ namespace OpenSim.Framework /// The element's size. Normally bytes, but can be any suitable unit of measure. /// /// - /// if element has been added successfully to the ; + /// if element has been added successfully to the ; /// otherwise . /// /// @@ -1759,17 +1759,17 @@ namespace OpenSim.Framework /// /// /// - /// If element's is larger than , then element is - /// not added to the , however - possible older element is - /// removed from the . + /// If element's is larger than , then element is + /// not added to the , however - possible older element is + /// removed from the . /// /// - /// When adding an new element to that is limiting total size of elements, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting total size of elements, + /// will remove less recently used elements until it can fit an new element. /// /// - /// When adding an new element to that is limiting element count, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting element count, + /// will remove less recently used elements until it can fit an new element. /// /// /// @@ -1809,15 +1809,15 @@ namespace OpenSim.Framework /// Gets the associated with the specified . /// /// - /// if the contains an element with + /// if the contains an element with /// the specified key; otherwise, . /// /// /// The key whose to get. /// /// - /// When this method returns, the value associated with the specified , - /// if the is found; otherwise, the + /// When this method returns, the value associated with the specified , + /// if the is found; otherwise, the /// default value for the type of the parameter. This parameter is passed uninitialized. /// /// diff --git a/OpenSim/Framework/CnmSynchronizedCache.cs b/OpenSim/Framework/CnmSynchronizedCache.cs index 2bafbe9..b33f4f7 100644 --- a/OpenSim/Framework/CnmSynchronizedCache.cs +++ b/OpenSim/Framework/CnmSynchronizedCache.cs @@ -36,10 +36,10 @@ namespace OpenSim.Framework /// Synchronized Cenome cache wrapper. /// /// - /// The type of keys in the cache. + /// The type of keys in the cache. /// /// - /// The type of values in the cache. + /// The type of values in the cache. /// /// /// @@ -60,7 +60,7 @@ namespace OpenSim.Framework private readonly object m_syncRoot; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// Initializes a new instance of the class. /// /// @@ -73,13 +73,13 @@ namespace OpenSim.Framework } /// - /// Returns a wrapper that is synchronized (thread safe). + /// Returns a wrapper that is synchronized (thread safe). /// /// /// The to synchronize. /// /// - /// A wrapper that is synchronized (thread safe). + /// A wrapper that is synchronized (thread safe). /// /// /// is null. @@ -125,7 +125,7 @@ namespace OpenSim.Framework } /// - /// Finalizes an instance of the class. + /// Finalizes an instance of the class. /// ~SynchronizedEnumerator() { @@ -184,7 +184,7 @@ namespace OpenSim.Framework /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection. /// /// - /// The collection was modified after the enumerator was created. + /// The collection was modified after the enumerator was created. /// public bool MoveNext() { @@ -195,7 +195,7 @@ namespace OpenSim.Framework /// Sets the enumerator to its initial position, which is before the first element in the collection. /// /// - /// The collection was modified after the enumerator was created. + /// The collection was modified after the enumerator was created. /// public void Reset() { @@ -214,8 +214,8 @@ namespace OpenSim.Framework /// /// /// - /// When adding an new element to that is limiting element count, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting element count, + /// will remove less recently used elements until it can fit an new element. /// /// /// @@ -241,13 +241,13 @@ namespace OpenSim.Framework /// /// /// - /// When element has been stored in longer than - /// and it is not accessed through method or element's value is - /// not replaced by method, then it is automatically removed from the + /// When element has been stored in longer than + /// and it is not accessed through method or element's value is + /// not replaced by method, then it is automatically removed from the /// . /// /// - /// It is possible that implementation removes element before it's expiration time, + /// It is possible that implementation removes element before it's expiration time, /// because total size or count of elements stored to cache is larger than or . /// /// @@ -291,17 +291,17 @@ namespace OpenSim.Framework /// Gets a value indicating whether is limiting count of elements. /// /// - /// if the count of elements is limited; - /// otherwise, . + /// if the count of elements is limited; + /// otherwise, . /// /// /// - /// When adding an new element to that is limiting element count, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting element count, + /// will remove less recently used elements until it can fit an new element. /// /// /// - /// + /// /// /// public bool IsCountLimited @@ -319,13 +319,13 @@ namespace OpenSim.Framework /// Gets a value indicating whether is limiting size of elements. /// /// - /// if the total size of elements is limited; - /// otherwise, . + /// if the total size of elements is limited; + /// otherwise, . /// /// /// - /// When adding an new element to that is limiting total size of elements, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting total size of elements, + /// will remove less recently used elements until it can fit an new element. /// /// /// @@ -348,12 +348,12 @@ namespace OpenSim.Framework /// Gets a value indicating whether or not access to the is synchronized (thread safe). /// /// - /// if access to the is synchronized (thread safe); - /// otherwise, . + /// if access to the is synchronized (thread safe); + /// otherwise, . /// /// /// - /// To get synchronized (thread safe) access to object, use + /// To get synchronized (thread safe) access to object, use /// in class /// to retrieve synchronized wrapper for object. /// @@ -369,13 +369,13 @@ namespace OpenSim.Framework /// Gets a value indicating whether elements stored to have limited inactivity time. /// /// - /// if the has a fixed total size of elements; - /// otherwise, . + /// if the has a fixed total size of elements; + /// otherwise, . /// /// /// If have limited inactivity time and element is not accessed through - /// or methods in , then element is automatically removed from - /// the cache. Depending on implementation of the , some of the elements may + /// or methods in , then element is automatically removed from + /// the cache. Depending on implementation of the , some of the elements may /// stay longer in cache. /// /// @@ -397,13 +397,13 @@ namespace OpenSim.Framework /// Gets or sets maximal allowed count of elements that can be stored to . /// /// - /// , if is not limited by count of elements; + /// , if is not limited by count of elements; /// otherwise maximal allowed count of elements. /// /// /// - /// When adding an new element to that is limiting element count, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting element count, + /// will remove less recently used elements until it can fit an new element. /// /// public int MaxCount @@ -433,7 +433,7 @@ namespace OpenSim.Framework /// /// /// - /// If element's size is larger than , then element is + /// If element's size is larger than , then element is /// not added to the . /// /// @@ -463,8 +463,8 @@ namespace OpenSim.Framework /// Normally size is total bytes used by elements in the cache. But it can be any other suitable unit of measure. /// /// - /// When adding an new element to that is limiting total size of elements, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting total size of elements, + /// will remove less recently used elements until it can fit an new element. /// /// /// value is less than 0. @@ -501,11 +501,11 @@ namespace OpenSim.Framework /// Normally bytes, but can be any suitable unit of measure. /// /// - /// Element's size is given when element is added or replaced by method. + /// Element's size is given when element is added or replaced by method. /// /// - /// When adding an new element to that is limiting total size of elements, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting total size of elements, + /// will remove less recently used elements until it can fit an new element. /// /// /// @@ -532,8 +532,8 @@ namespace OpenSim.Framework /// /// /// - /// To get synchronized (thread safe) access to , use - /// method to retrieve synchronized wrapper interface to + /// To get synchronized (thread safe) access to , use + /// method to retrieve synchronized wrapper interface to /// . /// /// @@ -647,7 +647,7 @@ namespace OpenSim.Framework } /// - /// Add or replace an element with the provided , and to + /// Add or replace an element with the provided , and to /// . /// /// @@ -660,7 +660,7 @@ namespace OpenSim.Framework /// The element's size. Normally bytes, but can be any suitable unit of measure. /// /// - /// if element has been added successfully to the ; + /// if element has been added successfully to the ; /// otherwise . /// /// @@ -671,17 +671,17 @@ namespace OpenSim.Framework /// /// /// - /// If element's is larger than , then element is - /// not added to the , however - possible older element is - /// removed from the . + /// If element's is larger than , then element is + /// not added to the , however - possible older element is + /// removed from the . /// /// - /// When adding an new element to that is limiting total size of elements, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting total size of elements, + /// will remove less recently used elements until it can fit an new element. /// /// - /// When adding an new element to that is limiting element count, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting element count, + /// will remove less recently used elements until it can fit an new element. /// /// /// @@ -703,15 +703,15 @@ namespace OpenSim.Framework /// Gets the associated with the specified . /// /// - /// if the contains an element with + /// if the contains an element with /// the specified key; otherwise, . /// /// /// The key whose to get. /// /// - /// When this method returns, the value associated with the specified , - /// if the is found; otherwise, the + /// When this method returns, the value associated with the specified , + /// if the is found; otherwise, the /// default value for the type of the parameter. This parameter is passed uninitialized. /// /// diff --git a/OpenSim/Framework/ColliderData.cs b/OpenSim/Framework/ColliderData.cs index 1b7b682..00013e1 100644 --- a/OpenSim/Framework/ColliderData.cs +++ b/OpenSim/Framework/ColliderData.cs @@ -42,6 +42,7 @@ namespace OpenSim.Framework public Vector3 velVector = Vector3.Zero; public string nameStr = String.Empty; public int colliderType = 0; + public int linkNumber; } public class ColliderArgs : EventArgs diff --git a/OpenSim/Framework/ConfigurationMember.cs b/OpenSim/Framework/ConfigurationMember.cs new file mode 100644 index 0000000..7afa68a --- /dev/null +++ b/OpenSim/Framework/ConfigurationMember.cs @@ -0,0 +1,530 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Net; +using System.Reflection; +using System.Xml; +using log4net; +using OpenMetaverse; +//using OpenSim.Framework.Console; + +namespace OpenSim.Framework +{ + public class ConfigurationMember + { + #region Delegates + + public delegate bool ConfigurationOptionResult(string configuration_key, object configuration_result); + + public delegate void ConfigurationOptionsLoad(); + + #endregion + + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private int cE = 0; + + private string configurationDescription = String.Empty; + private string configurationFilename = String.Empty; + private XmlNode configurationFromXMLNode = null; + private List configurationOptions = new List(); + private IGenericConfig configurationPlugin = null; + + /// + /// This is the default configuration DLL loaded + /// + private string configurationPluginFilename = "OpenSim.Framework.Configuration.XML.dll"; + + private ConfigurationOptionsLoad loadFunction; + private ConfigurationOptionResult resultFunction; + + private bool useConsoleToPromptOnError = true; + + public ConfigurationMember(string configuration_filename, string configuration_description, + ConfigurationOptionsLoad load_function, ConfigurationOptionResult result_function, bool use_console_to_prompt_on_error) + { + configurationFilename = configuration_filename; + configurationDescription = configuration_description; + loadFunction = load_function; + resultFunction = result_function; + useConsoleToPromptOnError = use_console_to_prompt_on_error; + } + + public ConfigurationMember(XmlNode configuration_xml, string configuration_description, + ConfigurationOptionsLoad load_function, ConfigurationOptionResult result_function, bool use_console_to_prompt_on_error) + { + configurationFilename = String.Empty; + configurationFromXMLNode = configuration_xml; + configurationDescription = configuration_description; + loadFunction = load_function; + resultFunction = result_function; + useConsoleToPromptOnError = use_console_to_prompt_on_error; + } + + public void setConfigurationFilename(string filename) + { + configurationFilename = filename; + } + + public void setConfigurationDescription(string desc) + { + configurationDescription = desc; + } + + public void setConfigurationResultFunction(ConfigurationOptionResult result) + { + resultFunction = result; + } + + public void forceConfigurationPluginLibrary(string dll_filename) + { + configurationPluginFilename = dll_filename; + } + + private void checkAndAddConfigOption(ConfigurationOption option) + { + if ((option.configurationKey != String.Empty && option.configurationQuestion != String.Empty) || + (option.configurationKey != String.Empty && option.configurationUseDefaultNoPrompt)) + { + if (!configurationOptions.Contains(option)) + { + configurationOptions.Add(option); + } + } + else + { + m_log.Info( + "Required fields for adding a configuration option is invalid. Will not add this option (" + + option.configurationKey + ")"); + } + } + + public void addConfigurationOption(string configuration_key, + ConfigurationOption.ConfigurationTypes configuration_type, + string configuration_question, string configuration_default, + bool use_default_no_prompt) + { + ConfigurationOption configOption = new ConfigurationOption(); + configOption.configurationKey = configuration_key; + configOption.configurationQuestion = configuration_question; + configOption.configurationDefault = configuration_default; + configOption.configurationType = configuration_type; + configOption.configurationUseDefaultNoPrompt = use_default_no_prompt; + configOption.shouldIBeAsked = null; //Assumes true, I can ask whenever + checkAndAddConfigOption(configOption); + } + + public void addConfigurationOption(string configuration_key, + ConfigurationOption.ConfigurationTypes configuration_type, + string configuration_question, string configuration_default, + bool use_default_no_prompt, + ConfigurationOption.ConfigurationOptionShouldBeAsked shouldIBeAskedDelegate) + { + ConfigurationOption configOption = new ConfigurationOption(); + configOption.configurationKey = configuration_key; + configOption.configurationQuestion = configuration_question; + configOption.configurationDefault = configuration_default; + configOption.configurationType = configuration_type; + configOption.configurationUseDefaultNoPrompt = use_default_no_prompt; + configOption.shouldIBeAsked = shouldIBeAskedDelegate; + checkAndAddConfigOption(configOption); + } + + // TEMP - REMOVE + public void performConfigurationRetrieve() + { + if (cE > 1) + m_log.Error("READING CONFIGURATION COUT: " + cE.ToString()); + + + configurationPlugin = LoadConfigDll(configurationPluginFilename); + configurationOptions.Clear(); + if (loadFunction == null) + { + m_log.Error("Load Function for '" + configurationDescription + + "' is null. Refusing to run configuration."); + return; + } + + if (resultFunction == null) + { + m_log.Error("Result Function for '" + configurationDescription + + "' is null. Refusing to run configuration."); + return; + } + + //m_log.Debug("[CONFIG]: Calling Configuration Load Function..."); + loadFunction(); + + if (configurationOptions.Count <= 0) + { + m_log.Error("[CONFIG]: No configuration options were specified for '" + configurationOptions + + "'. Refusing to continue configuration."); + return; + } + + bool useFile = true; + if (configurationPlugin == null) + { + m_log.Error("[CONFIG]: Configuration Plugin NOT LOADED!"); + return; + } + + if (configurationFilename.Trim() != String.Empty) + { + configurationPlugin.SetFileName(configurationFilename); + try + { + configurationPlugin.LoadData(); + useFile = true; + } + catch (XmlException e) + { + m_log.WarnFormat("[CONFIG] Not using {0}: {1}", + configurationFilename, + e.Message.ToString()); + //m_log.Error("Error loading " + configurationFilename + ": " + e.ToString()); + useFile = false; + } + } + else + { + if (configurationFromXMLNode != null) + { + m_log.Info("Loading from XML Node, will not save to the file"); + configurationPlugin.LoadDataFromString(configurationFromXMLNode.OuterXml); + } + + m_log.Info("XML Configuration Filename is not valid; will not save to the file."); + useFile = false; + } + + foreach (ConfigurationOption configOption in configurationOptions) + { + bool convertSuccess = false; + object return_result = null; + string errorMessage = String.Empty; + bool ignoreNextFromConfig = false; + while (convertSuccess == false) + { + string console_result = String.Empty; + string attribute = null; + if (useFile || configurationFromXMLNode != null) + { + if (!ignoreNextFromConfig) + { + attribute = configurationPlugin.GetAttribute(configOption.configurationKey); + } + else + { + ignoreNextFromConfig = false; + } + } + + if (attribute == null) + { + if (configOption.configurationUseDefaultNoPrompt || useConsoleToPromptOnError == false) + { + console_result = configOption.configurationDefault; + } + else + { + if ((configOption.shouldIBeAsked != null && + configOption.shouldIBeAsked(configOption.configurationKey)) || + configOption.shouldIBeAsked == null) + { + if (configurationDescription.Trim() != String.Empty) + { + console_result = + MainConsole.Instance.CmdPrompt( + configurationDescription + ": " + configOption.configurationQuestion, + configOption.configurationDefault); + } + else + { + console_result = + MainConsole.Instance.CmdPrompt(configOption.configurationQuestion, + configOption.configurationDefault); + } + } + else + { + //Dont Ask! Just use default + console_result = configOption.configurationDefault; + } + } + } + else + { + console_result = attribute; + } + + // if the first character is a "$", assume it's the name + // of an environment variable and substitute with the value of that variable + if (console_result.StartsWith("$")) + console_result = Environment.GetEnvironmentVariable(console_result.Substring(1)); + + switch (configOption.configurationType) + { + case ConfigurationOption.ConfigurationTypes.TYPE_STRING: + return_result = console_result; + convertSuccess = true; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY: + if (console_result.Length > 0) + { + return_result = console_result; + convertSuccess = true; + } + errorMessage = "a string that is not empty"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN: + bool boolResult; + if (Boolean.TryParse(console_result, out boolResult)) + { + convertSuccess = true; + return_result = boolResult; + } + errorMessage = "'true' or 'false' (Boolean)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_BYTE: + byte byteResult; + if (Byte.TryParse(console_result, out byteResult)) + { + convertSuccess = true; + return_result = byteResult; + } + errorMessage = "a byte (Byte)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_CHARACTER: + char charResult; + if (Char.TryParse(console_result, out charResult)) + { + convertSuccess = true; + return_result = charResult; + } + errorMessage = "a character (Char)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_INT16: + short shortResult; + if (Int16.TryParse(console_result, out shortResult)) + { + convertSuccess = true; + return_result = shortResult; + } + errorMessage = "a signed 32 bit integer (short)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_INT32: + int intResult; + if (Int32.TryParse(console_result, out intResult)) + { + convertSuccess = true; + return_result = intResult; + } + errorMessage = "a signed 32 bit integer (int)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_INT64: + long longResult; + if (Int64.TryParse(console_result, out longResult)) + { + convertSuccess = true; + return_result = longResult; + } + errorMessage = "a signed 32 bit integer (long)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS: + IPAddress ipAddressResult; + if (IPAddress.TryParse(console_result, out ipAddressResult)) + { + convertSuccess = true; + return_result = ipAddressResult; + } + errorMessage = "an IP Address (IPAddress)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_UUID: + UUID uuidResult; + if (UUID.TryParse(console_result, out uuidResult)) + { + convertSuccess = true; + return_result = uuidResult; + } + errorMessage = "a UUID (UUID)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_UUID_NULL_FREE: + UUID uuidResult2; + if (UUID.TryParse(console_result, out uuidResult2)) + { + convertSuccess = true; + + if (uuidResult2 == UUID.Zero) + uuidResult2 = UUID.Random(); + + return_result = uuidResult2; + } + errorMessage = "a non-null UUID (UUID)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_Vector3: + Vector3 vectorResult; + if (Vector3.TryParse(console_result, out vectorResult)) + { + convertSuccess = true; + return_result = vectorResult; + } + errorMessage = "a vector (Vector3)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_UINT16: + ushort ushortResult; + if (UInt16.TryParse(console_result, out ushortResult)) + { + convertSuccess = true; + return_result = ushortResult; + } + errorMessage = "an unsigned 16 bit integer (ushort)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_UINT32: + uint uintResult; + if (UInt32.TryParse(console_result, out uintResult)) + { + convertSuccess = true; + return_result = uintResult; + } + errorMessage = "an unsigned 32 bit integer (uint)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_UINT64: + ulong ulongResult; + if (UInt64.TryParse(console_result, out ulongResult)) + { + convertSuccess = true; + return_result = ulongResult; + } + errorMessage = "an unsigned 64 bit integer (ulong)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_FLOAT: + float floatResult; + if ( + float.TryParse(console_result, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, Culture.NumberFormatInfo, + out floatResult)) + { + convertSuccess = true; + return_result = floatResult; + } + errorMessage = "a single-precision floating point number (float)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE: + double doubleResult; + if ( + Double.TryParse(console_result, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, Culture.NumberFormatInfo, + out doubleResult)) + { + convertSuccess = true; + return_result = doubleResult; + } + errorMessage = "an double-precision floating point number (double)"; + break; + } + + if (convertSuccess) + { + if (useFile) + { + configurationPlugin.SetAttribute(configOption.configurationKey, console_result); + } + + if (!resultFunction(configOption.configurationKey, return_result)) + { + m_log.Info( + "The handler for the last configuration option denied that input, please try again."); + convertSuccess = false; + ignoreNextFromConfig = true; + } + } + else + { + if (configOption.configurationUseDefaultNoPrompt) + { + m_log.Error(string.Format( + "[CONFIG]: [{3}]:[{1}] is not valid default for parameter [{0}].\nThe configuration result must be parsable to {2}.\n", + configOption.configurationKey, console_result, errorMessage, + configurationFilename)); + convertSuccess = true; + } + else + { + m_log.Warn(string.Format( + "[CONFIG]: [{3}]:[{1}] is not a valid value [{0}].\nThe configuration result must be parsable to {2}.\n", + configOption.configurationKey, console_result, errorMessage, + configurationFilename)); + ignoreNextFromConfig = true; + } + } + } + } + + if (useFile) + { + configurationPlugin.Commit(); + configurationPlugin.Close(); + } + } + + private static IGenericConfig LoadConfigDll(string dllName) + { + Assembly pluginAssembly = Assembly.LoadFrom(dllName); + IGenericConfig plug = null; + + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (pluginType.IsPublic) + { + if (!pluginType.IsAbstract) + { + Type typeInterface = pluginType.GetInterface("IGenericConfig", true); + + if (typeInterface != null) + { + plug = + (IGenericConfig) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + } + } + } + } + + pluginAssembly = null; + return plug; + } + + public void forceSetConfigurationOption(string configuration_key, string configuration_value) + { + configurationPlugin.LoadData(); + configurationPlugin.SetAttribute(configuration_key, configuration_value); + configurationPlugin.Commit(); + configurationPlugin.Close(); + } + } +} diff --git a/OpenSim/Framework/Console/AssemblyInfo.cs b/OpenSim/Framework/Console/AssemblyInfo.cs index 67af471..c53d92b 100644 --- a/OpenSim/Framework/Console/AssemblyInfo.cs +++ b/OpenSim/Framework/Console/AssemblyInfo.cs @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.8.2.*")] +[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] diff --git a/OpenSim/Framework/Console/CommandConsole.cs b/OpenSim/Framework/Console/CommandConsole.cs index 0f68afe..52360b4 100644 --- a/OpenSim/Framework/Console/CommandConsole.cs +++ b/OpenSim/Framework/Console/CommandConsole.cs @@ -52,27 +52,27 @@ namespace OpenSim.Framework.Console /// The module from which this command comes /// public string module; - + /// /// Whether the module is shared /// public bool shared; - + /// /// Very short BNF description /// public string help_text; - + /// /// Longer one line help text /// public string long_help; - + /// /// Full descriptive help for this command /// public string descriptive_help; - + /// /// The method to invoke for this command /// @@ -83,8 +83,8 @@ namespace OpenSim.Framework.Console = "To enter an argument that contains spaces, surround the argument with double quotes.\nFor example, show object name \"My long object name\"\n"; public const string ItemHelpText -= @"For more information, type 'help all' to get a list of all commands, - or type help ' where is one of the following:"; + = @"For more information, type 'help all' to get a list of all commands, + or type help ' where is one of the following:"; /// /// Commands organized by keyword in a tree @@ -106,7 +106,7 @@ namespace OpenSim.Framework.Console { List help = new List(); List helpParts = new List(cmd); - + // Remove initial help keyword helpParts.RemoveAt(0); @@ -154,7 +154,7 @@ namespace OpenSim.Framework.Console return help; } - + /// /// See if we can find the requested command in order to display longer help /// @@ -171,23 +171,23 @@ namespace OpenSim.Framework.Console help.Insert(0, ItemHelpText); return help; } - + Dictionary dict = tree; while (helpParts.Count > 0) { string helpPart = helpParts[0]; - + if (!dict.ContainsKey(helpPart)) break; - + //m_log.Debug("Found {0}", helpParts[0]); - + if (dict[helpPart] is Dictionary) - dict = (Dictionary)dict[helpPart]; - + dict = (Dictionary)dict[helpPart]; + helpParts.RemoveAt(0); } - + // There was a command for the given help string if (dict.ContainsKey(String.Empty)) { @@ -200,14 +200,14 @@ namespace OpenSim.Framework.Console // If we do have some descriptive help then insert a spacing line before for readability. if (descriptiveHelp != string.Empty) help.Add(string.Empty); - + help.Add(commandInfo.descriptive_help); } else { help.Add(string.Format("No help is available for {0}", originalHelpRequest)); } - + return help; } @@ -268,7 +268,7 @@ namespace OpenSim.Framework.Console // } // return result; // } - + /// /// Add a command to those which can be invoked from the console. /// @@ -299,7 +299,7 @@ namespace OpenSim.Framework.Console string[] parts = Parser.Parse(command); Dictionary current = tree; - + foreach (string part in parts) { if (current.ContainsKey(part)) @@ -326,7 +326,7 @@ namespace OpenSim.Framework.Console return; } - + info = new CommandInfo(); info.module = module; info.shared = shared; @@ -471,7 +471,7 @@ namespace OpenSim.Framework.Console return null; } - + public bool HasCommand(string command) { string[] result; diff --git a/OpenSim/Framework/Console/ConsoleBase.cs b/OpenSim/Framework/Console/ConsoleBase.cs old mode 100644 new mode 100755 index 2d8e723..64cddea --- a/OpenSim/Framework/Console/ConsoleBase.cs +++ b/OpenSim/Framework/Console/ConsoleBase.cs @@ -67,7 +67,7 @@ namespace OpenSim.Framework.Console { System.Console.WriteLine(text); } - + public virtual void OutputFormat(string format, params object[] components) { Output(string.Format(format, components)); @@ -86,7 +86,7 @@ namespace OpenSim.Framework.Console return ret; } - + public string CmdPrompt(string p, List excludedCharacters) { bool itisdone = false; @@ -95,7 +95,7 @@ namespace OpenSim.Framework.Console { itisdone = true; ret = CmdPrompt(p); - + foreach (char c in excludedCharacters) { if (ret.Contains(c.ToString())) @@ -117,7 +117,7 @@ namespace OpenSim.Framework.Console { itisdone = true; ret = CmdPrompt(p, def); - + if (ret == String.Empty) { ret = def; diff --git a/OpenSim/Framework/Console/ConsolePluginCommand.cs b/OpenSim/Framework/Console/ConsolePluginCommand.cs old mode 100644 new mode 100755 diff --git a/OpenSim/Framework/Console/ConsoleUtil.cs b/OpenSim/Framework/Console/ConsoleUtil.cs index 44f6dc1..bfa05a2 100644 --- a/OpenSim/Framework/Console/ConsoleUtil.cs +++ b/OpenSim/Framework/Console/ConsoleUtil.cs @@ -40,7 +40,7 @@ namespace OpenSim.Framework.Console // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public const int LocalIdNotFound = 0; - + /// /// Used by modules to display stock co-ordinate help, though possibly this should be under some general section /// rather than in each help summary. @@ -57,10 +57,10 @@ namespace OpenSim.Framework.Console show object pos ,20,20 to ,40,40 delete object pos ,,30 to ,,~ show object pos ,,-~ to ,,30"; - + public const string MinRawConsoleVectorValue = "-~"; public const string MaxRawConsoleVectorValue = "~"; - + public const string VectorSeparator = ","; public static char[] VectorSeparatorChars = VectorSeparator.ToCharArray(); @@ -81,7 +81,7 @@ namespace OpenSim.Framework.Console return true; } - + /// /// Try to parse a console UUID from the console. /// @@ -101,7 +101,7 @@ namespace OpenSim.Framework.Console return false; } - + return true; } @@ -259,7 +259,7 @@ namespace OpenSim.Framework.Console return false; } - + /// /// Convert a minimum vector input from the console to an OpenMetaverse.Vector3 /// @@ -270,7 +270,7 @@ namespace OpenSim.Framework.Console { return TryParseConsoleVector(rawConsoleVector, c => float.MinValue.ToString(), out vector); } - + /// /// Convert a maximum vector input from the console to an OpenMetaverse.Vector3 /// @@ -281,7 +281,7 @@ namespace OpenSim.Framework.Console { return TryParseConsoleVector(rawConsoleVector, c => float.MaxValue.ToString(), out vector); } - + /// /// Convert a vector input from the console to an OpenMetaverse.Vector3 /// @@ -354,10 +354,10 @@ namespace OpenSim.Framework.Console string rawConsoleVector, int dimensions, Func blankComponentFunc) { List components = rawConsoleVector.Split(VectorSeparatorChars).ToList(); - + if (components.Count < 1 || components.Count > dimensions) return null; - + if (components.Count < dimensions) { if (blankComponentFunc == null) @@ -380,7 +380,7 @@ namespace OpenSim.Framework.Console else return c; }); - + return string.Join(VectorSeparator, cookedComponents.ToArray()); } } diff --git a/OpenSim/Framework/Console/LocalConsole.cs b/OpenSim/Framework/Console/LocalConsole.cs index d8f8ecc..73f0323 100644 --- a/OpenSim/Framework/Console/LocalConsole.cs +++ b/OpenSim/Framework/Console/LocalConsole.cs @@ -51,7 +51,7 @@ namespace OpenSim.Framework.Console private const string LOGLEVEL_NONE = "(none)"; // Used to extract categories for colourization. - private Regex m_categoryRegex + private Regex m_categoryRegex = new Regex( @"^(?.*?)\[(?[^\]]+)\]:?(?.*)", RegexOptions.Singleline | RegexOptions.Compiled); @@ -97,7 +97,7 @@ namespace OpenSim.Framework.Console string m_historyFile = startupConfig.GetString("ConsoleHistoryFile", "OpenSimConsoleHistory.txt"); int m_historySize = startupConfig.GetInt("ConsoleHistoryFileLines", 100); - m_historyPath = Path.GetFullPath(Path.Combine("../caches", m_historyFile)); + m_historyPath = Path.GetFullPath(Path.Combine(Util.configDir(), m_historyFile)); m_log.InfoFormat("[LOCAL CONSOLE]: Persistent command line history is Enabled, up to {0} lines from file {1}", m_historySize, m_historyPath); if (File.Exists(m_historyPath)) @@ -167,15 +167,15 @@ namespace OpenSim.Framework.Console { System.Console.CursorLeft = 0; } - else + else { int bufferWidth = System.Console.BufferWidth; - + // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) if (bufferWidth > 0 && left >= bufferWidth) System.Console.CursorLeft = bufferWidth - 1; } - + if (top < 0) { top = 0; @@ -183,7 +183,7 @@ namespace OpenSim.Framework.Console else { int bufferHeight = System.Console.BufferHeight; - + // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) if (bufferHeight > 0 && top >= bufferHeight) top = bufferHeight - 1; @@ -216,14 +216,14 @@ namespace OpenSim.Framework.Console { System.Console.CursorTop = 0; } - else + else { int bufferHeight = System.Console.BufferHeight; // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) if (bufferHeight > 0 && top >= bufferHeight) System.Console.CursorTop = bufferHeight - 1; } - + if (left < 0) { left = 0; @@ -339,7 +339,7 @@ namespace OpenSim.Framework.Console string outText = text; if (level != LOGLEVEL_NONE) - { + { MatchCollection matches = m_categoryRegex.Matches(text); if (matches.Count == 1) @@ -364,7 +364,7 @@ namespace OpenSim.Framework.Console WriteColorText(ConsoleColor.Yellow, outText); else System.Console.Write(outText); - + System.Console.WriteLine(); } @@ -551,7 +551,7 @@ namespace OpenSim.Framework.Console } string commandLine = m_commandLine.ToString(); - + if (isCommand) { string[] cmd = Commands.Resolve(Parser.Parse(commandLine)); @@ -573,7 +573,7 @@ namespace OpenSim.Framework.Console // If we're not echoing to screen (e.g. a password) then we probably don't want it in history if (m_echo && commandLine != "") AddToHistory(commandLine); - + return commandLine; default: break; diff --git a/OpenSim/Framework/Console/MockConsole.cs b/OpenSim/Framework/Console/MockConsole.cs index 1a142df..e1ff720 100644 --- a/OpenSim/Framework/Console/MockConsole.cs +++ b/OpenSim/Framework/Console/MockConsole.cs @@ -35,7 +35,7 @@ namespace OpenSim.Framework.Console { /// /// This is a Fake console that's used when setting up the Scene in Unit Tests - /// Don't use this except for Unit Testing or you're in for a world of hurt when the + /// Don't use this except for Unit Testing or you're in for a world of hurt when the /// sim gets to ReadLine /// public class MockConsole : ICommandConsole @@ -56,7 +56,7 @@ namespace OpenSim.Framework.Console public string ReadLine(string p, bool isCommand, bool e) { return ""; } - public object ConsoleScene { + public object ConsoleScene { get { return null; } set {} } diff --git a/OpenSim/Framework/Console/RemoteConsole.cs b/OpenSim/Framework/Console/RemoteConsole.cs index 8ad7b0d..f59c902 100644 --- a/OpenSim/Framework/Console/RemoteConsole.cs +++ b/OpenSim/Framework/Console/RemoteConsole.cs @@ -34,6 +34,7 @@ using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Threading; +using System.Timers; using OpenMetaverse; using Nini.Config; using OpenSim.Framework.Servers.HttpServer; @@ -41,51 +42,147 @@ using log4net; namespace OpenSim.Framework.Console { - public class ConsoleConnection - { - public int last; - public long lastLineSeen; - public bool newConnection = true; - } - // A console that uses REST interfaces // public class RemoteConsole : CommandConsole { - private IHttpServer m_Server = null; - private IConfigSource m_Config = null; - - private List m_Scrollback = new List(); - private ManualResetEvent m_DataEvent = new ManualResetEvent(false); - private List m_InputData = new List(); - private long m_LineNumber = 0; - private Dictionary m_Connections = + // Connection specific data, indexed by a session ID + // we create when a client connects. + protected class ConsoleConnection + { + // Last activity from the client + public int last; + + // Last line of scrollback posted to this client + public long lastLineSeen; + + // True if this is a new connection, e.g. has never + // displayed a prompt to the user. + public bool newConnection = true; + } + + // A line in the scrollback buffer. + protected class ScrollbackEntry + { + // The line number of this entry + public long lineNumber; + + // The text to send to the client + public string text; + + // The level this should be logged as. Omitted for + // prompts and input echo. + public string level; + + // True if the text above is a prompt, e.g. the + // client should turn on the cursor / accept input + public bool isPrompt; + + // True if the requested input is a command. A + // client may offer help or validate input if + // this is set. If false, input should be sent + // as typed. + public bool isCommand; + + // True if this text represents a line of text that + // was input in response to a prompt. A client should + // turn off the cursor and refrain from sending commands + // until a new prompt is received. + public bool isInput; + } + + // Data that is relevant to all connections + + // The scrollback buffer + protected List m_Scrollback = new List(); + + // Monotonously incrementing line number. This may eventually + // wrap. No provision is made for that case because 64 bits + // is a long, long time. + protected long m_lineNumber = 0; + + // These two variables allow us to send the correct + // information about the prompt status to the client, + // irrespective of what may have run off the top of the + // scrollback buffer; + protected bool m_expectingInput = false; + protected bool m_expectingCommand = true; + protected string m_lastPromptUsed; + + // This is the list of things received from clients. + // Note: Race conditions can happen. If a client sends + // something while nothing is expected, it will be + // intepreted as input to the next prompt. For + // commands this is largely correct. For other prompts, + // YMMV. + // TODO: Find a better way to fix this + protected List m_InputData = new List(); + + // Event to allow ReadLine to wait synchronously even though + // everthing else is asynchronous here. + protected ManualResetEvent m_DataEvent = new ManualResetEvent(false); + + // The list of sessions we maintain. Unlike other console types, + // multiple users on the same console are explicitly allowed. + protected Dictionary m_Connections = new Dictionary(); - private string m_UserName = String.Empty; - private string m_Password = String.Empty; - private string m_AllowedOrigin = String.Empty; + + // Timer to control expiration of sessions that have been + // disconnected. + protected System.Timers.Timer m_expireTimer = new System.Timers.Timer(5000); + + // The less interesting stuff that makes the actual server + // work. + protected IHttpServer m_Server = null; + protected IConfigSource m_Config = null; + + protected string m_UserName = String.Empty; + protected string m_Password = String.Empty; + protected string m_AllowedOrigin = String.Empty; + public RemoteConsole(string defaultPrompt) : base(defaultPrompt) { + // There is something wrong with this architecture. + // A prompt is sent on every single input, so why have this? + // TODO: Investigate and fix. + m_lastPromptUsed = defaultPrompt; + + // Start expiration of sesssions. + m_expireTimer.Elapsed += DoExpire; + m_expireTimer.Start(); } public void ReadConfig(IConfigSource config) { m_Config = config; + // We're pulling this from the 'Network' section for legacy + // compatibility. However, this is so essentially insecure + // that TLS and client certs should be used instead of + // a username / password. IConfig netConfig = m_Config.Configs["Network"]; + if (netConfig == null) return; + // Get the username and password. m_UserName = netConfig.GetString("ConsoleUser", String.Empty); m_Password = netConfig.GetString("ConsolePass", String.Empty); + + // Woefully underdocumented, this is what makes javascript + // console clients work. Set to "*" for anywhere or (better) + // to specific addresses. m_AllowedOrigin = netConfig.GetString("ConsoleAllowedOrigin", String.Empty); } public void SetServer(IHttpServer server) { + // This is called by the framework to give us the server + // instance (means: port) to work with. m_Server = server; + // Add our handlers m_Server.AddHTTPHandler("/StartSession/", HandleHttpStartSession); m_Server.AddHTTPHandler("/CloseSession/", HandleHttpCloseSession); m_Server.AddHTTPHandler("/SessionCommand/", HandleHttpSessionCommand); @@ -93,38 +190,84 @@ namespace OpenSim.Framework.Console public override void Output(string text, string level) { + Output(text, level, false, false, false); + } + + protected void Output(string text, string level, bool isPrompt, bool isCommand, bool isInput) + { + // Increment the line number. It was 0 and they start at 1 + // so we need to pre-increment. + m_lineNumber++; + + // Create and populate the new entry. + ScrollbackEntry newEntry = new ScrollbackEntry(); + + newEntry.lineNumber = m_lineNumber; + newEntry.text = text; + newEntry.level = level; + newEntry.isPrompt = isPrompt; + newEntry.isCommand = isCommand; + newEntry.isInput = isInput; + + // Add a line to the scrollback. In some cases, that may not + // actually be a line of text. lock (m_Scrollback) { + // Prune the scrollback to the length se send as connect + // burst to give the user some context. while (m_Scrollback.Count >= 1000) m_Scrollback.RemoveAt(0); - m_LineNumber++; - m_Scrollback.Add(String.Format("{0}", m_LineNumber)+":"+level+":"+text); + + m_Scrollback.Add(newEntry); } + + // Let the rest of the system know we have output something. FireOnOutput(text.Trim()); + + // Also display it for debugging. System.Console.WriteLine(text.Trim()); } public override void Output(string text) { - Output(text, "normal"); + // Output plain (non-logging style) text. + Output(text, String.Empty, false, false, false); } public override string ReadLine(string p, bool isCommand, bool e) { + // Output the prompt an prepare to wait. This + // is called on a dedicated console thread and + // needs to be synchronous. Old architecture but + // not worth upgrading. if (isCommand) - Output("+++"+p); + { + m_expectingInput = true; + m_expectingCommand = true; + Output(p, String.Empty, true, true, false); + m_lastPromptUsed = p; + } else - Output("-++"+p); + { + m_expectingInput = true; + Output(p, String.Empty, true, false, false); + } + + // Here is where we wait for the user to input something. m_DataEvent.WaitOne(); string cmdinput; + // Check for empty input. Read input if not empty. lock (m_InputData) { if (m_InputData.Count == 0) { m_DataEvent.Reset(); + m_expectingInput = false; + m_expectingCommand = false; + return ""; } @@ -135,8 +278,19 @@ namespace OpenSim.Framework.Console } + m_expectingInput = false; + m_expectingCommand = false; + + // Echo to all the other users what we have done. This + // will also go to ourselves. + Output (cmdinput, String.Empty, false, false, true); + + // If this is a command, we need to resolve and execute it. if (isCommand) { + // This call will actually execute the command and create + // any output associated with it. The core just gets an + // empty string so it will call again immediately. string[] cmd = Commands.Resolve(Parser.Parse(cmdinput)); if (cmd.Length != 0) @@ -151,18 +305,23 @@ namespace OpenSim.Framework.Console return String.Empty; } } + + // Return the raw input string if not a command. return cmdinput; } - private Hashtable CheckOrigin(Hashtable result) + // Very simplistic static access control header. + protected Hashtable CheckOrigin(Hashtable result) { if (!string.IsNullOrEmpty(m_AllowedOrigin)) result["access_control_allow_origin"] = m_AllowedOrigin; + return result; } + /* TODO: Figure out how PollServiceHTTPHandler can access the request headers * in order to use m_AllowedOrigin as a regular expression - private Hashtable CheckOrigin(Hashtable headers, Hashtable result) + protected Hashtable CheckOrigin(Hashtable headers, Hashtable result) { if (!string.IsNullOrEmpty(m_AllowedOrigin)) { @@ -177,18 +336,23 @@ namespace OpenSim.Framework.Console } */ - private void DoExpire() + protected void DoExpire(Object sender, ElapsedEventArgs e) { + // Iterate the list of console connections and find those we + // haven't heard from for longer then the longpoll interval. + // Remove them. List expired = new List(); lock (m_Connections) { + // Mark the expired ones foreach (KeyValuePair kvp in m_Connections) { if (System.Environment.TickCount - kvp.Value.last > 500000) expired.Add(kvp.Key); } + // Delete them foreach (UUID id in expired) { m_Connections.Remove(id); @@ -197,10 +361,10 @@ namespace OpenSim.Framework.Console } } - private Hashtable HandleHttpStartSession(Hashtable request) + // Start a new session. + protected Hashtable HandleHttpStartSession(Hashtable request) { - DoExpire(); - + // The login is in the form of a http form post Hashtable post = DecodePostString(request["body"].ToString()); Hashtable reply = new Hashtable(); @@ -208,6 +372,7 @@ namespace OpenSim.Framework.Console reply["int_response_code"] = 401; reply["content_type"] = "text/plain"; + // Check user name and password if (m_UserName == String.Empty) return reply; @@ -220,22 +385,28 @@ namespace OpenSim.Framework.Console return reply; } + // Set up the new console connection record ConsoleConnection c = new ConsoleConnection(); c.last = System.Environment.TickCount; c.lastLineSeen = 0; + // Assign session ID UUID sessionID = UUID.Random(); + // Add connection to list. lock (m_Connections) { m_Connections[sessionID] = c; } + // This call is a CAP. The URL is the authentication. string uri = "/ReadResponses/" + sessionID.ToString() + "/"; m_Server.AddPollServiceHTTPHandler( uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout + // Our reply is an XML document. + // TODO: Change this to Linq.Xml XmlDocument xmldoc = new XmlDocument(); XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, "", ""); @@ -252,12 +423,13 @@ namespace OpenSim.Framework.Console rootElement.AppendChild(id); XmlElement prompt = xmldoc.CreateElement("", "Prompt", ""); - prompt.AppendChild(xmldoc.CreateTextNode(DefaultPrompt)); + prompt.AppendChild(xmldoc.CreateTextNode(m_lastPromptUsed)); rootElement.AppendChild(prompt); rootElement.AppendChild(MainConsole.Instance.Commands.GetXml(xmldoc)); + // Set up the response and check origin reply["str_response_string"] = xmldoc.InnerXml; reply["int_response_code"] = 200; reply["content_type"] = "text/xml"; @@ -266,10 +438,9 @@ namespace OpenSim.Framework.Console return reply; } - private Hashtable HandleHttpCloseSession(Hashtable request) + // Client closes session. Clean up. + protected Hashtable HandleHttpCloseSession(Hashtable request) { - DoExpire(); - Hashtable post = DecodePostString(request["body"].ToString()); Hashtable reply = new Hashtable(); @@ -316,10 +487,9 @@ namespace OpenSim.Framework.Console return reply; } - private Hashtable HandleHttpSessionCommand(Hashtable request) + // Command received from the client. + protected Hashtable HandleHttpSessionCommand(Hashtable request) { - DoExpire(); - Hashtable post = DecodePostString(request["body"].ToString()); Hashtable reply = new Hashtable(); @@ -327,6 +497,7 @@ namespace OpenSim.Framework.Console reply["int_response_code"] = 404; reply["content_type"] = "text/plain"; + // Check the ID if (post["ID"] == null) return reply; @@ -334,21 +505,25 @@ namespace OpenSim.Framework.Console if (!UUID.TryParse(post["ID"].ToString(), out id)) return reply; + // Find the connection for that ID. lock (m_Connections) { if (!m_Connections.ContainsKey(id)) return reply; } + // Empty post. Just error out. if (post["COMMAND"] == null) return reply; + // Place the input data in the buffer. lock (m_InputData) { m_DataEvent.Set(); m_InputData.Add(post["COMMAND"].ToString()); } + // Create the XML reply document. XmlDocument xmldoc = new XmlDocument(); XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, "", ""); @@ -372,7 +547,8 @@ namespace OpenSim.Framework.Console return reply; } - private Hashtable DecodePostString(string data) + // Decode a HTTP form post to a Hashtable + protected Hashtable DecodePostString(string data) { Hashtable result = new Hashtable(); @@ -389,13 +565,14 @@ namespace OpenSim.Framework.Console if (elems.Length > 1) value = System.Web.HttpUtility.UrlDecode(elems[1]); - + result[name] = value; } return result; } + // Close the CAP receiver for the responses for a given client. public void CloseConnection(UUID id) { try @@ -409,7 +586,9 @@ namespace OpenSim.Framework.Console } } - private bool HasEvents(UUID RequestID, UUID sessionID) + // Check if there is anything to send. Return true if this client has + // lines pending. + protected bool HasEvents(UUID RequestID, UUID sessionID) { ConsoleConnection c = null; @@ -420,13 +599,15 @@ namespace OpenSim.Framework.Console c = m_Connections[sessionID]; } c.last = System.Environment.TickCount; - if (c.lastLineSeen < m_LineNumber) + if (c.lastLineSeen < m_lineNumber) return true; return false; } - private Hashtable GetEvents(UUID RequestID, UUID sessionID) + // Send all pending output to the client. + protected Hashtable GetEvents(UUID RequestID, UUID sessionID) { + // Find the connection that goes with this client. ConsoleConnection c = null; lock (m_Connections) @@ -435,12 +616,15 @@ namespace OpenSim.Framework.Console return NoEvents(RequestID, UUID.Zero); c = m_Connections[sessionID]; } + + // If we have nothing to send, send the no events response. c.last = System.Environment.TickCount; - if (c.lastLineSeen >= m_LineNumber) + if (c.lastLineSeen >= m_lineNumber) return NoEvents(RequestID, UUID.Zero); Hashtable result = new Hashtable(); + // Create the response document. XmlDocument xmldoc = new XmlDocument(); XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, "", ""); @@ -449,30 +633,53 @@ namespace OpenSim.Framework.Console XmlElement rootElement = xmldoc.CreateElement("", "ConsoleSession", ""); - if (c.newConnection) - { - c.newConnection = false; - Output("+++" + DefaultPrompt); - } + //if (c.newConnection) + //{ + // c.newConnection = false; + // Output("+++" + DefaultPrompt); + //} lock (m_Scrollback) { - long startLine = m_LineNumber - m_Scrollback.Count; + long startLine = m_lineNumber - m_Scrollback.Count; long sendStart = startLine; if (sendStart < c.lastLineSeen) sendStart = c.lastLineSeen; - for (long i = sendStart ; i < m_LineNumber ; i++) + for (long i = sendStart ; i < m_lineNumber ; i++) { + ScrollbackEntry e = m_Scrollback[(int)(i - startLine)]; + XmlElement res = xmldoc.CreateElement("", "Line", ""); - long line = i + 1; - res.SetAttribute("Number", line.ToString()); - res.AppendChild(xmldoc.CreateTextNode(m_Scrollback[(int)(i - startLine)])); + res.SetAttribute("Number", e.lineNumber.ToString()); + res.SetAttribute("Level", e.level); + // Don't include these for the scrollback, we'll send the + // real state later. + if (!c.newConnection) + { + res.SetAttribute("Prompt", e.isPrompt ? "true" : "false"); + res.SetAttribute("Command", e.isCommand ? "true" : "false"); + res.SetAttribute("Input", e.isInput ? "true" : "false"); + } + else if (i == m_lineNumber - 1) // Last line for a new connection + { + res.SetAttribute("Prompt", m_expectingInput ? "true" : "false"); + res.SetAttribute("Command", m_expectingCommand ? "true" : "false"); + res.SetAttribute("Input", (!m_expectingInput) ? "true" : "false"); + } + else + { + res.SetAttribute("Input", e.isInput ? "true" : "false"); + } + + res.AppendChild(xmldoc.CreateTextNode(e.text)); rootElement.AppendChild(res); } } - c.lastLineSeen = m_LineNumber; + + c.lastLineSeen = m_lineNumber; + c.newConnection = false; xmldoc.AppendChild(rootElement); @@ -486,7 +693,9 @@ namespace OpenSim.Framework.Console return result; } - private Hashtable NoEvents(UUID RequestID, UUID id) + // This is really just a no-op. It generates what is sent + // to the client if the poll times out without any events. + protected Hashtable NoEvents(UUID RequestID, UUID id) { Hashtable result = new Hashtable(); diff --git a/OpenSim/Framework/Constants.cs b/OpenSim/Framework/Constants.cs index 48478b4..209c991 100644 --- a/OpenSim/Framework/Constants.cs +++ b/OpenSim/Framework/Constants.cs @@ -34,7 +34,7 @@ namespace OpenSim.Framework // DO NOT USE THIS FOR ANY NEW CODE. Use Scene.RegionInfo.RegionSize[XYZ] as a region might not // be the legacy region size. public const uint RegionSize = 256; - public const uint RegionHeight = 16384; + public const uint RegionHeight = 4096; // This could be a parameters but, really, a region of greater than this is pretty unmanageable public const uint MaximumRegionSize = 8192; @@ -46,12 +46,20 @@ namespace OpenSim.Framework public enum EstateAccessCodex : uint { - AccessOptions = 1, + AllowedAccess = 1, AllowedGroups = 2, EstateBans = 4, EstateManagers = 8 } + public enum EstateAccessLimits : int + { + AllowedAccess = 500, + AllowedGroups = 63, + EstateBans = 500, + EstateManagers = 10 + } + [Flags]public enum TeleportFlags : uint { /// No flags set, or teleport failed diff --git a/OpenSim/Framework/Crc32.cs b/OpenSim/Framework/Crc32.cs new file mode 100644 index 0000000..7ad1566 --- /dev/null +++ b/OpenSim/Framework/Crc32.cs @@ -0,0 +1,139 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Security.Cryptography; + +namespace OpenSim.Framework +{ + // this is more generic than openmetaverse CRC32 + + public class Crc32 : HashAlgorithm + { + public const UInt32 DefaultPolynomial = 0xedb88320; + public const UInt32 DefaultSeed = 0xffffffff; + + private UInt32 hash; + private UInt32 seed; + private UInt32[] table; + private static UInt32[] defaultTable; + + public Crc32() + { + table = InitializeTable(DefaultPolynomial); + seed = DefaultSeed; + Initialize(); + } + + public Crc32(UInt32 polynomial, UInt32 seed) + { + table = InitializeTable(polynomial); + this.seed = seed; + Initialize(); + } + + public override void Initialize() + { + hash = seed; + } + + protected override void HashCore(byte[] buffer, int start, int length) + { + hash = CalculateHash(table, hash, buffer, start, length); + } + + protected override byte[] HashFinal() + { + byte[] hashBuffer = UInt32ToBigEndianBytes(~hash); + this.HashValue = hashBuffer; + return hashBuffer; + } + + public override int HashSize + { + get { return 32; } + } + + public static UInt32 Compute(byte[] buffer) + { + return ~CalculateHash(InitializeTable(DefaultPolynomial), DefaultSeed, buffer, 0, buffer.Length); + } + + public static UInt32 Compute(UInt32 seed, byte[] buffer) + { + return ~CalculateHash(InitializeTable(DefaultPolynomial), seed, buffer, 0, buffer.Length); + } + + public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer) + { + return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length); + } + + private static UInt32[] InitializeTable(UInt32 polynomial) + { + if (polynomial == DefaultPolynomial && defaultTable != null) + return defaultTable; + + UInt32[] createTable = new UInt32[256]; + for (int i = 0; i < 256; i++) + { + UInt32 entry = (UInt32)i; + for (int j = 0; j < 8; j++) + if ((entry & 1) == 1) + entry = (entry >> 1) ^ polynomial; + else + entry = entry >> 1; + createTable[i] = entry; + } + + if (polynomial == DefaultPolynomial) + defaultTable = createTable; + + return createTable; + } + + private static UInt32 CalculateHash(UInt32[] table, UInt32 seed, byte[] buffer, int start, int size) + { + UInt32 crc = seed; + for (int i = start; i < size; i++) + unchecked + { + crc = (crc >> 8) ^ table[buffer[i] ^ crc & 0xff]; + } + return crc; + } + + private byte[] UInt32ToBigEndianBytes(UInt32 x) + { + return new byte[] { + (byte)((x >> 24) & 0xff), + (byte)((x >> 16) & 0xff), + (byte)((x >> 8) & 0xff), + (byte)(x & 0xff) }; + } + } +} diff --git a/OpenSim/Framework/CustomTypes.cs b/OpenSim/Framework/CustomTypes.cs new file mode 100644 index 0000000..d109c26 --- /dev/null +++ b/OpenSim/Framework/CustomTypes.cs @@ -0,0 +1,43 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; + +namespace OpenSim.Framework +{ + public enum CustomAssetType : sbyte + { + CustomTypeBase = 0x60, + AnimationSet = 0x60, + } + + public enum CustomInventoryType : sbyte + { + CustomTypeBase = 0x60, + AnimationSet = 0x60, + } +} diff --git a/OpenSim/Framework/DAMap.cs b/OpenSim/Framework/DAMap.cs index 4995a92..1915fa5 100644 --- a/OpenSim/Framework/DAMap.cs +++ b/OpenSim/Framework/DAMap.cs @@ -63,9 +63,9 @@ namespace OpenSim.Framework { get { return m_map; } set { m_map = value; } - } - - public XmlSchema GetSchema() { return null; } + } + + public XmlSchema GetSchema() { return null; } public static DAMap FromXml(string rawXml) { @@ -73,19 +73,19 @@ namespace OpenSim.Framework map.ReadXml(rawXml); return map; } - + public void ReadXml(XmlReader reader) - { - ReadXml(reader.ReadInnerXml()); + { + ReadXml(reader.ReadInnerXml()); } public void ReadXml(string rawXml) - { + { // System.Console.WriteLine("Trying to deserialize [{0}]", rawXml); - + lock (this) { - m_map = (OSDMap)OSDParser.DeserializeLLSDXml(rawXml); + m_map = (OSDMap)OSDParser.DeserializeLLSDXml(rawXml); SanitiseMap(this); } } @@ -104,7 +104,7 @@ namespace OpenSim.Framework public void CopyFrom(DAMap other) { // Deep copy - + string data = null; lock (other) { @@ -113,7 +113,7 @@ namespace OpenSim.Framework data = OSDParser.SerializeLLSDXmlString(other.m_map); } } - + lock (this) { if (data == null) @@ -185,9 +185,9 @@ namespace OpenSim.Framework /// /// Get the number of stores. /// - public int CountStores + public int CountStores { - get + get { int count = 0; @@ -263,8 +263,8 @@ namespace OpenSim.Framework throw new Exception("Minimum namespace length is " + MIN_NAMESPACE_LENGTH); } - public bool ContainsStore(string ns, string storeName) - { + public bool ContainsStore(string ns, string storeName) + { OSD namespaceOsd; lock (this) @@ -276,7 +276,7 @@ namespace OpenSim.Framework } return false; - } + } public bool TryGetStore(string ns, string storeName, out OSDMap store) { @@ -297,17 +297,17 @@ namespace OpenSim.Framework store = null; return false; - } + } public void Clear() { lock (this) m_map.Clear(); - } + } public bool RemoveStore(string ns, string storeName) { - OSD namespaceOsd; + OSD namespaceOsd; lock (this) { @@ -323,6 +323,6 @@ namespace OpenSim.Framework } return false; - } + } } } \ No newline at end of file diff --git a/OpenSim/Framework/DOMap.cs b/OpenSim/Framework/DOMap.cs index f5b650b..033cbf9 100644 --- a/OpenSim/Framework/DOMap.cs +++ b/OpenSim/Framework/DOMap.cs @@ -47,7 +47,7 @@ namespace OpenSim.Framework public class DOMap { private IDictionary m_map; - + public void Add(string ns, string objName, object dynObj) { DAMap.ValidateNamespace(ns); diff --git a/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs b/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs index 9056548..816523b 100644 --- a/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs +++ b/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs @@ -55,6 +55,11 @@ namespace OpenSim.Framework Dictionary2 = new Dictionary(capacity); } + ~DoubleDictionaryThreadAbortSafe() + { + rwLock.Dispose(); + } + public void Add(TKey1 key1, TKey2 key2, TValue value) { bool gotLock = false; @@ -64,31 +69,29 @@ namespace OpenSim.Framework // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing // the acquision inside the main try. The inner finally block is needed because thread aborts cannot // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). - try {} + try {} finally { rwLock.EnterWriteLock(); gotLock = true; + if (Dictionary1.ContainsKey(key1)) + { + if (!Dictionary2.ContainsKey(key2)) + throw new ArgumentException("key1 exists in the dictionary but not key2"); + } + else if (Dictionary2.ContainsKey(key2)) + { + if (!Dictionary1.ContainsKey(key1)) + throw new ArgumentException("key2 exists in the dictionary but not key1"); + } + Dictionary1[key1] = value; + Dictionary2[key2] = value; } - - if (Dictionary1.ContainsKey(key1)) - { - if (!Dictionary2.ContainsKey(key2)) - throw new ArgumentException("key1 exists in the dictionary but not key2"); - } - else if (Dictionary2.ContainsKey(key2)) - { - if (!Dictionary1.ContainsKey(key1)) - throw new ArgumentException("key2 exists in the dictionary but not key1"); - } - - Dictionary1[key1] = value; - Dictionary2[key2] = value; } - finally - { + finally + { if (gotLock) - rwLock.ExitWriteLock(); + rwLock.ExitWriteLock(); } } @@ -102,20 +105,19 @@ namespace OpenSim.Framework // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing // the acquision inside the main try. The inner finally block is needed because thread aborts cannot // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). - try {} + try {} finally { rwLock.EnterWriteLock(); gotLock = true; + Dictionary1.Remove(key1); + success = Dictionary2.Remove(key2); } - - Dictionary1.Remove(key1); - success = Dictionary2.Remove(key2); } - finally - { + finally + { if (gotLock) - rwLock.ExitWriteLock(); + rwLock.ExitWriteLock(); } return success; @@ -131,7 +133,7 @@ namespace OpenSim.Framework // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing // the acquision inside the main try. The inner finally block is needed because thread aborts cannot // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). - try {} + try {} finally { rwLock.EnterWriteLock(); @@ -146,18 +148,22 @@ namespace OpenSim.Framework { if (kvp.Value.Equals(value)) { - Dictionary1.Remove(key1); - Dictionary2.Remove(kvp.Key); + try { } + finally + { + Dictionary1.Remove(key1); + Dictionary2.Remove(kvp.Key); + } found = true; break; } } } } - finally - { + finally + { if (gotLock) - rwLock.ExitWriteLock(); + rwLock.ExitWriteLock(); } return found; @@ -173,7 +179,7 @@ namespace OpenSim.Framework // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing // the acquision inside the main try. The inner finally block is needed because thread aborts cannot // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). - try {} + try {} finally { rwLock.EnterWriteLock(); @@ -188,18 +194,22 @@ namespace OpenSim.Framework { if (kvp.Value.Equals(value)) { - Dictionary2.Remove(key2); - Dictionary1.Remove(kvp.Key); + try { } + finally + { + Dictionary2.Remove(key2); + Dictionary1.Remove(kvp.Key); + } found = true; break; } } } } - finally - { + finally + { if (gotLock) - rwLock.ExitWriteLock(); + rwLock.ExitWriteLock(); } return found; @@ -214,20 +224,19 @@ namespace OpenSim.Framework // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing // the acquision inside the main try. The inner finally block is needed because thread aborts cannot // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). - try {} + try {} finally { rwLock.EnterWriteLock(); gotLock = true; + Dictionary1.Clear(); + Dictionary2.Clear(); } - - Dictionary1.Clear(); - Dictionary2.Clear(); } - finally - { + finally + { if (gotLock) - rwLock.ExitWriteLock(); + rwLock.ExitWriteLock(); } } @@ -251,24 +260,24 @@ namespace OpenSim.Framework bool success; bool gotLock = false; - try - { + try + { // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing // the acquision inside the main try. The inner finally block is needed because thread aborts cannot // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). - try {} + try {} finally { rwLock.EnterReadLock(); gotLock = true; } - success = Dictionary1.TryGetValue(key, out value); + success = Dictionary1.TryGetValue(key, out value); } - finally - { + finally + { if (gotLock) - rwLock.ExitReadLock(); + rwLock.ExitReadLock(); } return success; @@ -279,24 +288,24 @@ namespace OpenSim.Framework bool success; bool gotLock = false; - try - { + try + { // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing // the acquision inside the main try. The inner finally block is needed because thread aborts cannot // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). - try {} + try {} finally { rwLock.EnterReadLock(); gotLock = true; } - success = Dictionary2.TryGetValue(key, out value); + success = Dictionary2.TryGetValue(key, out value); } - finally - { + finally + { if (gotLock) - rwLock.ExitReadLock(); + rwLock.ExitReadLock(); } return success; @@ -311,7 +320,7 @@ namespace OpenSim.Framework // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing // the acquision inside the main try. The inner finally block is needed because thread aborts cannot // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). - try {} + try {} finally { rwLock.EnterReadLock(); @@ -321,10 +330,10 @@ namespace OpenSim.Framework foreach (TValue value in Dictionary1.Values) action(value); } - finally - { + finally + { if (gotLock) - rwLock.ExitReadLock(); + rwLock.ExitReadLock(); } } @@ -337,7 +346,7 @@ namespace OpenSim.Framework // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing // the acquision inside the main try. The inner finally block is needed because thread aborts cannot // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). - try {} + try {} finally { rwLock.EnterReadLock(); @@ -347,10 +356,10 @@ namespace OpenSim.Framework foreach (KeyValuePair entry in Dictionary1) action(entry); } - finally - { + finally + { if (gotLock) - rwLock.ExitReadLock(); + rwLock.ExitReadLock(); } } @@ -363,7 +372,7 @@ namespace OpenSim.Framework // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing // the acquision inside the main try. The inner finally block is needed because thread aborts cannot // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). - try {} + try {} finally { rwLock.EnterReadLock(); @@ -373,10 +382,10 @@ namespace OpenSim.Framework foreach (KeyValuePair entry in Dictionary2) action(entry); } - finally - { + finally + { if (gotLock) - rwLock.ExitReadLock(); + rwLock.ExitReadLock(); } } @@ -389,7 +398,7 @@ namespace OpenSim.Framework // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing // the acquision inside the main try. The inner finally block is needed because thread aborts cannot // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). - try {} + try {} finally { rwLock.EnterReadLock(); @@ -402,10 +411,10 @@ namespace OpenSim.Framework return value; } } - finally - { + finally + { if (gotLock) - rwLock.ExitReadLock(); + rwLock.ExitReadLock(); } return default(TValue); @@ -421,7 +430,7 @@ namespace OpenSim.Framework // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing // the acquision inside the main try. The inner finally block is needed because thread aborts cannot // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). - try {} + try {} finally { rwLock.EnterReadLock(); @@ -434,10 +443,10 @@ namespace OpenSim.Framework list.Add(value); } } - finally - { + finally + { if (gotLock) - rwLock.ExitReadLock(); + rwLock.ExitReadLock(); } return list; @@ -453,7 +462,7 @@ namespace OpenSim.Framework // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing // the acquision inside the main try. The inner finally block is needed because thread aborts cannot // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). - try {} + try {} finally { rwLock.EnterUpgradeableReadLock(); @@ -477,29 +486,29 @@ namespace OpenSim.Framework try { - try {} + try {} finally { - rwLock.EnterUpgradeableReadLock(); + rwLock.EnterWriteLock(); gotWriteLock = true; - } - for (int i = 0; i < list.Count; i++) - Dictionary1.Remove(list[i]); + for (int i = 0; i < list.Count; i++) + Dictionary1.Remove(list[i]); - for (int i = 0; i < list2.Count; i++) - Dictionary2.Remove(list2[i]); + for (int i = 0; i < list2.Count; i++) + Dictionary2.Remove(list2[i]); + } } - finally - { + finally + { if (gotWriteLock) - rwLock.ExitWriteLock(); + rwLock.ExitWriteLock(); } } - finally - { + finally + { if (gotUpgradeableLock) - rwLock.ExitUpgradeableReadLock(); + rwLock.ExitUpgradeableReadLock(); } return list.Count; diff --git a/OpenSim/Framework/EntityTransferContext.cs b/OpenSim/Framework/EntityTransferContext.cs new file mode 100644 index 0000000..860414e --- /dev/null +++ b/OpenSim/Framework/EntityTransferContext.cs @@ -0,0 +1,70 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Framework +{ + public class EntityTransferContext + { + public EntityTransferContext() + { + InboundVersion = VersionInfo.SimulationServiceVersionAcceptedMax; + OutboundVersion = VersionInfo.SimulationServiceVersionSupportedMax; + WearablesCount = -1; + } + + public float InboundVersion { get; set; } + public float OutboundVersion { get; set; } + public int WearablesCount { get; set; } + + public OSD Pack() + { + OSDMap data = new OSDMap(); + data["InboundVersion"] = OSD.FromReal(InboundVersion); + data["OutboundVersion"] = OSD.FromReal(OutboundVersion); + data["WearablesCount"] = OSD.FromInteger(WearablesCount); + + return data; + } + + public void Unpack(OSD data) + { + OSDMap map = (OSDMap)data; + + if (map.ContainsKey("InboundVersion")) + InboundVersion = (float)map["InboundVersion"].AsReal(); + if (map.ContainsKey("OutboundVersion")) + OutboundVersion = (float)map["OutboundVersion"].AsReal(); + if (map.ContainsKey("WearablesCount")) + WearablesCount = map["WearablesCount"].AsInteger(); + } + } +} diff --git a/OpenSim/Framework/EstateBan.cs b/OpenSim/Framework/EstateBan.cs index ebed794..12a92bb 100644 --- a/OpenSim/Framework/EstateBan.cs +++ b/OpenSim/Framework/EstateBan.cs @@ -43,7 +43,7 @@ namespace OpenSim.Framework { get { - return m_estateID; + return m_estateID; } set { diff --git a/OpenSim/Framework/EstateSettings.cs b/OpenSim/Framework/EstateSettings.cs index 4df7860..8c8270a 100644 --- a/OpenSim/Framework/EstateSettings.cs +++ b/OpenSim/Framework/EstateSettings.cs @@ -305,11 +305,17 @@ namespace OpenSim.Framework OnSave(this); } + public int EstateUsersCount() + { + return l_EstateAccess.Count; + } + public void AddEstateUser(UUID avatarID) { if (avatarID == UUID.Zero) return; - if (!l_EstateAccess.Contains(avatarID)) + if (!l_EstateAccess.Contains(avatarID) && + (l_EstateAccess.Count < (int)Constants.EstateAccessLimits.AllowedAccess)) l_EstateAccess.Add(avatarID); } @@ -319,11 +325,17 @@ namespace OpenSim.Framework l_EstateAccess.Remove(avatarID); } + public int EstateGroupsCount() + { + return l_EstateGroups.Count; + } + public void AddEstateGroup(UUID avatarID) { if (avatarID == UUID.Zero) return; - if (!l_EstateGroups.Contains(avatarID)) + if (!l_EstateGroups.Contains(avatarID) && + (l_EstateGroups.Count < (int)Constants.EstateAccessLimits.AllowedGroups)) l_EstateGroups.Add(avatarID); } @@ -333,11 +345,17 @@ namespace OpenSim.Framework l_EstateGroups.Remove(avatarID); } + public int EstateManagersCount() + { + return l_EstateManagers.Count; + } + public void AddEstateManager(UUID avatarID) { if (avatarID == UUID.Zero) return; - if (!l_EstateManagers.Contains(avatarID)) + if (!l_EstateManagers.Contains(avatarID) && + (l_EstateManagers.Count < (int)Constants.EstateAccessLimits.EstateManagers)) l_EstateManagers.Add(avatarID); } @@ -365,17 +383,55 @@ namespace OpenSim.Framework public bool IsBanned(UUID avatarID) { - foreach (EstateBan ban in l_EstateBans) + if (!IsEstateManagerOrOwner(avatarID)) + { + foreach (EstateBan ban in l_EstateBans) + if (ban.BannedUserID == avatarID) + return true; + } + return false; + } + + public bool IsBanned(UUID avatarID, int userFlags) + { + if (!IsEstateManagerOrOwner(avatarID)) + { + foreach (EstateBan ban in l_EstateBans) if (ban.BannedUserID == avatarID) return true; + + if (!HasAccess(avatarID)) + { + if (DenyMinors) + { + if ((userFlags & 32) == 0) + { + return true; + } + } + if (DenyAnonymous) + { + if ((userFlags & 4) == 0) + { + return true; + } + } + } + } return false; } + public int EstateBansCount() + { + return l_EstateBans.Count; + } + public void AddBan(EstateBan ban) { if (ban == null) return; - if (!IsBanned(ban.BannedUserID)) + if (!IsBanned(ban.BannedUserID, 32) && + (l_EstateBans.Count < (int)Constants.EstateAccessLimits.EstateBans)) //Ignore age-based bans l_EstateBans.Add(ban); } @@ -516,14 +572,41 @@ namespace OpenSim.Framework // EstateBans are special if (map.ContainsKey("EstateBans")) - { - var banData = ((Dictionary)map["EstateBans"]).Values; - EstateBan[] bans = new EstateBan[banData.Count]; - int b = 0; - foreach (Dictionary ban in banData) - bans[b++] = new EstateBan(ban); - PropertyInfo bansProperty = this.GetType().GetProperty("EstateBans", BindingFlags.Public | BindingFlags.Instance); - bansProperty.SetValue(this, bans, null); + { + if(map["EstateBans"] is string) + { + // JSON encoded bans map + Dictionary bdata = new Dictionary(); + try + { + // bypass libovm, we dont need even more useless high level maps + // this should only be called once.. but no problem, i hope + // (other uses may need more..) + LitJson.JsonMapper.RegisterImporter((input) => new UUID(input)); + bdata = LitJson.JsonMapper.ToObject>((string)map["EstateBans"]); + } + // catch(Exception e) + catch + { + return; + } + EstateBan[] jbans = new EstateBan[bdata.Count]; + bdata.Values.CopyTo(jbans,0); + + PropertyInfo jbansProperty = this.GetType().GetProperty("EstateBans", BindingFlags.Public | BindingFlags.Instance); + jbansProperty.SetValue(this, jbans, null); + } + else + { + var banData = ((Dictionary)map["EstateBans"]).Values; + EstateBan[] bans = new EstateBan[banData.Count]; + + int b = 0; + foreach (Dictionary ban in banData) + bans[b++] = new EstateBan(ban); + PropertyInfo bansProperty = this.GetType().GetProperty("EstateBans", BindingFlags.Public | BindingFlags.Instance); + bansProperty.SetValue(this, bans, null); + } } } } diff --git a/OpenSim/Framework/GridInstantMessage.cs b/OpenSim/Framework/GridInstantMessage.cs index da3690c..1605005 100644 --- a/OpenSim/Framework/GridInstantMessage.cs +++ b/OpenSim/Framework/GridInstantMessage.cs @@ -66,6 +66,7 @@ namespace OpenSim.Framework Position = im.Position; binaryBucket = im.binaryBucket; RegionID = im.RegionID; + ParentEstateID = im.ParentEstateID; if (addTimestamp) timestamp = (uint)Util.UnixTimeSinceEpoch(); @@ -84,6 +85,7 @@ namespace OpenSim.Framework fromGroup = _fromGroup; message = _message; imSessionID = _imSessionID.Guid; + if (_offline) offline = 1; else diff --git a/OpenSim/Framework/IAssetCache.cs b/OpenSim/Framework/IAssetCache.cs new file mode 100644 index 0000000..2df9199 --- /dev/null +++ b/OpenSim/Framework/IAssetCache.cs @@ -0,0 +1,71 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Framework; + +namespace OpenSim.Framework +{ + public interface IAssetCache + { + /// + /// Cache the specified asset. + /// + /// + void Cache(AssetBase asset); + + /// + /// Cache that the specified asset wasn't found. + /// + /// + /// + void CacheNegative(string id); + + /// Get an asset by its id. + /// + /// + /// Will be set to null if no asset was found + /// False if the asset has been negative-cached + bool Get(string id, out AssetBase asset); + + /// + /// Check whether an asset with the specified id exists in the cache. + /// + /// + bool Check(string id); + + /// + /// Expire an asset from the cache. + /// + /// + void Expire(string id); + + /// + /// Clear the cache. + /// + void Clear(); + } +} diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index e36edb2..a9044d5 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -47,10 +47,12 @@ namespace OpenSim.Framework public delegate void ImprovedInstantMessage(IClientAPI remoteclient, GridInstantMessage im); - public delegate void RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, - UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, - bool RezSelected, bool RemoveItem, UUID fromTaskID); + public delegate void RezObject(IClientAPI remoteClient, UUID itemID, UUID GroupID, + Vector3 RayEnd, Vector3 RayStart, + UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, + bool RezSelected, bool RemoveItem, UUID fromTaskID); + public delegate void RezRestoreToWorld(IClientAPI remoteClient, UUID itemId); public delegate ISceneEntity RezSingleAttachmentFromInv(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); public delegate void RezMultipleAttachmentsFromInv(IClientAPI remoteClient, List> rezlist ); @@ -58,20 +60,21 @@ namespace OpenSim.Framework public delegate void ObjectAttach( IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent); - public delegate void ModifyTerrain(UUID user, + public delegate void ModifyTerrain(UUID user, float height, float seconds, byte size, byte action, float north, float west, float south, float east, UUID agentId); public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes); - public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List cachedTextureRequest); - public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 AvSize, WearableCacheItem[] CacheItems); + public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List cachedTextureRequest); public delegate void StartAnim(IClientAPI remoteClient, UUID animID); public delegate void StopAnim(IClientAPI remoteClient, UUID animID); + public delegate void ChangeAnim(UUID animID, bool addOrRemove, bool sendPack); + public delegate void LinkObjects(IClientAPI remoteClient, uint parent, List children); public delegate void DelinkObjects(List primIds, IClientAPI client); @@ -104,7 +107,7 @@ namespace OpenSim.Framework public delegate void GenericCall4(Packet packet, IClientAPI remoteClient); public delegate void DeRezObject( - IClientAPI remoteClient, List localIDs, UUID groupID, DeRezAction action, UUID destinationID); + IClientAPI remoteClient, List localIDs, UUID groupID, DeRezAction action, UUID destinationID, bool AddToReturns = true); public delegate void GenericCall5(IClientAPI remoteClient, bool status); @@ -114,7 +117,7 @@ namespace OpenSim.Framework public delegate void ObjectExtraParams(UUID agentID, uint localID, ushort type, bool inUse, byte[] data); - public delegate void ObjectSelect(uint localID, IClientAPI remoteClient); + public delegate void ObjectSelect(List localID, IClientAPI remoteClient); public delegate void ObjectRequest(uint localID, IClientAPI remoteClient); @@ -132,6 +135,8 @@ namespace OpenSim.Framework public delegate void UpdateVector(uint localID, Vector3 pos, IClientAPI remoteClient); + public delegate void ClientChangeObject(uint localID, object data ,IClientAPI remoteClient); + public delegate void UpdatePrimRotation(uint localID, Quaternion rot, IClientAPI remoteClient); public delegate void UpdatePrimSingleRotation(uint localID, Quaternion rot, IClientAPI remoteClient); @@ -222,10 +227,10 @@ namespace OpenSim.Framework byte RayEndIsIntersection); public delegate void RequestGodlikePowers( - UUID AgentID, UUID SessionID, UUID token, bool GodLike, IClientAPI remote_client); + UUID AgentID, UUID SessionID, UUID token, bool GodLike); public delegate void GodKickUser( - UUID GodAgentID, UUID GodSessionID, UUID AgentID, uint kickflags, byte[] reason); + UUID GodAgentID, UUID AgentID, uint kickflags, byte[] reason); public delegate void CreateInventoryFolder( IClientAPI remoteClient, UUID folderID, ushort folderType, string folderName, UUID parentID); @@ -238,7 +243,7 @@ namespace OpenSim.Framework public delegate void CreateNewInventoryItem( IClientAPI remoteClient, UUID transActionID, UUID folderID, uint callbackID, string description, string name, - sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask, int creationDate); + sbyte invType, sbyte type, byte wearableType, uint everyoneMask, int creationDate); public delegate void LinkInventoryItem( IClientAPI remoteClient, UUID transActionID, UUID folderID, uint callbackID, string description, string name, @@ -268,6 +273,9 @@ namespace OpenSim.Framework public delegate void MoveInventoryItem( IClientAPI remoteClient, List items); + public delegate void MoveItemsAndLeaveCopy( + IClientAPI remoteClient, List items, UUID destFolder); + public delegate void RemoveInventoryItem( IClientAPI remoteClient, List itemIDs); @@ -443,6 +451,7 @@ namespace OpenSim.Framework public delegate void ClassifiedInfoRequest(UUID classifiedID, IClientAPI client); public delegate void ClassifiedInfoUpdate(UUID classifiedID, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, Vector3 globalPos, byte classifiedFlags, int price, IClientAPI client); public delegate void ClassifiedDelete(UUID classifiedID, IClientAPI client); + public delegate void ClassifiedGodDelete(UUID classifiedID, UUID queryID, IClientAPI client); public delegate void EventNotificationAddRequest(uint EventID, IClientAPI client); public delegate void EventNotificationRemoveRequest(uint EventID, IClientAPI client); @@ -464,47 +473,48 @@ namespace OpenSim.Framework public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client); public delegate void AgentFOV(IClientAPI client, float verticalAngle); - - public delegate void MuteListEntryUpdate(IClientAPI client, UUID MuteID, string Name, int Flags,UUID AgentID); - - public delegate void MuteListEntryRemove(IClientAPI client, UUID MuteID, string Name, UUID AgentID); - + + public delegate void MuteListEntryUpdate(IClientAPI client, UUID MuteID, string Name, int type, uint flags); + + public delegate void MuteListEntryRemove(IClientAPI client, UUID MuteID, string Name); + public delegate void AvatarInterestReply(IClientAPI client,UUID target, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages); - + public delegate void FindAgentUpdate(IClientAPI client, UUID hunter, UUID target); - + public delegate void TrackAgentUpdate(IClientAPI client, UUID hunter, UUID target); - + public delegate void FreezeUserUpdate(IClientAPI client, UUID parcelowner,uint flags, UUID target); - + public delegate void EjectUserUpdate(IClientAPI client, UUID parcelowner,uint flags, UUID target); - + public delegate void NewUserReport(IClientAPI client, string regionName,UUID abuserID, byte catagory, byte checkflags, string details, UUID objectID, Vector3 postion, byte reportType ,UUID screenshotID, string Summary, UUID reporter); - + public delegate void GodUpdateRegionInfoUpdate(IClientAPI client, float BillableFactor, ulong EstateID, ulong RegionFlags, byte[] SimName,int RedirectX, int RedirectY); - + public delegate void GodlikeMessage(IClientAPI client, UUID requester, byte[] Method, byte[] Parameter); - + public delegate void SaveStateHandler(IClientAPI client,UUID agentID); - + public delegate void GroupAccountSummaryRequest(IClientAPI client,UUID agentID, UUID groupID); - + public delegate void GroupAccountDetailsRequest(IClientAPI client,UUID agentID, UUID groupID, UUID transactionID, UUID sessionID); - + public delegate void GroupAccountTransactionsRequest(IClientAPI client,UUID agentID, UUID groupID, UUID transactionID, UUID sessionID); - + public delegate void ParcelBuyPass(IClientAPI client, UUID agentID, int ParcelLocalID); - + public delegate void ParcelGodMark(IClientAPI client, UUID agentID, int ParcelLocalID); - + public delegate void GroupActiveProposalsRequest(IClientAPI client,UUID agentID, UUID groupID, UUID transactionID, UUID sessionID); - + public delegate void GroupVoteHistoryRequest(IClientAPI client,UUID agentID, UUID groupID, UUID transactionID, UUID sessionID); - - + + public delegate void SimWideDeletesDelegate(IClientAPI client,UUID agentID, int flags, UUID targetID); - + public delegate void SendPostcard(IClientAPI client); + public delegate void ChangeInventoryItemFlags(IClientAPI client, UUID itemID, uint flags); #endregion @@ -575,10 +585,10 @@ namespace OpenSim.Framework public float dwell; } - public class IEntityUpdate + public class EntityUpdate { private ISceneEntity m_entity; - private uint m_flags; + private PrimUpdateFlags m_flags; private int m_updateTime; public ISceneEntity Entity @@ -586,7 +596,7 @@ namespace OpenSim.Framework get { return m_entity; } } - public uint Flags + public PrimUpdateFlags Flags { get { return m_flags; } } @@ -596,23 +606,30 @@ namespace OpenSim.Framework get { return m_updateTime; } } - public virtual void Update(IEntityUpdate update) + public virtual void Update(EntityUpdate oldupdate) { - m_flags |= update.Flags; + // we are on the new one + PrimUpdateFlags updateFlags = oldupdate.Flags; + if(m_flags.HasFlag(PrimUpdateFlags.CancelKill)) + m_flags = PrimUpdateFlags.FullUpdate; + else if(updateFlags.HasFlag(PrimUpdateFlags.Kill)) + return; + else // kill case will just merge in + m_flags |= updateFlags; // Use the older of the updates as the updateTime - if (Util.EnvironmentTickCountCompare(UpdateTime, update.UpdateTime) > 0) - m_updateTime = update.UpdateTime; + if (Util.EnvironmentTickCountCompare(UpdateTime, oldupdate.UpdateTime) > 0) + m_updateTime = oldupdate.UpdateTime; } - public IEntityUpdate(ISceneEntity entity, uint flags) + public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags) { m_entity = entity; m_flags = flags; m_updateTime = Util.EnvironmentTickCount(); } - public IEntityUpdate(ISceneEntity entity, uint flags, Int32 updateTime) + public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, Int32 updateTime) { m_entity = entity; m_flags = flags; @@ -620,29 +637,6 @@ namespace OpenSim.Framework } } - public class EntityUpdate : IEntityUpdate - { - private float m_timeDilation; - - public float TimeDilation - { - get { return m_timeDilation; } - } - - public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation) - : base(entity, (uint)flags) - { - // Flags = flags; - m_timeDilation = timedilation; - } - - public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation, Int32 updateTime) - : base(entity,(uint)flags,updateTime) - { - m_timeDilation = timedilation; - } - } - public class PlacesReplyData { public UUID OwnerID; @@ -691,9 +685,13 @@ namespace OpenSim.Framework ExtraData = 1 << 20, Sound = 1 << 21, Joint = 1 << 22, - FullUpdate = UInt32.MaxValue + FullUpdate = 0x0fffffff, + SendInTransit = 0x20000000, + CancelKill = 0x4fffffff, // 1 << 30 + Kill = 0x80000000 // 1 << 31 } +/* included in .net 4.0 public static class PrimUpdateFlagsExtensions { public static bool HasFlag(this PrimUpdateFlags updateFlags, PrimUpdateFlags flag) @@ -701,7 +699,7 @@ namespace OpenSim.Framework return (updateFlags & flag) == flag; } } - +*/ public interface IClientAPI { Vector3 StartPos { get; set; } @@ -718,11 +716,15 @@ namespace OpenSim.Framework UUID SecureSessionId { get; } - UUID ActiveGroupId { get; } + UUID ActiveGroupId { get; set; } + + string ActiveGroupName { get; set;} - string ActiveGroupName { get; } + ulong ActiveGroupPowers { get; set;} - ulong ActiveGroupPowers { get; } + Dictionary GetGroupPowers(); + + void SetGroupPowers(Dictionary powers); ulong GetGroupPowers(UUID groupID); @@ -734,6 +736,8 @@ namespace OpenSim.Framework IScene Scene { get; } + List SelectedObjects { get; } + // [Obsolete("LLClientView Specific - Replace with ???")] int NextAnimationSequenceNumber { get; } @@ -747,6 +751,8 @@ namespace OpenSim.Framework /// bool IsActive { get; set; } + int PingTimeMS { get; } + /// /// Set if the client is closing due to a logout request /// @@ -758,7 +764,7 @@ namespace OpenSim.Framework /// Only set for root agents. /// bool IsLoggingOut { get; set; } - + bool SendLogoutPacketWhenClosing { set; } // [Obsolete("LLClientView Specific - Circuits are unique to LLClientView")] @@ -794,6 +800,7 @@ namespace OpenSim.Framework event ObjectDrop OnObjectDrop; event StartAnim OnStartAnim; event StopAnim OnStopAnim; + event ChangeAnim OnChangeAnim; event LinkObjects OnLinkObjects; event DelinkObjects OnDelinkObjects; event RequestMapBlocks OnRequestMapBlocks; @@ -805,6 +812,7 @@ namespace OpenSim.Framework event TeleportLandmarkRequest OnTeleportLandmarkRequest; event TeleportCancel OnTeleportCancel; event DeRezObject OnDeRezObject; + event RezRestoreToWorld OnRezRestoreToWorld; event Action OnRegionHandShakeReply; event GenericCall1 OnRequestWearables; event Action OnCompleteMovementToRegion; @@ -860,6 +868,7 @@ namespace OpenSim.Framework event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; event UpdatePrimFlags OnUpdatePrimFlags; event UpdatePrimTexture OnUpdatePrimTexture; + event ClientChangeObject onClientChangeObject; event UpdateVector OnUpdatePrimGroupPosition; event UpdateVector OnUpdatePrimSinglePosition; event UpdatePrimRotation OnUpdatePrimGroupRotation; @@ -884,6 +893,7 @@ namespace OpenSim.Framework event RequestTaskInventory OnRequestTaskInventory; event UpdateInventoryItem OnUpdateInventoryItem; event CopyInventoryItem OnCopyInventoryItem; + event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy; event MoveInventoryItem OnMoveInventoryItem; event RemoveInventoryFolder OnRemoveInventoryFolder; event RemoveInventoryItem OnRemoveInventoryItem; @@ -1002,7 +1012,7 @@ namespace OpenSim.Framework event ClassifiedInfoRequest OnClassifiedInfoRequest; event ClassifiedInfoUpdate OnClassifiedInfoUpdate; event ClassifiedDelete OnClassifiedDelete; - event ClassifiedDelete OnClassifiedGodDelete; + event ClassifiedGodDelete OnClassifiedGodDelete; event EventNotificationAddRequest OnEventNotificationAddRequest; event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; @@ -1025,7 +1035,7 @@ namespace OpenSim.Framework event MuteListRequest OnMuteListRequest; event PlacesQuery OnPlacesQuery; - + event FindAgentUpdate OnFindAgent; event TrackAgentUpdate OnTrackAgent; event NewUserReport OnUserReport; @@ -1041,11 +1051,12 @@ namespace OpenSim.Framework event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; event SimWideDeletesDelegate OnSimWideDeletes; event SendPostcard OnSendPostcard; + event ChangeInventoryItemFlags OnChangeInventoryItemFlags; event MuteListEntryUpdate OnUpdateMuteListEntry; event MuteListEntryRemove OnRemoveMuteListEntry; event GodlikeMessage onGodlikeMessage; event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; - + event GenericCall2 OnUpdateThrottles; /// /// Set the debug level at which packet output should be printed to console. /// @@ -1066,15 +1077,15 @@ namespace OpenSim.Framework /// If true, attempts the close without checking active status. You do not want to try this except as a last /// ditch attempt where Active == false but the ScenePresence still exists. /// - void Close(bool force); + void Close(bool sendStop, bool force); void Kick(string message); - + /// /// Start processing for this client. /// void Start(); - + void Stop(); // void ActivateGesture(UUID assetId, UUID gestureId); @@ -1102,6 +1113,8 @@ namespace OpenSim.Framework /// void SendKillObject(List localID); +// void SendPartFullUpdate(ISceneEntity ent, uint? parentID); + void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs); void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args); @@ -1125,11 +1138,13 @@ namespace OpenSim.Framework void SendGenericMessage(string method, UUID invoice, List message); void SendGenericMessage(string method, UUID invoice, List message); + bool CanSendLayerData(); + void SendLayerData(float[] map); void SendLayerData(int px, int py, float[] map); - void SendWindData(Vector2[] windSpeeds); - void SendCloudData(float[] cloudCover); + void SendWindData(int version, Vector2[] windSpeeds); + void SendCloudData(int version, float[] cloudCover); /// /// Sent when an agent completes its movement into a region. @@ -1141,7 +1156,7 @@ namespace OpenSim.Framework void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look); void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourExternalEndPoint); - + /// /// Return circuit information for this client. /// @@ -1168,8 +1183,13 @@ namespace OpenSim.Framework void SendCoarseLocationUpdate(List users, List CoarseLocations); void SetChildAgentThrottle(byte[] throttle); + void SetChildAgentThrottle(byte[] throttle,float factor); + + void SetAgentThrottleSilent(int throttle, int setting); + int GetAgentThrottleSilent(int throttle); - void SendAvatarDataImmediate(ISceneEntity avatar); + void SendEntityFullUpdateImmediate(ISceneEntity entity); + void SendEntityTerseUpdateImmediate(ISceneEntity entity); /// /// Send a positional, velocity, etc. update to the viewer for a given entity. @@ -1192,6 +1212,7 @@ namespace OpenSim.Framework /// /// void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId); + void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId); void SendRemoveInventoryItem(UUID itemID); @@ -1204,14 +1225,14 @@ namespace OpenSim.Framework /// /// Used by the server to inform the client of new inventory items and folders. /// - /// + /// /// If the node is a folder then the contents will be transferred /// (including all descendent folders) as well as the folder itself. - /// + /// /// void SendBulkUpdateInventory(InventoryNodeBase node); - void SendXferPacket(ulong xferID, uint packet, byte[] data); + void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory); void SendAbortXferPacket(ulong xferID); @@ -1237,9 +1258,11 @@ namespace OpenSim.Framework void SendAttachedSoundGainChange(UUID objectID, float gain); void SendNameReply(UUID profileId, string firstname, string lastname); - void SendAlertMessage(string message); + void SendAlertMessage(string message); + void SendAlertMessage(string message, string into); void SendAgentAlertMessage(string message, bool modal); + void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message, string url); /// @@ -1268,11 +1291,11 @@ namespace OpenSim.Framework /// The orbital position is given in radians, and must be "adjusted" for the linden client, see LLClientView void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition); - + void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks); void SendViewerTime(int phase); - void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember, string flAbout, + void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] membershipType, string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID); void SendScriptQuestion(UUID taskID, string taskName, string ownerName, UUID itemID, int question); @@ -1336,7 +1359,7 @@ namespace OpenSim.Framework void SendImageFirstPart(ushort numParts, UUID ImageUUID, uint ImageSize, byte[] ImageData, byte imageCodec); /// - /// Send the next packet for a series of packets making up a single texture, + /// Send the next packet for a series of packets making up a single texture, /// as established by SendImageFirstPart() /// /// @@ -1361,12 +1384,16 @@ namespace OpenSim.Framework void SendObjectPropertiesReply(ISceneEntity Entity); + void SendSelectedPartsProprieties(List parts); + void SendPartPhysicsProprieties(ISceneEntity Entity); void SendAgentOffline(UUID[] agentIDs); void SendAgentOnline(UUID[] agentIDs); + void SendFindAgent(UUID HunterID, UUID PreyID, double GlobalX, double GlobalY); + void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook); @@ -1432,6 +1459,7 @@ namespace OpenSim.Framework void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags); void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data); + void SendAgentGroupDataUpdate(UUID avatarID, GroupMembershipData[] data); void SendOfferCallingCard(UUID srcID, UUID transactionID); void SendAcceptCallingCard(UUID transactionID); void SendDeclineCallingCard(UUID transactionID); @@ -1443,6 +1471,9 @@ namespace OpenSim.Framework void SendAgentDropGroup(UUID groupID); void RefreshGroupMembership(); + void UpdateGroupMembership(GroupMembershipData[] data); + void GroupMembershipRemove(UUID GroupID); + void GroupMembershipAddReplace(UUID GroupID,ulong GroupPowers); void SendAvatarNotesReply(UUID targetID, string text); void SendAvatarPicksReply(UUID targetID, Dictionary picks); void SendPickInfoReply(UUID pickID,UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled); @@ -1452,9 +1483,9 @@ namespace OpenSim.Framework void SendParcelDwellReply(int localID, UUID parcelID, float dwell); void SendUserInfoReply(bool imViaEmail, bool visible, string email); - - void SendUseCachedMuteList(); + void SendUseCachedMuteList(); + void SendEmpytMuteList(); void SendMuteListUpdate(string filename); void SendGroupActiveProposals(UUID groupID, UUID transactionID, GroupActiveProposals[] Proposals); @@ -1466,13 +1497,13 @@ namespace OpenSim.Framework void SendRebakeAvatarTextures(UUID textureID); void SendAvatarInterestsReply(UUID avatarID, uint wantMask, string wantText, uint skillsMask, string skillsText, string languages); - + void SendGroupAccountingDetails(IClientAPI sender,UUID groupID, UUID transactionID, UUID sessionID, int amt); - + void SendGroupAccountingSummary(IClientAPI sender,UUID groupID, uint moneyAmt, int totalTier, int usedTier); - + void SendGroupTransactionsSummaryDetails(IClientAPI sender,UUID groupID, UUID transactionID, UUID sessionID,int amt); - + void SendChangeUserRights(UUID agentID, UUID friendID, int rights); void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId); diff --git a/OpenSim/Framework/ICnmCache.cs b/OpenSim/Framework/ICnmCache.cs index 27b9c56..69b5b42 100644 --- a/OpenSim/Framework/ICnmCache.cs +++ b/OpenSim/Framework/ICnmCache.cs @@ -34,10 +34,10 @@ namespace OpenSim.Framework /// Represent generic cache to store key/value pairs (elements) limited by time, size and count of elements. /// /// - /// The type of keys in the cache. + /// The type of keys in the cache. /// /// - /// The type of values in the cache. + /// The type of values in the cache. /// /// /// @@ -51,8 +51,8 @@ namespace OpenSim.Framework /// /// Time /// - /// Element that is not accessed through or in last are - /// removed from the cache automatically. Depending on implementation of the cache some of elements may stay longer in cache. + /// Element that is not accessed through or in last are + /// removed from the cache automatically. Depending on implementation of the cache some of elements may stay longer in cache. /// returns , if cache is limited by time. /// /// @@ -60,7 +60,7 @@ namespace OpenSim.Framework /// Count /// /// When adding an new element to cache that already have of elements, cache will remove less recently - /// used element(s) from the cache, until element fits to cache. + /// used element(s) from the cache, until element fits to cache. /// returns , if cache is limiting element count. /// /// @@ -69,8 +69,8 @@ namespace OpenSim.Framework /// /// /// When adding an new element to cache that already have of elements, cache will remove less recently - /// used element(s) from the cache, until element fits to cache. - /// returns , if cache is limiting total size of elements. + /// used element(s) from the cache, until element fits to cache. + /// returns , if cache is limiting total size of elements. /// Normally size is bytes used by element in the cache. But it can be any other suitable unit of measure. /// /// @@ -84,8 +84,8 @@ namespace OpenSim.Framework /// /// /// - /// When adding an new element to that is limiting element count, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting element count, + /// will remove less recently used elements until it can fit an new element. /// /// /// @@ -102,13 +102,13 @@ namespace OpenSim.Framework /// /// /// - /// When element has been stored in longer than - /// and it is not accessed through method or element's value is - /// not replaced by method, then it is automatically removed from the + /// When element has been stored in longer than + /// and it is not accessed through method or element's value is + /// not replaced by method, then it is automatically removed from the /// . /// /// - /// It is possible that implementation removes element before it's expiration time, + /// It is possible that implementation removes element before it's expiration time, /// because total size or count of elements stored to cache is larger than or . /// /// @@ -135,12 +135,12 @@ namespace OpenSim.Framework /// Gets a value indicating whether or not access to the is synchronized (thread safe). /// /// - /// if access to the is synchronized (thread safe); - /// otherwise, . + /// if access to the is synchronized (thread safe); + /// otherwise, . /// /// /// - /// To get synchronized (thread safe) access to object, use + /// To get synchronized (thread safe) access to object, use /// in class /// to retrieve synchronized wrapper for object. /// @@ -153,17 +153,17 @@ namespace OpenSim.Framework /// Gets a value indicating whether is limiting count of elements. /// /// - /// if the count of elements is limited; - /// otherwise, . + /// if the count of elements is limited; + /// otherwise, . /// /// /// - /// When adding an new element to that is limiting element count, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting element count, + /// will remove less recently used elements until it can fit an new element. /// /// /// - /// + /// /// /// bool IsCountLimited { get; } @@ -172,13 +172,13 @@ namespace OpenSim.Framework /// Gets a value indicating whether is limiting size of elements. /// /// - /// if the total size of elements is limited; - /// otherwise, . + /// if the total size of elements is limited; + /// otherwise, . /// /// /// - /// When adding an new element to that is limiting total size of elements, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting total size of elements, + /// will remove less recently used elements until it can fit an new element. /// /// /// @@ -192,13 +192,13 @@ namespace OpenSim.Framework /// Gets a value indicating whether elements stored to have limited inactivity time. /// /// - /// if the has a fixed total size of elements; - /// otherwise, . + /// if the has a fixed total size of elements; + /// otherwise, . /// /// /// If have limited inactivity time and element is not accessed through - /// or methods in , then element is automatically removed from - /// the cache. Depending on implementation of the , some of the elements may + /// or methods in , then element is automatically removed from + /// the cache. Depending on implementation of the , some of the elements may /// stay longer in cache. /// /// @@ -206,18 +206,18 @@ namespace OpenSim.Framework /// /// bool IsTimeLimited { get; } - + /// /// Gets or sets maximal allowed count of elements that can be stored to . /// /// - /// , if is not limited by count of elements; + /// , if is not limited by count of elements; /// otherwise maximal allowed count of elements. /// /// /// - /// When adding an new element to that is limiting element count, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting element count, + /// will remove less recently used elements until it can fit an new element. /// /// int MaxCount { get; set; } @@ -230,7 +230,7 @@ namespace OpenSim.Framework /// /// /// - /// If element's size is larger than , then element is + /// If element's size is larger than , then element is /// not added to the . /// /// @@ -251,8 +251,8 @@ namespace OpenSim.Framework /// Normally size is total bytes used by elements in the cache. But it can be any other suitable unit of measure. /// /// - /// When adding an new element to that is limiting total size of elements, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting total size of elements, + /// will remove less recently used elements until it can fit an new element. /// /// /// value is less than 0. @@ -272,11 +272,11 @@ namespace OpenSim.Framework /// Normally bytes, but can be any suitable unit of measure. /// /// - /// Element's size is given when element is added or replaced by method. + /// Element's size is given when element is added or replaced by method. /// /// - /// When adding an new element to that is limiting total size of elements, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting total size of elements, + /// will remove less recently used elements until it can fit an new element. /// /// /// @@ -294,8 +294,8 @@ namespace OpenSim.Framework /// /// /// - /// To get synchronized (thread safe) access to , use - /// method to retrieve synchronized wrapper interface to + /// To get synchronized (thread safe) access to , use + /// method to retrieve synchronized wrapper interface to /// . /// /// @@ -367,7 +367,7 @@ namespace OpenSim.Framework void RemoveRange(IEnumerable keys); /// - /// Add or replace an element with the provided , and to + /// Add or replace an element with the provided , and to /// . /// /// @@ -380,7 +380,7 @@ namespace OpenSim.Framework /// The element's size. Normally bytes, but can be any suitable unit of measure. /// /// - /// if element has been added successfully to the ; + /// if element has been added successfully to the ; /// otherwise . /// /// @@ -391,17 +391,17 @@ namespace OpenSim.Framework /// /// /// - /// If element's is larger than , then element is - /// not added to the , however - possible older element is - /// removed from the . + /// If element's is larger than , then element is + /// not added to the , however - possible older element is + /// removed from the . /// /// - /// When adding an new element to that is limiting total size of elements, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting total size of elements, + /// will remove less recently used elements until it can fit an new element. /// /// - /// When adding an new element to that is limiting element count, - /// will remove less recently used elements until it can fit an new element. + /// When adding an new element to that is limiting element count, + /// will remove less recently used elements until it can fit an new element. /// /// /// @@ -417,15 +417,15 @@ namespace OpenSim.Framework /// Gets the associated with the specified . /// /// - /// if the contains an element with + /// if the contains an element with /// the specified key; otherwise, . /// /// /// The key whose to get. /// /// - /// When this method returns, the value associated with the specified , - /// if the is found; otherwise, the + /// When this method returns, the value associated with the specified , + /// if the is found; otherwise, the /// default value for the type of the parameter. This parameter is passed uninitialized. /// /// diff --git a/OpenSim/Framework/IImprovedAssetCache.cs b/OpenSim/Framework/IImprovedAssetCache.cs deleted file mode 100644 index a853e90..0000000 --- a/OpenSim/Framework/IImprovedAssetCache.cs +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using OpenSim.Framework; - -namespace OpenSim.Framework -{ - public interface IImprovedAssetCache - { - /// - /// Cache the specified asset. - /// - /// - void Cache(AssetBase asset); - - /// - /// Get an asset by its id. - /// - /// - /// null if the asset does not exist. - AssetBase Get(string id); - - /// - /// Check whether an asset with the specified id exists in the cache. - /// - /// - bool Check(string id); - - /// - /// Expire an asset from the cache. - /// - /// - void Expire(string id); - - /// - /// Clear the cache. - /// - void Clear(); - } -} \ No newline at end of file diff --git a/OpenSim/Framework/ILandChannel.cs b/OpenSim/Framework/ILandChannel.cs index c46c03c..8667837 100644 --- a/OpenSim/Framework/ILandChannel.cs +++ b/OpenSim/Framework/ILandChannel.cs @@ -38,7 +38,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// List AllParcels(); - + /// /// Get the parcel at the specified point /// @@ -75,7 +75,9 @@ namespace OpenSim.Region.Framework.Interfaces /// /// ILandObject GetLandObject(int localID); - + + ILandObject GetLandObject(UUID GlobalID); + /// /// Clear the land channel of all parcels. /// @@ -83,9 +85,10 @@ namespace OpenSim.Region.Framework.Interfaces /// If true, set up a default parcel covering the whole region owned by the estate owner. /// void Clear(bool setupDefaultParcel); - + bool IsForcefulBansAllowed(); void UpdateLandObject(int localID, LandData data); + void SendParcelsOverlay(IClientAPI client); void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient); void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel); void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel); @@ -93,5 +96,7 @@ namespace OpenSim.Region.Framework.Interfaces void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id); void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id); + void sendClientInitialLandInfo(IClientAPI remoteClient); + } } diff --git a/OpenSim/Framework/ILandObject.cs b/OpenSim/Framework/ILandObject.cs index 8465c86..a783256 100644 --- a/OpenSim/Framework/ILandObject.cs +++ b/OpenSim/Framework/ILandObject.cs @@ -43,32 +43,39 @@ namespace OpenSim.Framework LandData LandData { get; set; } bool[,] LandBitmap { get; set; } UUID RegionUUID { get; } - + /// /// Prim counts for this land object. /// IPrimCounts PrimCounts { get; set; } - + /// - /// The start point for the land object. This is the western-most point as one scans land working from - /// north to south. + /// The start point for the land object. This is the northern-most point as one scans land working from + /// west to east. /// - Vector3 StartPoint { get; } - + Vector2 StartPoint { get; } + /// - /// The end point for the land object. This is the eastern-most point as one scans land working from - /// south to north. - /// - Vector3 EndPoint { get; } - + /// The end point for the land object. This is the southern-most point as one scans land working from + /// west to east. + /// + Vector2 EndPoint { get; } + + // a estimation of a parcel center. + Vector2 CenterPoint { get; } + + // get positions + Vector2? GetNearestPoint(Vector3 pos); + Vector2? GetNearestPointAlongDirection(Vector3 pos, Vector3 pdirection); + bool ContainsPoint(int x, int y); - + ILandObject Copy(); void SendLandUpdateToAvatarsOverMe(); void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client); - void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client); + bool UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client, out bool snap_selection, out bool needOverlay); bool IsEitherBannedOrRestricted(UUID avatar); bool IsBannedFromLand(UUID avatar); bool CanBeOnThisLand(UUID avatar, float posHeight); @@ -90,27 +97,70 @@ namespace OpenSim.Framework /// /// The bitmap created. bool[,] BasicFullRegionLandBitmap(); - + /// /// Create a square land bitmap. /// /// /// Land co-ordinates are zero indexed. The inputs are treated as points. So if you want to create a bitmap - /// that covers an entire 256 x 256m region apart from a strip of land on the east, then you would need to - /// specify start_x = 0, start_y = 0, end_x = 252 (or anything up to 255), end_y = 256. - /// - /// At the moment, the smallest parcel of land is 4m x 4m, so if the + /// that covers an entire 256 x 256m region apart from a strip of land on the east, then you would need to + /// specify start_x = 0, start_y = 0, end_x = 252 (or anything up to 255), end_y = 255. + /// + /// At the moment, the smallest parcel of land is 4m x 4m, so if the /// region is 256 x 256m (the SL size), the bitmap returned will start at (0,0) and end at (63,63). + /// The value of the set_value needs to be true to define an active parcel of the given size. /// /// /// /// /// + /// /// The bitmap created. - bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y); - + bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y, bool set_value = true); + bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, bool set_value); + + /// + /// Merge two (same size) land bitmaps. + /// + /// + /// + /// The modified bitmap. bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add); + + /// + /// Remap a land bitmap. Takes the supplied land bitmap and rotates it, crops it and finally offsets it into + /// a final land bitmap of the target region size. + /// + /// The original parcel bitmap + /// + /// <x,y,?> + /// <x,y,?> + /// <x,y,?> + /// <x,y,?> + /// out: This is set if the resultant bitmap is now empty + /// out: parcel.AABBMin <x,y,0> + /// out: parcel.AABBMax <x,y,0> + /// New parcel bitmap + bool[,] RemapLandBitmap(bool[,] bitmap_base, Vector2 displacement, float rotationDegrees, Vector2 boundingOrigin, Vector2 boundingSize, Vector2 regionSize, out bool isEmptyNow, out Vector3 AABBMin, out Vector3 AABBMax); + + /// + /// Clears any parcel data in bitmap_base where there exists parcel data in bitmap_new. In other words the parcel data + /// in bitmap_new takes over the space of the parcel data in bitmap_base. + /// + /// + /// + /// out: This is set if the resultant bitmap is now empty + /// out: parcel.AABBMin <x,y,0> + /// out: parcel.AABBMax <x,y,0> + /// New parcel bitmap + bool[,] RemoveFromLandBitmap(bool[,] bitmap_base, bool[,] bitmap_new, out bool isEmptyNow, out Vector3 AABBMin, out Vector3 AABBMax); + + byte[] ConvertLandBitmapToBytes(); + bool[,] ConvertBytesToLandBitmap(bool overrideRegionSize = false); + bool IsLandBitmapEmpty(bool[,] landBitmap); + void DebugLandBitmap(bool[,] landBitmap); + void SendForceObjectSelect(int local_id, int request_type, List returnIDs, IClientAPI remote_client); void SendLandObjectOwners(IClientAPI remote_client); void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client); @@ -127,7 +177,7 @@ namespace OpenSim.Framework /// /// void SetMediaUrl(string url); - + /// /// Set the music url for this land parcel /// @@ -139,5 +189,7 @@ namespace OpenSim.Framework /// /// The music url. string GetMusicUrl(); + + void Clear(); } } diff --git a/OpenSim/Framework/IMoneyModule.cs b/OpenSim/Framework/IMoneyModule.cs index 52f3e83..c72c742 100644 --- a/OpenSim/Framework/IMoneyModule.cs +++ b/OpenSim/Framework/IMoneyModule.cs @@ -32,15 +32,16 @@ namespace OpenSim.Framework public delegate void ObjectPaid(UUID objectID, UUID agentID, int amount); public interface IMoneyModule { - bool ObjectGiveMoney(UUID objectID, UUID fromID, UUID toID, - int amount); + bool ObjectGiveMoney(UUID objectID, UUID fromID, + UUID toID, int amount, UUID txn, out string reason); int GetBalance(UUID agentID); bool UploadCovered(UUID agentID, int amount); bool AmountCovered(UUID agentID, int amount); - void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type); - void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData); + void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData = ""); void ApplyUploadCharge(UUID agentID, int amount, string text); + void MoveMoney(UUID fromUser, UUID toUser, int amount, string text); + bool MoveMoney(UUID fromUser, UUID toUser, int amount, MoneyTransactionType type, string text); int UploadCharge { get; } int GroupCreationCharge { get; } diff --git a/OpenSim/Framework/IPrimCounts.cs b/OpenSim/Framework/IPrimCounts.cs index 3e12348..3b62ad3 100644 --- a/OpenSim/Framework/IPrimCounts.cs +++ b/OpenSim/Framework/IPrimCounts.cs @@ -35,12 +35,12 @@ namespace OpenSim.Framework /// Parcel owner owned prims /// int Owner { get; } - + /// /// Parcel group owned prims /// int Group { get; } - + /// /// Prims owned by others (not parcel owner or parcel group). /// @@ -48,19 +48,19 @@ namespace OpenSim.Framework /// /// Selected prims - /// - int Selected { get; } - + /// + int Selected { get; } + /// /// Total prims on the parcel. /// int Total { get; } - + /// /// Prims on the simulator that are owned by the parcel owner, even if they are in other parcels. /// int Simulator { get; } - + /// /// Prims per individual users. /// diff --git a/OpenSim/Framework/IRegistryCore.cs b/OpenSim/Framework/IRegistryCore.cs index a94b65d..cf3ecc0 100644 --- a/OpenSim/Framework/IRegistryCore.cs +++ b/OpenSim/Framework/IRegistryCore.cs @@ -31,7 +31,7 @@ using System.Text; namespace OpenSim.Framework { - public interface IRegistryCore + public interface IRegistryCore { T Get(); void RegisterInterface(T iface); diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs index e1b6d1e..37a064f 100644 --- a/OpenSim/Framework/IScene.cs +++ b/OpenSim/Framework/IScene.cs @@ -40,7 +40,7 @@ namespace OpenSim.Framework Crashed = 2, Starting = 3, }; - + /// /// Indicate what action to take on an object derez request /// @@ -118,7 +118,7 @@ namespace OpenSim.Framework /// /// void RegisterModuleInterface(M mod); - + void StackModuleInterface(M mod); /// diff --git a/OpenSim/Framework/ISceneAgent.cs b/OpenSim/Framework/ISceneAgent.cs index ca1399c..5d70b83 100644 --- a/OpenSim/Framework/ISceneAgent.cs +++ b/OpenSim/Framework/ISceneAgent.cs @@ -55,6 +55,10 @@ namespace OpenSim.Framework /// bool IsChildAgent { get; } + bool IsInTransit { get; } + bool IsNPC { get;} + + bool Invulnerable { get; set; } /// /// Avatar appearance data. /// @@ -66,22 +70,17 @@ namespace OpenSim.Framework AvatarAppearance Appearance { get; set; } /// - /// Set if initial data about the scene (avatars, objects) has been sent to the client. - /// - bool SentInitialDataToClient { get; } - - /// /// Send initial scene data to the client controlling this agent /// /// /// This includes scene object data and the appearance data of other avatars. /// - void SendInitialDataToClient(); + void SendInitialDataToMe(); - /// + /// /// Direction in which the scene presence is looking. /// /// Will be Vector3.Zero for a child agent. - Vector3 Lookat { get; } + Vector3 Lookat { get; } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/InventoryFolderImpl.cs b/OpenSim/Framework/InventoryFolderImpl.cs index 139776b..d14f3be 100644 --- a/OpenSim/Framework/InventoryFolderImpl.cs +++ b/OpenSim/Framework/InventoryFolderImpl.cs @@ -314,7 +314,7 @@ namespace OpenSim.Framework /// XPath like expression /// /// FIXME: Delimitors which occur in names themselves are not currently escapable. - /// + /// /// /// The path to the required folder. /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. diff --git a/OpenSim/Framework/InventoryItemBase.cs b/OpenSim/Framework/InventoryItemBase.cs index f9fd752..c359a0c 100644 --- a/OpenSim/Framework/InventoryItemBase.cs +++ b/OpenSim/Framework/InventoryItemBase.cs @@ -34,17 +34,17 @@ namespace OpenSim.Framework /// Inventory Item - contains all the properties associated with an individual inventory piece. /// public class InventoryItemBase : InventoryNodeBase, ICloneable - { + { /// /// The inventory type of the item. This is slightly different from the asset type in some situations. /// - public int InvType - { + public int InvType + { get { return m_invType; } - + set { m_invType = value; @@ -55,13 +55,13 @@ namespace OpenSim.Framework /// /// The folder this item is contained in /// - public UUID Folder - { + public UUID Folder + { get { return m_folder; } - + set { m_folder = value; @@ -72,17 +72,17 @@ namespace OpenSim.Framework /// /// The creator of this item /// - public string CreatorId - { + public string CreatorId + { get { - return m_creatorId; + return m_creatorId; } - + set { m_creatorId = value; - + if ((m_creatorId == null) || !UUID.TryParse(m_creatorId, out m_creatorIdAsUuid)) m_creatorIdAsUuid = UUID.Zero; } @@ -92,7 +92,7 @@ namespace OpenSim.Framework /// /// The CreatorId expressed as a UUID. /// - public UUID CreatorIdAsUuid + public UUID CreatorIdAsUuid { get { @@ -161,13 +161,13 @@ namespace OpenSim.Framework /// /// The description of the inventory item (must be less than 64 characters) /// - public string Description - { + public string Description + { get { return m_description; } - + set { m_description = value; @@ -178,13 +178,13 @@ namespace OpenSim.Framework /// /// /// - public uint NextPermissions - { + public uint NextPermissions + { get { return m_nextPermissions; } - + set { m_nextPermissions = value; @@ -195,13 +195,13 @@ namespace OpenSim.Framework /// /// A mask containing permissions for the current owner (cannot be enforced) /// - public uint CurrentPermissions - { + public uint CurrentPermissions + { get { return m_currentPermissions; } - + set { m_currentPermissions = value; @@ -212,13 +212,13 @@ namespace OpenSim.Framework /// /// /// - public uint BasePermissions - { + public uint BasePermissions + { get { return m_basePermissions; } - + set { m_basePermissions = value; @@ -229,13 +229,13 @@ namespace OpenSim.Framework /// /// /// - public uint EveryOnePermissions - { + public uint EveryOnePermissions + { get { return m_everyonePermissions; } - + set { m_everyonePermissions = value; @@ -246,13 +246,13 @@ namespace OpenSim.Framework /// /// /// - public uint GroupPermissions - { + public uint GroupPermissions + { get { return m_groupPermissions; } - + set { m_groupPermissions = value; @@ -263,13 +263,13 @@ namespace OpenSim.Framework /// /// This is an enumerated value determining the type of asset (eg Notecard, Sound, Object, etc) /// - public int AssetType - { + public int AssetType + { get { return m_assetType; } - + set { m_assetType = value; @@ -280,13 +280,13 @@ namespace OpenSim.Framework /// /// The UUID of the associated asset on the asset server /// - public UUID AssetID - { + public UUID AssetID + { get { return m_assetID; } - + set { m_assetID = value; @@ -297,13 +297,13 @@ namespace OpenSim.Framework /// /// /// - public UUID GroupID - { + public UUID GroupID + { get { return m_groupID; } - + set { m_groupID = value; @@ -314,13 +314,13 @@ namespace OpenSim.Framework /// /// /// - public bool GroupOwned - { + public bool GroupOwned + { get { return m_groupOwned; } - + set { m_groupOwned = value; @@ -331,13 +331,13 @@ namespace OpenSim.Framework /// /// /// - public int SalePrice - { + public int SalePrice + { get { return m_salePrice; } - + set { m_salePrice = value; @@ -348,13 +348,13 @@ namespace OpenSim.Framework /// /// /// - public byte SaleType - { + public byte SaleType + { get { return m_saleType; } - + set { m_saleType = value; @@ -365,13 +365,13 @@ namespace OpenSim.Framework /// /// /// - public uint Flags - { + public uint Flags + { get { return m_flags; } - + set { m_flags = value; @@ -382,13 +382,13 @@ namespace OpenSim.Framework /// /// /// - public int CreationDate - { + public int CreationDate + { get { return m_creationDate; } - + set { m_creationDate = value; diff --git a/OpenSim/Framework/InventoryNodeBase.cs b/OpenSim/Framework/InventoryNodeBase.cs index 31c3fd1..9ef36b7 100644 --- a/OpenSim/Framework/InventoryNodeBase.cs +++ b/OpenSim/Framework/InventoryNodeBase.cs @@ -41,19 +41,19 @@ namespace OpenSim.Framework { get { return m_name; } set { m_name = value; } - } + } private string m_name = string.Empty; - + /// /// A UUID containing the ID for the inventory node itself /// - public UUID ID + public UUID ID { get { return m_id; } set { m_id = value; } } private UUID m_id; - + /// /// The agent who's inventory this is contained by /// diff --git a/OpenSim/Framework/LandData.cs b/OpenSim/Framework/LandData.cs index fc02f33..13b58be 100644 --- a/OpenSim/Framework/LandData.cs +++ b/OpenSim/Framework/LandData.cs @@ -67,11 +67,11 @@ namespace OpenSim.Framework private uint _flags = (uint)ParcelFlags.AllowFly | (uint)ParcelFlags.AllowLandmark | (uint)ParcelFlags.AllowAPrimitiveEntry | - (uint)ParcelFlags.AllowDeedToGroup | (uint)ParcelFlags.AllowTerraform | + (uint)ParcelFlags.AllowDeedToGroup | (uint)ParcelFlags.CreateObjects | (uint)ParcelFlags.AllowOtherScripts | - (uint)ParcelFlags.SoundLocal | (uint)ParcelFlags.AllowVoiceChat; + (uint)ParcelFlags.AllowVoiceChat; - private byte _landingType = 0; + private byte _landingType = (byte)OpenMetaverse.LandingType.Direct; private string _name = "Your Parcel"; private ParcelStatus _status = ParcelStatus.Leased; private int _localID = 0; @@ -97,7 +97,13 @@ namespace OpenSim.Framework private bool _mediaLoop = false; private bool _obscureMusic = false; private bool _obscureMedia = false; - private float _dwell = 0; + + private float m_dwell = 0; + public double LastDwellTimeMS; + + public bool SeeAVs { get; set; } + public bool AnyAVSounds { get; set; } + public bool GroupAVSounds { get; set; } /// /// Traffic count of parcel @@ -107,11 +113,12 @@ namespace OpenSim.Framework { get { - return _dwell; + return m_dwell; } set { - _dwell = value; + m_dwell = value; + LastDwellTimeMS = Util.GetTimeStampMS(); } } @@ -407,7 +414,7 @@ namespace OpenSim.Framework } /// - /// Determines if people are able to teleport where they please on the parcel or if they + /// Determines if people are able to teleport where they please on the parcel or if they /// get constrainted to a specific point on teleport within the parcel /// public byte LandingType @@ -616,7 +623,7 @@ namespace OpenSim.Framework } /// - /// Number of meters^2 in the Simulator + /// Number of meters^2 that the land owner has in the Simulator /// [XmlIgnore] public int SimwideArea @@ -663,7 +670,7 @@ namespace OpenSim.Framework } /// - /// When teleporting is restricted to a certain point, this is the location + /// When teleporting is restricted to a certain point, this is the location /// that the user will be redirected to /// public Vector3 UserLocation @@ -679,7 +686,7 @@ namespace OpenSim.Framework } /// - /// When teleporting is restricted to a certain point, this is the rotation + /// When teleporting is restricted to a certain point, this is the rotation /// that the user will be positioned /// public Vector3 UserLookAt @@ -695,7 +702,7 @@ namespace OpenSim.Framework } /// - /// Autoreturn number of minutes to return SceneObjectGroup that are owned by someone who doesn't own + /// Autoreturn number of minutes to return SceneObjectGroup that are owned by someone who doesn't own /// the parcel and isn't set to the same 'group' as the parcel. /// public int OtherCleanTime @@ -728,6 +735,10 @@ namespace OpenSim.Framework public LandData() { _globalID = UUID.Random(); + SeeAVs = true; + AnyAVSounds = true; + GroupAVSounds = true; + LastDwellTimeMS = Util.GetTimeStampMS(); } /// @@ -777,7 +788,10 @@ namespace OpenSim.Framework landData._obscureMedia = _obscureMedia; landData._simwideArea = _simwideArea; landData._simwidePrims = _simwidePrims; - landData._dwell = _dwell; + landData.m_dwell = m_dwell; + landData.SeeAVs = SeeAVs; + landData.AnyAVSounds = AnyAVSounds; + landData.GroupAVSounds = GroupAVSounds; landData._parcelAccessList.Clear(); foreach (LandAccessEntry entry in _parcelAccessList) @@ -793,21 +807,21 @@ namespace OpenSim.Framework return landData; } - public void ToXml(XmlWriter xmlWriter) - { - serializer.Serialize(xmlWriter, this); - } +// public void ToXml(XmlWriter xmlWriter) +// { +// serializer.Serialize(xmlWriter, this); +// } /// /// Restore a LandData object from the serialized xml representation. /// /// /// - public static LandData FromXml(XmlReader xmlReader) - { - LandData land = (LandData)serializer.Deserialize(xmlReader); - - return land; - } +// public static LandData FromXml(XmlReader xmlReader) +// { +// LandData land = (LandData)serializer.Deserialize(xmlReader); +// +// return land; +// } } } diff --git a/OpenSim/Framework/LandUpdateArgs.cs b/OpenSim/Framework/LandUpdateArgs.cs index 7d6c4f2..a48b8bf 100644 --- a/OpenSim/Framework/LandUpdateArgs.cs +++ b/OpenSim/Framework/LandUpdateArgs.cs @@ -56,5 +56,8 @@ namespace OpenSim.Framework public bool MediaLoop; public bool ObscureMusic; public bool ObscureMedia; + public bool SeeAVs; + public bool AnyAVSounds; + public bool GroupAVSounds; } } diff --git a/OpenSim/Framework/Lazy.cs b/OpenSim/Framework/Lazy.cs index 91de4bd..ea07d0e 100644 --- a/OpenSim/Framework/Lazy.cs +++ b/OpenSim/Framework/Lazy.cs @@ -14,10 +14,10 @@ // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: -// +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND diff --git a/OpenSim/Framework/LocklessQueue.cs b/OpenSim/Framework/LocklessQueue.cs index 84f887c..21b8178 100644 --- a/OpenSim/Framework/LocklessQueue.cs +++ b/OpenSim/Framework/LocklessQueue.cs @@ -29,7 +29,7 @@ using System.Threading; namespace OpenSim.Framework { - public sealed class LocklessQueue + public class LocklessQueue { private sealed class SingleLinkNode { @@ -41,7 +41,7 @@ namespace OpenSim.Framework SingleLinkNode tail; int count; - public int Count { get { return count; } } + public virtual int Count { get { return count; } } public LocklessQueue() { @@ -76,7 +76,7 @@ namespace OpenSim.Framework Interlocked.Increment(ref count); } - public bool Dequeue(out T item) + public virtual bool Dequeue(out T item) { item = default(T); SingleLinkNode oldHead = null; @@ -93,13 +93,16 @@ namespace OpenSim.Framework if (oldHead == oldTail) { if (oldHeadNext == null) + { + count = 0; return false; + } CAS(ref tail, oldTail, oldHeadNext); } else { - item = oldHeadNext.Item; + item = oldHeadNext.Item; haveAdvancedHead = CAS(ref head, oldHead, oldHeadNext); if (haveAdvancedHead) { @@ -118,8 +121,7 @@ namespace OpenSim.Framework { // ugly T item; - while(count > 0) - Dequeue(out item); + while(Dequeue(out item)); Init(); } @@ -136,4 +138,4 @@ namespace OpenSim.Framework (object)Interlocked.CompareExchange(ref location, newValue, comparand); } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/LogWriter.cs b/OpenSim/Framework/LogWriter.cs old mode 100644 new mode 100755 diff --git a/OpenSim/Framework/MapAndArray.cs b/OpenSim/Framework/MapAndArray.cs index c98d3cc..32d6978 100644 --- a/OpenSim/Framework/MapAndArray.cs +++ b/OpenSim/Framework/MapAndArray.cs @@ -45,9 +45,9 @@ namespace OpenSim.Framework /// Number of values currently stored in the collection public int Count { get { return m_array.Length; } } - /// NOTE: This collection is thread safe. You do not need to - /// acquire a lock to add, remove, or enumerate entries. This - /// synchronization object should only be locked for larger + /// NOTE: This collection is thread safe. You do not need to + /// acquire a lock to add, remove, or enumerate entries. This + /// synchronization object should only be locked for larger /// transactions public object SyncRoot { get { return m_syncRoot; } } @@ -92,7 +92,7 @@ namespace OpenSim.Framework } /// - /// Adds a key/value pair to the collection. This will throw an + /// Adds a key/value pair to the collection. This will throw an /// exception if the key is already present in the collection /// /// Key to add or update @@ -166,7 +166,7 @@ namespace OpenSim.Framework /// Gets a reference to the immutable array of values stored in this /// collection. This array is thread safe for iteration /// - /// A thread safe reference ton an array of all of the stored + /// A thread safe reference ton an array of all of the stored /// values public TValue[] GetArray() { @@ -175,7 +175,7 @@ namespace OpenSim.Framework private void CreateArray() { - // Rebuild the array from the dictionary. This method must be + // Rebuild the array from the dictionary. This method must be // called from inside a lock TValue[] array = new TValue[m_dict.Count]; int i = 0; diff --git a/OpenSim/Framework/MapItemReplyStruct.cs b/OpenSim/Framework/MapItemReplyStruct.cs index c8693ae..348a240 100644 --- a/OpenSim/Framework/MapItemReplyStruct.cs +++ b/OpenSim/Framework/MapItemReplyStruct.cs @@ -60,7 +60,7 @@ namespace OpenSim.Framework map["Extra2"] = OSD.FromInteger(Extra2); return map; } - + public void FromOSD(OSDMap map) { x = (uint) map["X"].AsInteger(); diff --git a/OpenSim/Framework/MetricsCollector.cs b/OpenSim/Framework/MetricsCollector.cs index c8f4a33..391f57e 100644 --- a/OpenSim/Framework/MetricsCollector.cs +++ b/OpenSim/Framework/MetricsCollector.cs @@ -42,23 +42,23 @@ namespace OpenSim.Framework } } - + struct MetricsBucket { public T value; public int count; } - + /// /// Collects metrics in a sliding window. /// /// /// MetricsCollector provides the current Sum of the metrics that it collects. It can easily be extended /// to provide the Average, too. It uses a sliding window to keep these values current. - /// + /// /// This class is not thread-safe. - /// + /// /// Subclass MetricsCollector to have it use a concrete value type. Override the abstract methods. /// public abstract class MetricsCollector diff --git a/OpenSim/Framework/Monitoring/BaseStatsCollector.cs b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs index 20495f6..e513abd 100644 --- a/OpenSim/Framework/Monitoring/BaseStatsCollector.cs +++ b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs @@ -43,7 +43,6 @@ namespace OpenSim.Framework.Monitoring StringBuilder sb = new StringBuilder(Environment.NewLine); sb.Append("MEMORY STATISTICS"); sb.Append(Environment.NewLine); - sb.AppendFormat( "Heap allocated to OpenSim : {0} MB\n", Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)); @@ -56,13 +55,30 @@ namespace OpenSim.Framework.Monitoring "Average heap allocation rate: {0} MB/s\n", Math.Round((MemoryWatchdog.AverageHeapAllocationRate * 1000) / 1024.0 / 1024, 3)); - sb.AppendFormat( - "Process memory : {0} MB\n", - Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0)); + Process myprocess = Process.GetCurrentProcess(); +// if (!myprocess.HasExited) + try + { + myprocess.Refresh(); + sb.AppendFormat( + "Process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n", + Math.Round(myprocess.WorkingSet64 / 1024.0 / 1024.0), + Math.Round(myprocess.PagedMemorySize64 / 1024.0 / 1024.0), + Math.Round(myprocess.VirtualMemorySize64 / 1024.0 / 1024.0)); + sb.AppendFormat( + "Peak process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n", + Math.Round(myprocess.PeakWorkingSet64 / 1024.0 / 1024.0), + Math.Round(myprocess.PeakPagedMemorySize64 / 1024.0 / 1024.0), + Math.Round(myprocess.PeakVirtualMemorySize64 / 1024.0 / 1024.0)); + } + catch + { } +// else +// sb.Append("Process reported as Exited \n"); return sb.ToString(); } - + public virtual string XReport(string uptime, string version) { return (string) Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0).ToString() ; diff --git a/OpenSim/Framework/Monitoring/Checks/Check.cs b/OpenSim/Framework/Monitoring/Checks/Check.cs index 594386a..9a1bd45 100644 --- a/OpenSim/Framework/Monitoring/Checks/Check.cs +++ b/OpenSim/Framework/Monitoring/Checks/Check.cs @@ -79,7 +79,7 @@ namespace OpenSim.Framework.Monitoring string category, string container, Func checkFunc, - StatVerbosity verbosity) + StatVerbosity verbosity) { if (ChecksManager.SubCommands.Contains(category)) throw new Exception( @@ -108,9 +108,9 @@ namespace OpenSim.Framework.Monitoring public virtual string ToConsoleString() { return string.Format( - "{0}.{1}.{2} - {3}", - Category, - Container, + "{0}.{1}.{2} - {3}", + Category, + Container, ShortName, Description); } diff --git a/OpenSim/Framework/Monitoring/ChecksManager.cs b/OpenSim/Framework/Monitoring/ChecksManager.cs index e4a7f8c..ff3b041 100644 --- a/OpenSim/Framework/Monitoring/ChecksManager.cs +++ b/OpenSim/Framework/Monitoring/ChecksManager.cs @@ -132,8 +132,8 @@ namespace OpenSim.Framework.Monitoring /// public static bool RegisterCheck(Check check) { - SortedDictionary> category = null, newCategory; - SortedDictionary container = null, newContainer; + SortedDictionary> category = null; + SortedDictionary container = null; lock (RegisteredChecks) { @@ -146,19 +146,15 @@ namespace OpenSim.Framework.Monitoring // We take a copy-on-write approach here of replacing dictionaries when keys are added or removed. // This means that we don't need to lock or copy them on iteration, which will be a much more // common operation after startup. - if (container != null) - newContainer = new SortedDictionary(container); - else - newContainer = new SortedDictionary(); + if (container == null) + container = new SortedDictionary(); - if (category != null) - newCategory = new SortedDictionary>(category); - else - newCategory = new SortedDictionary>(); + if (category == null) + category = new SortedDictionary>(); - newContainer[check.ShortName] = check; - newCategory[check.Container] = newContainer; - RegisteredChecks[check.Category] = newCategory; + container[check.ShortName] = check; + category[check.Container] = container; + RegisteredChecks[check.Category] = category; } return true; @@ -171,23 +167,24 @@ namespace OpenSim.Framework.Monitoring /// public static bool DeregisterCheck(Check check) { - SortedDictionary> category = null, newCategory; - SortedDictionary container = null, newContainer; + SortedDictionary> category = null; + SortedDictionary container = null; lock (RegisteredChecks) { if (!TryGetCheckParents(check, out category, out container)) return false; - newContainer = new SortedDictionary(container); - newContainer.Remove(check.ShortName); - - newCategory = new SortedDictionary>(category); - newCategory.Remove(check.Container); - - newCategory[check.Container] = newContainer; - RegisteredChecks[check.Category] = newCategory; - + if(container != null) + { + container.Remove(check.ShortName); + if(category != null && container.Count == 0) + { + category.Remove(check.Container); + if(category.Count == 0) + RegisteredChecks.Remove(check.Category); + } + } return true; } } diff --git a/OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs b/OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs index 40df562..e326e8b 100644 --- a/OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs +++ b/OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs @@ -39,7 +39,7 @@ namespace OpenSim.Framework.Monitoring /// /// string Report(); - + /// /// Report back collected statistical information in json /// diff --git a/OpenSim/Framework/Monitoring/JobEngine.cs b/OpenSim/Framework/Monitoring/JobEngine.cs index 6db9a67..115871e 100644 --- a/OpenSim/Framework/Monitoring/JobEngine.cs +++ b/OpenSim/Framework/Monitoring/JobEngine.cs @@ -40,6 +40,8 @@ namespace OpenSim.Framework.Monitoring public int LogLevel { get; set; } + private object JobLock = new object(); + public string Name { get; private set; } public string LoggingName { get; private set; } @@ -47,7 +49,7 @@ namespace OpenSim.Framework.Monitoring /// /// Is this engine running? /// - public bool IsRunning { get; private set; } + public bool IsRunning { get; private set; } /// /// The current job that the engine is running. @@ -55,7 +57,8 @@ namespace OpenSim.Framework.Monitoring /// /// Will be null if no job is currently running. /// - public Job CurrentJob { get; private set; } + private Job m_currentJob; + public Job CurrentJob { get { return m_currentJob;} } /// /// Number of jobs waiting to be processed. @@ -71,96 +74,64 @@ namespace OpenSim.Framework.Monitoring /// Controls whether we need to warn in the log about exceeding the max queue size. /// /// - /// This is flipped to false once queue max has been exceeded and back to true when it falls below max, in + /// This is flipped to false once queue max has been exceeded and back to true when it falls below max, in /// order to avoid spamming the log with lots of warnings. /// private bool m_warnOverMaxQueue = true; - private BlockingCollection m_jobQueue; + private BlockingCollection m_jobQueue = new BlockingCollection(new ConcurrentQueue(), 5000); private CancellationTokenSource m_cancelSource; - /// - /// Used to signal that we are ready to complete stop. - /// - private ManualResetEvent m_finishedProcessingAfterStop = new ManualResetEvent(false); + private int m_timeout = -1; - public JobEngine(string name, string loggingName) + private bool m_threadRunnig = false; + + public JobEngine(string name, string loggingName, int timeout = -1) { Name = name; LoggingName = loggingName; - + m_timeout = timeout; RequestProcessTimeoutOnStop = 5000; } public void Start() { - lock (this) + lock (JobLock) { if (IsRunning) return; IsRunning = true; - m_finishedProcessingAfterStop.Reset(); - - m_jobQueue = new BlockingCollection(new ConcurrentQueue(), 5000); m_cancelSource = new CancellationTokenSource(); - - WorkManager.StartThread( - ProcessRequests, - Name, - ThreadPriority.Normal, - false, - true, - null, - int.MaxValue); + WorkManager.RunInThreadPool(ProcessRequests, null, Name, false); + m_threadRunnig = true; } } public void Stop() - { - lock (this) + { + lock (JobLock) { try { if (!IsRunning) return; - IsRunning = false; + m_log.DebugFormat("[JobEngine] Stopping {0}", Name); - int requestsLeft = m_jobQueue.Count; - - if (requestsLeft <= 0) + IsRunning = false; + if(m_threadRunnig) { m_cancelSource.Cancel(); - } - else - { - m_log.InfoFormat("[{0}]: Waiting to write {1} events after stop.", LoggingName, requestsLeft); - - while (requestsLeft > 0) - { - if (!m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop)) - { - // After timeout no events have been written - if (requestsLeft == m_jobQueue.Count) - { - m_log.WarnFormat( - "[{0}]: No requests processed after {1} ms wait. Discarding remaining {2} requests", - LoggingName, RequestProcessTimeoutOnStop, requestsLeft); - - break; - } - } - - requestsLeft = m_jobQueue.Count; - } + m_threadRunnig = false; } } finally { - m_cancelSource.Dispose(); + if(m_cancelSource != null) + m_cancelSource.Dispose(); } } } @@ -169,7 +140,7 @@ namespace OpenSim.Framework.Monitoring /// Make a job. /// /// - /// We provide this method to replace the constructor so that we can later pool job objects if necessary to + /// We provide this method to replace the constructor so that we can later pool job objects if necessary to /// reduce memory churn. Normally one would directly call QueueJob() with parameters anyway. /// /// @@ -219,6 +190,18 @@ namespace OpenSim.Framework.Monitoring /// public bool QueueJob(Job job) { + lock(JobLock) + { + if(!IsRunning) + return false; + + if(!m_threadRunnig) + { + WorkManager.RunInThreadPool(ProcessRequests, null, Name, false); + m_threadRunnig = true; + } + } + if (m_jobQueue.Count < m_jobQueue.BoundedCapacity) { m_jobQueue.Add(job); @@ -238,56 +221,53 @@ namespace OpenSim.Framework.Monitoring m_warnOverMaxQueue = false; } - return false; } } - private void ProcessRequests() + private void ProcessRequests(Object o) { - try + while(IsRunning) { - while (IsRunning || m_jobQueue.Count > 0) + try { - try + if(!m_jobQueue.TryTake(out m_currentJob, m_timeout, m_cancelSource.Token)) { - CurrentJob = m_jobQueue.Take(m_cancelSource.Token); - } - catch (ObjectDisposedException e) - { - // If we see this whilst not running then it may be due to a race where this thread checks - // IsRunning after the stopping thread sets it to false and disposes of the cancellation source. - if (IsRunning) - throw e; - else - break; + lock(JobLock) + m_threadRunnig = false; + break; } + } + catch(ObjectDisposedException e) + { + m_log.DebugFormat("[JobEngine] {0} stopping ignoring {1} jobs in queue", + Name,m_jobQueue.Count); + break; + } + catch(OperationCanceledException) + { + break; + } - if (LogLevel >= 1) - m_log.DebugFormat("[{0}]: Processing job {1}", LoggingName, CurrentJob.Name); + if(LogLevel >= 1) + m_log.DebugFormat("[{0}]: Processing job {1}",LoggingName,m_currentJob.Name); - try - { - CurrentJob.Action(); - } - catch (Exception e) - { - m_log.Error( - string.Format( - "[{0}]: Job {1} failed, continuing. Exception ", LoggingName, CurrentJob.Name), e); - } + try + { + m_currentJob.Action(); + } + catch(Exception e) + { + m_log.Error( + string.Format( + "[{0}]: Job {1} failed, continuing. Exception ",LoggingName,m_currentJob.Name),e); + } - if (LogLevel >= 1) - m_log.DebugFormat("[{0}]: Processed job {1}", LoggingName, CurrentJob.Name); + if(LogLevel >= 1) + m_log.DebugFormat("[{0}]: Processed job {1}",LoggingName,m_currentJob.Name); - CurrentJob = null; - } - } - catch (OperationCanceledException) - { + m_currentJob = null; } - - m_finishedProcessingAfterStop.Set(); } public class Job @@ -320,7 +300,7 @@ namespace OpenSim.Framework.Monitoring CommonId = commonId; Action = action; } - + /// /// Make a job. It needs to be separately queued. /// @@ -338,4 +318,4 @@ namespace OpenSim.Framework.Monitoring } } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/Monitoring/Properties/AssemblyInfo.cs b/OpenSim/Framework/Monitoring/Properties/AssemblyInfo.cs index a617b93..2ff2014 100644 --- a/OpenSim/Framework/Monitoring/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Monitoring/Properties/AssemblyInfo.cs @@ -2,7 +2,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("OpenSim.Framework.Monitoring")] @@ -14,8 +14,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] @@ -25,9 +25,9 @@ using System.Runtime.InteropServices; // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("0.8.3.*")] +[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] diff --git a/OpenSim/Framework/Monitoring/ServerStatsCollector.cs b/OpenSim/Framework/Monitoring/ServerStatsCollector.cs index 77315bb..a26a6e0 100644 --- a/OpenSim/Framework/Monitoring/ServerStatsCollector.cs +++ b/OpenSim/Framework/Monitoring/ServerStatsCollector.cs @@ -88,7 +88,7 @@ namespace OpenSim.Framework.Monitoring IConfig cfg = source.Configs["Monitoring"]; if (cfg != null) - Enabled = cfg.GetBoolean("ServerStatsEnabled", true); + Enabled = cfg.GetBoolean("ServerStatsEnabled", false); if (Enabled) { @@ -98,12 +98,18 @@ namespace OpenSim.Framework.Monitoring public void Start() { + if(!Enabled) + return; + if (RegisteredStats.Count == 0) RegisterServerStats(); } public void Close() { + if(!Enabled) + return; + if (RegisteredStats.Count > 0) { foreach (Stat stat in RegisteredStats.Values) @@ -167,18 +173,18 @@ namespace OpenSim.Framework.Monitoring } MakeStat("BuiltinThreadpoolWorkerThreadsAvailable", null, "threads", ContainerThreadpool, - s => - { - int workerThreads, iocpThreads; - ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads); + s => + { + int workerThreads, iocpThreads; + ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads); s.Value = workerThreads; }); MakeStat("BuiltinThreadpoolIOCPThreadsAvailable", null, "threads", ContainerThreadpool, - s => - { - int workerThreads, iocpThreads; - ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads); + s => + { + int workerThreads, iocpThreads; + ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads); s.Value = iocpThreads; }); @@ -193,10 +199,10 @@ namespace OpenSim.Framework.Monitoring } MakeStat( - "HTTPRequestsMade", - "Number of outbound HTTP requests made", - "requests", - ContainerNetwork, + "HTTPRequestsMade", + "Number of outbound HTTP requests made", + "requests", + ContainerNetwork, s => s.Value = WebUtil.RequestNumber, MeasuresOfInterest.AverageChangeOverTime); @@ -249,9 +255,52 @@ namespace OpenSim.Framework.Monitoring (s) => { s.Value = Math.Round(MemoryWatchdog.LastHeapAllocationRate * 1000d / 1024d / 1024d, 3); }); MakeStat("AverageHeapAllocationRate", null, "MB/sec", ContainerMemory, (s) => { s.Value = Math.Round(MemoryWatchdog.AverageHeapAllocationRate * 1000d / 1024d / 1024d, 3); }); + + MakeStat("ProcessResident", null, "MB", ContainerProcess, + (s) => + { + Process myprocess = Process.GetCurrentProcess(); + myprocess.Refresh(); + s.Value = Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0); + }); + MakeStat("ProcessPaged", null, "MB", ContainerProcess, + (s) => + { + Process myprocess = Process.GetCurrentProcess(); + myprocess.Refresh(); + s.Value = Math.Round(Process.GetCurrentProcess().PagedMemorySize64 / 1024.0 / 1024.0); + }); + MakeStat("ProcessVirtual", null, "MB", ContainerProcess, + (s) => + { + Process myprocess = Process.GetCurrentProcess(); + myprocess.Refresh(); + s.Value = Math.Round(Process.GetCurrentProcess().VirtualMemorySize64 / 1024.0 / 1024.0); + }); + MakeStat("PeakProcessResident", null, "MB", ContainerProcess, + (s) => + { + Process myprocess = Process.GetCurrentProcess(); + myprocess.Refresh(); + s.Value = Math.Round(Process.GetCurrentProcess().PeakWorkingSet64 / 1024.0 / 1024.0); + }); + MakeStat("PeakProcessPaged", null, "MB", ContainerProcess, + (s) => + { + Process myprocess = Process.GetCurrentProcess(); + myprocess.Refresh(); + s.Value = Math.Round(Process.GetCurrentProcess().PeakPagedMemorySize64 / 1024.0 / 1024.0); + }); + MakeStat("PeakProcessVirtual", null, "MB", ContainerProcess, + (s) => + { + Process myprocess = Process.GetCurrentProcess(); + myprocess.Refresh(); + s.Value = Math.Round(Process.GetCurrentProcess().PeakVirtualMemorySize64 / 1024.0 / 1024.0); + }); } - // Notes on performance counters: + // Notes on performance counters: // "How To Read Performance Counters": http://blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx // "How to get the CPU Usage in C#": http://stackoverflow.com/questions/278071/how-to-get-the-cpu-usage-in-c // "Mono Performance Counters": http://www.mono-project.com/Mono_Performance_Counters diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs old mode 100644 new mode 100755 index e4df7ee..88a0297 --- a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs +++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs @@ -34,6 +34,7 @@ using OpenMetaverse; using OpenMetaverse.StructuredData; using OpenSim.Framework.Monitoring.Interfaces; + namespace OpenSim.Framework.Monitoring { /// @@ -71,6 +72,11 @@ namespace OpenSim.Framework.Monitoring private volatile float pendingDownloads; private volatile float pendingUploads; private volatile float activeScripts; + private volatile float spareTime; + private volatile float sleepTime; + private volatile float physicsStep; + + private volatile float scriptLinesPerSecond; private volatile float m_frameDilation; private volatile float m_usersLoggingIn; @@ -84,17 +90,17 @@ namespace OpenSim.Framework.Monitoring // /// haven't yet been implemented... // /// // public long AssetsInCache { get { return assetsInCache; } } -// +// // /// // /// Currently unused // /// // public long TexturesInCache { get { return texturesInCache; } } -// +// // /// // /// Currently misleading since we can't currently subtract removed asset memory usage without a performance hit // /// // public long AssetCacheMemoryUsage { get { return assetCacheMemoryUsage; } } -// +// // /// // /// Currently unused // /// @@ -121,7 +127,7 @@ namespace OpenSim.Framework.Monitoring public float PendingUploads { get { return pendingUploads; } } public float ActiveScripts { get { return activeScripts; } } public float ScriptLinesPerSecond { get { return scriptLinesPerSecond; } } - + // /// // /// This is the time it took for the last asset request made in response to a cache miss. // /// @@ -171,7 +177,7 @@ namespace OpenSim.Framework.Monitoring // assetsInCache++; // //assetCacheMemoryUsage += asset.Data.Length; // } -// +// // public void RemoveAsset(UUID uuid) // { // assetsInCache--; @@ -198,7 +204,7 @@ namespace OpenSim.Framework.Monitoring // texturesInCache = 0; // textureCacheMemoryUsage = 0; // } -// +// // public void AddAssetRequestTimeAfterCacheMiss(TimeSpan ts) // { // assetRequestTimeAfterCacheMiss = ts; @@ -253,7 +259,7 @@ namespace OpenSim.Framework.Monitoring /// public void ReceiveClassicSimStatsPacket(SimStats stats) { - // FIXME: SimStats shouldn't allow an arbitrary stat packing order (which is inherited from the original + // FIXME: SimStats shouldn't allow an arbitrary stat packing order (which is inherited from the original // SimStatsPacket that was being used). // For an unknown reason the original designers decided not to @@ -270,8 +276,8 @@ namespace OpenSim.Framework.Monitoring totalFrameTime = stats.StatsBlock[8].StatValue; netFrameTime = stats.StatsBlock[9].StatValue; physicsFrameTime = stats.StatsBlock[10].StatValue; - otherFrameTime = stats.StatsBlock[11].StatValue; - imageFrameTime = stats.StatsBlock[12].StatValue; + imageFrameTime = stats.StatsBlock[11].StatValue; + otherFrameTime = stats.StatsBlock[12].StatValue; inPacketsPerSecond = stats.StatsBlock[13].StatValue; outPacketsPerSecond = stats.StatsBlock[14].StatValue; unackedBytes = stats.StatsBlock[15].StatValue; @@ -279,12 +285,16 @@ namespace OpenSim.Framework.Monitoring pendingDownloads = stats.StatsBlock[17].StatValue; pendingUploads = stats.StatsBlock[18].StatValue; activeScripts = stats.StatsBlock[19].StatValue; - scriptLinesPerSecond = stats.StatsBlock[20].StatValue; - m_frameDilation = stats.StatsBlock[22].StatValue; - m_usersLoggingIn = stats.StatsBlock[23].StatValue; - m_totalGeoPrims = stats.StatsBlock[24].StatValue; - m_totalMeshes = stats.StatsBlock[25].StatValue; - m_inUseThreads = stats.StatsBlock[26].StatValue; + sleepTime = stats.StatsBlock[20].StatValue; + spareTime = stats.StatsBlock[21].StatValue; + physicsStep = stats.StatsBlock[22].StatValue; + + scriptLinesPerSecond = stats.ExtraStatsBlock[0].StatValue; + m_frameDilation = stats.ExtraStatsBlock[1].StatValue; + m_usersLoggingIn = stats.ExtraStatsBlock[2].StatValue; + m_totalGeoPrims = stats.ExtraStatsBlock[3].StatValue; + m_totalMeshes = stats.ExtraStatsBlock[4].StatValue; + m_inUseThreads = stats.ExtraStatsBlock[5].StatValue; } /// @@ -296,7 +306,7 @@ namespace OpenSim.Framework.Monitoring StringBuilder sb = new StringBuilder(Environment.NewLine); // sb.Append("ASSET STATISTICS"); // sb.Append(Environment.NewLine); - + /* sb.Append( string.Format( @@ -332,7 +342,7 @@ Asset service request failures: {3}" + Environment.NewLine, List stats = StatsManager.GetStatsFromEachContainer("clientstack", "ClientLogoutsDueToNoReceives"); sb.AppendFormat( - "Client logouts due to no data receive timeout: {0}\n\n", + "Client logouts due to no data receive timeout: {0}\n\n", stats != null ? stats.Sum(s => s.Value).ToString() : "unknown"); // sb.Append(Environment.NewLine); @@ -433,10 +443,10 @@ Asset service request failures: {3}" + Environment.NewLine, foreach (ProcessThread currentThread in Process.GetCurrentProcess().Threads) { - // A known issue with the current process .Threads property is - // that it can return null threads, thus don't count those as + // A known issue with the current process .Threads property is + // that it can return null threads, thus don't count those as // running threads and prevent the program function from failing - if (currentThread != null && + if (currentThread != null && currentThread.ThreadState == ThreadState.Running) { numberThreadsRunning++; @@ -495,7 +505,7 @@ Asset service request failures: {3}" + Environment.NewLine, "{0:0.##}", numberThreadsRunning)); args["ProcMem"] = OSD.FromString(String.Format("{0:#,###,###.##}", memUsage)); - + return args; } } @@ -521,12 +531,12 @@ Asset service request failures: {3}" + Environment.NewLine, { return m_statsProvider.GetStats(); } - + public string XReport(string uptime, string version) { return ""; } - + public OSDMap OReport(string uptime, string version) { OSDMap ret = new OSDMap(); diff --git a/OpenSim/Framework/Monitoring/Stats/CounterStat.cs b/OpenSim/Framework/Monitoring/Stats/CounterStat.cs old mode 100644 new mode 100755 diff --git a/OpenSim/Framework/Monitoring/Stats/EventHistogram.cs b/OpenSim/Framework/Monitoring/Stats/EventHistogram.cs old mode 100644 new mode 100755 index f51f322..bc56372 --- a/OpenSim/Framework/Monitoring/Stats/EventHistogram.cs +++ b/OpenSim/Framework/Monitoring/Stats/EventHistogram.cs @@ -1,173 +1,173 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using OpenMetaverse.StructuredData; - -namespace OpenSim.Framework.Monitoring -{ -// Create a time histogram of events. The histogram is built in a wrap-around -// array of equally distributed buckets. -// For instance, a minute long histogram of second sized buckets would be: -// new EventHistogram(60, 1000) -public class EventHistogram -{ - private int m_timeBase; - private int m_numBuckets; - private int m_bucketMilliseconds; - private int m_lastBucket; - private int m_totalHistogramMilliseconds; - private long[] m_histogram; - private object histoLock = new object(); - - public EventHistogram(int numberOfBuckets, int millisecondsPerBucket) - { - m_numBuckets = numberOfBuckets; - m_bucketMilliseconds = millisecondsPerBucket; - m_totalHistogramMilliseconds = m_numBuckets * m_bucketMilliseconds; - - m_histogram = new long[m_numBuckets]; - Zero(); - m_lastBucket = 0; - m_timeBase = Util.EnvironmentTickCount(); - } - - public void Event() - { - this.Event(1); - } - - // Record an event at time 'now' in the histogram. - public void Event(int cnt) - { - lock (histoLock) - { - // The time as displaced from the base of the histogram - int bucketTime = Util.EnvironmentTickCountSubtract(m_timeBase); - - // If more than the total time of the histogram, we just start over - if (bucketTime > m_totalHistogramMilliseconds) - { - Zero(); - m_lastBucket = 0; - m_timeBase = Util.EnvironmentTickCount(); - } - else - { - // To which bucket should we add this event? - int bucket = bucketTime / m_bucketMilliseconds; - - // Advance m_lastBucket to the new bucket. Zero any buckets skipped over. - while (bucket != m_lastBucket) - { - // Zero from just after the last bucket to the new bucket or the end - for (int jj = m_lastBucket + 1; jj <= Math.Min(bucket, m_numBuckets - 1); jj++) - { - m_histogram[jj] = 0; - } - m_lastBucket = bucket; - // If the new bucket is off the end, wrap around to the beginning - if (bucket > m_numBuckets) - { - bucket -= m_numBuckets; - m_lastBucket = 0; - m_histogram[m_lastBucket] = 0; - m_timeBase += m_totalHistogramMilliseconds; - } - } - } - m_histogram[m_lastBucket] += cnt; - } - } - - // Get a copy of the current histogram - public long[] GetHistogram() - { - long[] ret = new long[m_numBuckets]; - lock (histoLock) - { - int indx = m_lastBucket + 1; - for (int ii = 0; ii < m_numBuckets; ii++, indx++) - { - if (indx >= m_numBuckets) - indx = 0; - ret[ii] = m_histogram[indx]; - } - } - return ret; - } - - public OSDMap GetHistogramAsOSDMap() - { - OSDMap ret = new OSDMap(); - - ret.Add("Buckets", OSD.FromInteger(m_numBuckets)); - ret.Add("BucketMilliseconds", OSD.FromInteger(m_bucketMilliseconds)); - ret.Add("TotalMilliseconds", OSD.FromInteger(m_totalHistogramMilliseconds)); - - // Compute a number for the first bucket in the histogram. - // This will allow readers to know how this histogram relates to any previously read histogram. - int baseBucketNum = (m_timeBase / m_bucketMilliseconds) + m_lastBucket + 1; - ret.Add("BaseNumber", OSD.FromInteger(baseBucketNum)); - - ret.Add("Values", GetHistogramAsOSDArray()); - - return ret; - } - // Get a copy of the current histogram - public OSDArray GetHistogramAsOSDArray() - { - OSDArray ret = new OSDArray(m_numBuckets); - lock (histoLock) - { - int indx = m_lastBucket + 1; - for (int ii = 0; ii < m_numBuckets; ii++, indx++) - { - if (indx >= m_numBuckets) - indx = 0; - ret[ii] = OSD.FromLong(m_histogram[indx]); - } - } - return ret; - } - - // Zero out the histogram - public void Zero() - { - lock (histoLock) - { - for (int ii = 0; ii < m_numBuckets; ii++) - m_histogram[ii] = 0; - } - } -} - -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using OpenMetaverse.StructuredData; + +namespace OpenSim.Framework.Monitoring +{ +// Create a time histogram of events. The histogram is built in a wrap-around +// array of equally distributed buckets. +// For instance, a minute long histogram of second sized buckets would be: +// new EventHistogram(60, 1000) +public class EventHistogram +{ + private int m_timeBase; + private int m_numBuckets; + private int m_bucketMilliseconds; + private int m_lastBucket; + private int m_totalHistogramMilliseconds; + private long[] m_histogram; + private object histoLock = new object(); + + public EventHistogram(int numberOfBuckets, int millisecondsPerBucket) + { + m_numBuckets = numberOfBuckets; + m_bucketMilliseconds = millisecondsPerBucket; + m_totalHistogramMilliseconds = m_numBuckets * m_bucketMilliseconds; + + m_histogram = new long[m_numBuckets]; + Zero(); + m_lastBucket = 0; + m_timeBase = Util.EnvironmentTickCount(); + } + + public void Event() + { + this.Event(1); + } + + // Record an event at time 'now' in the histogram. + public void Event(int cnt) + { + lock (histoLock) + { + // The time as displaced from the base of the histogram + int bucketTime = Util.EnvironmentTickCountSubtract(m_timeBase); + + // If more than the total time of the histogram, we just start over + if (bucketTime > m_totalHistogramMilliseconds) + { + Zero(); + m_lastBucket = 0; + m_timeBase = Util.EnvironmentTickCount(); + } + else + { + // To which bucket should we add this event? + int bucket = bucketTime / m_bucketMilliseconds; + + // Advance m_lastBucket to the new bucket. Zero any buckets skipped over. + while (bucket != m_lastBucket) + { + // Zero from just after the last bucket to the new bucket or the end + for (int jj = m_lastBucket + 1; jj <= Math.Min(bucket, m_numBuckets - 1); jj++) + { + m_histogram[jj] = 0; + } + m_lastBucket = bucket; + // If the new bucket is off the end, wrap around to the beginning + if (bucket > m_numBuckets) + { + bucket -= m_numBuckets; + m_lastBucket = 0; + m_histogram[m_lastBucket] = 0; + m_timeBase += m_totalHistogramMilliseconds; + } + } + } + m_histogram[m_lastBucket] += cnt; + } + } + + // Get a copy of the current histogram + public long[] GetHistogram() + { + long[] ret = new long[m_numBuckets]; + lock (histoLock) + { + int indx = m_lastBucket + 1; + for (int ii = 0; ii < m_numBuckets; ii++, indx++) + { + if (indx >= m_numBuckets) + indx = 0; + ret[ii] = m_histogram[indx]; + } + } + return ret; + } + + public OSDMap GetHistogramAsOSDMap() + { + OSDMap ret = new OSDMap(); + + ret.Add("Buckets", OSD.FromInteger(m_numBuckets)); + ret.Add("BucketMilliseconds", OSD.FromInteger(m_bucketMilliseconds)); + ret.Add("TotalMilliseconds", OSD.FromInteger(m_totalHistogramMilliseconds)); + + // Compute a number for the first bucket in the histogram. + // This will allow readers to know how this histogram relates to any previously read histogram. + int baseBucketNum = (m_timeBase / m_bucketMilliseconds) + m_lastBucket + 1; + ret.Add("BaseNumber", OSD.FromInteger(baseBucketNum)); + + ret.Add("Values", GetHistogramAsOSDArray()); + + return ret; + } + // Get a copy of the current histogram + public OSDArray GetHistogramAsOSDArray() + { + OSDArray ret = new OSDArray(m_numBuckets); + lock (histoLock) + { + int indx = m_lastBucket + 1; + for (int ii = 0; ii < m_numBuckets; ii++, indx++) + { + if (indx >= m_numBuckets) + indx = 0; + ret[ii] = OSD.FromLong(m_histogram[indx]); + } + } + return ret; + } + + // Zero out the histogram + public void Zero() + { + lock (histoLock) + { + for (int ii = 0; ii < m_numBuckets; ii++) + m_histogram[ii] = 0; + } + } +} + +} diff --git a/OpenSim/Framework/Monitoring/Stats/Stat.cs b/OpenSim/Framework/Monitoring/Stats/Stat.cs index a7cb2a6..2402acd 100644 --- a/OpenSim/Framework/Monitoring/Stats/Stat.cs +++ b/OpenSim/Framework/Monitoring/Stats/Stat.cs @@ -121,17 +121,17 @@ namespace OpenSim.Framework.Monitoring string container, StatType type, Action pullAction, - StatVerbosity verbosity) + StatVerbosity verbosity) : this( - shortName, - name, - description, - unitName, - category, - container, - type, - MeasuresOfInterest.None, - pullAction, + shortName, + name, + description, + unitName, + category, + container, + type, + MeasuresOfInterest.None, + pullAction, verbosity) { } @@ -227,11 +227,11 @@ namespace OpenSim.Framework.Monitoring { StringBuilder sb = new StringBuilder(); sb.AppendFormat( - "{0}.{1}.{2} : {3}{4}", - Category, - Container, - ShortName, - Value, + "{0}.{1}.{2} : {3}{4}", + Category, + Container, + ShortName, + Value, string.IsNullOrEmpty(UnitName) ? "" : string.Format(" {0}", UnitName)); AppendMeasuresOfInterest(sb); @@ -239,6 +239,17 @@ namespace OpenSim.Framework.Monitoring return sb.ToString(); } + public virtual OSDMap ToBriefOSDMap() + { + OSDMap ret = new OSDMap(); + + ret.Add("Value", OSD.FromReal(Value)); + + double lastChangeOverTime, averageChangeOverTime; + + return ret; + } + public virtual OSDMap ToOSDMap() { OSDMap ret = new OSDMap(); @@ -279,7 +290,7 @@ namespace OpenSim.Framework.Monitoring lock (m_samples) { // m_log.DebugFormat( - // "[STAT]: Samples for {0} are {1}", + // "[STAT]: Samples for {0} are {1}", // Name, string.Join(",", m_samples.Select(s => s.ToString()).ToArray())); foreach (double s in m_samples) @@ -315,12 +326,12 @@ namespace OpenSim.Framework.Monitoring if (ComputeMeasuresOfInterest(out lastChangeOverTime, out averageChangeOverTime)) { sb.AppendFormat( - ", {0:0.##}{1}/s, {2:0.##}{3}/s", - lastChangeOverTime, - string.IsNullOrEmpty(UnitName) ? "" : string.Format(" {0}", UnitName), + ", {0:0.##}{1}/s, {2:0.##}{3}/s", + lastChangeOverTime, + string.IsNullOrEmpty(UnitName) ? "" : string.Format(" {0}", UnitName), averageChangeOverTime, string.IsNullOrEmpty(UnitName) ? "" : string.Format(" {0}", UnitName)); } } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/Monitoring/StatsLogger.cs b/OpenSim/Framework/Monitoring/StatsLogger.cs index 15a37aa..b719af9 100644 --- a/OpenSim/Framework/Monitoring/StatsLogger.cs +++ b/OpenSim/Framework/Monitoring/StatsLogger.cs @@ -99,13 +99,13 @@ namespace OpenSim.Framework.Monitoring } string path = cmd[2]; - + using (StreamWriter sw = new StreamWriter(path, true)) { foreach (string line in GetReport()) sw.WriteLine(line); - } - + } + MainConsole.Instance.OutputFormat("Stats saved to file {0}", path); } diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index 3136ee8..a6b341f 100644 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs @@ -47,6 +47,8 @@ namespace OpenSim.Framework.Monitoring // Subcommand used to list other stats. public const string ListSubCommand = "list"; + public static string StatsPassword { get; set; } + // All subcommands public static HashSet SubCommands = new HashSet { AllSubCommand, ListSubCommand }; @@ -80,8 +82,7 @@ namespace OpenSim.Framework.Monitoring + "'all' will show all statistics.\n" + "A name will show statistics from that category.\n" + "A . name will show statistics from that category in that container.\n" - + "More than one name can be given separated by spaces.\n" - + "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS", + + "More than one name can be given separated by spaces.\n", HandleShowStatsCommand); console.Commands.AddCommand( @@ -91,7 +92,6 @@ namespace OpenSim.Framework.Monitoring "show stats [list|all|([.])+", "Alias for 'stats show' command", HandleShowStatsCommand); - StatsLogger.RegisterConsoleCommands(console); } @@ -262,33 +262,36 @@ namespace OpenSim.Framework.Monitoring { OSDMap map = new OSDMap(); - foreach (string catName in RegisteredStats.Keys) + lock (RegisteredStats) { - // Do this category if null spec, "all" subcommand or category name matches passed parameter. - // Skip category if none of the above. - if (!(String.IsNullOrEmpty(pCategoryName) || pCategoryName == AllSubCommand || pCategoryName == catName)) - continue; - - OSDMap contMap = new OSDMap(); - foreach (string contName in RegisteredStats[catName].Keys) + foreach (string catName in RegisteredStats.Keys) { - if (!(string.IsNullOrEmpty(pContainerName) || pContainerName == AllSubCommand || pContainerName == contName)) + // Do this category if null spec, "all" subcommand or category name matches passed parameter. + // Skip category if none of the above. + if (!(String.IsNullOrEmpty(pCategoryName) || pCategoryName == AllSubCommand || pCategoryName == catName)) continue; - - OSDMap statMap = new OSDMap(); - SortedDictionary theStats = RegisteredStats[catName][contName]; - foreach (string statName in theStats.Keys) + OSDMap contMap = new OSDMap(); + foreach (string contName in RegisteredStats[catName].Keys) { - if (!(String.IsNullOrEmpty(pStatName) || pStatName == AllSubCommand || pStatName == statName)) + if (!(string.IsNullOrEmpty(pContainerName) || pContainerName == AllSubCommand || pContainerName == contName)) continue; - statMap.Add(statName, theStats[statName].ToOSDMap()); - } + OSDMap statMap = new OSDMap(); + + SortedDictionary theStats = RegisteredStats[catName][contName]; + foreach (string statName in theStats.Keys) + { + if (!(String.IsNullOrEmpty(pStatName) || pStatName == AllSubCommand || pStatName == statName)) + continue; + + statMap.Add(statName, theStats[statName].ToBriefOSDMap()); + } - contMap.Add(contName, statMap); + contMap.Add(contName, statMap); + } + map.Add(catName, contMap); } - map.Add(catName, contMap); } return map; @@ -301,6 +304,17 @@ namespace OpenSim.Framework.Monitoring int response_code = 200; string contenttype = "text/json"; + if (StatsPassword != String.Empty && (!request.ContainsKey("pass") || request["pass"].ToString() != StatsPassword)) + { + responsedata["int_response_code"] = response_code; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Access denied"; + responsedata["access_control_allow_origin"] = "*"; + + return responsedata; + } + string pCategoryName = StatsManager.AllSubCommand; string pContainerName = StatsManager.AllSubCommand; string pStatName = StatsManager.AllSubCommand; @@ -358,8 +372,8 @@ namespace OpenSim.Framework.Monitoring /// public static bool RegisterStat(Stat stat) { - SortedDictionary> category = null, newCategory; - SortedDictionary container = null, newContainer; + SortedDictionary> category = null; + SortedDictionary container = null; lock (RegisteredStats) { @@ -369,22 +383,15 @@ namespace OpenSim.Framework.Monitoring if (TryGetStatParents(stat, out category, out container)) return false; - // We take a copy-on-write approach here of replacing dictionaries when keys are added or removed. - // This means that we don't need to lock or copy them on iteration, which will be a much more - // common operation after startup. - if (container != null) - newContainer = new SortedDictionary(container); - else - newContainer = new SortedDictionary(); + if (container == null) + container = new SortedDictionary(); - if (category != null) - newCategory = new SortedDictionary>(category); - else - newCategory = new SortedDictionary>(); + if (category == null) + category = new SortedDictionary>(); - newContainer[stat.ShortName] = stat; - newCategory[stat.Container] = newContainer; - RegisteredStats[stat.Category] = newCategory; + container[stat.ShortName] = stat; + category[stat.Container] = container; + RegisteredStats[stat.Category] = category; } return true; @@ -397,23 +404,24 @@ namespace OpenSim.Framework.Monitoring /// public static bool DeregisterStat(Stat stat) { - SortedDictionary> category = null, newCategory; - SortedDictionary container = null, newContainer; + SortedDictionary> category = null; + SortedDictionary container = null; lock (RegisteredStats) { if (!TryGetStatParents(stat, out category, out container)) return false; - newContainer = new SortedDictionary(container); - newContainer.Remove(stat.ShortName); - - newCategory = new SortedDictionary>(category); - newCategory.Remove(stat.Container); - - newCategory[stat.Container] = newContainer; - RegisteredStats[stat.Category] = newCategory; - + if(container != null) + { + container.Remove(stat.ShortName); + if(category != null && container.Count == 0) + { + category.Remove(stat.Container); + if(category.Count == 0) + RegisteredStats.Remove(stat.Category); + } + } return true; } } @@ -554,4 +562,4 @@ namespace OpenSim.Framework.Monitoring Debug, Info } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/Monitoring/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs index a644fa5..9cac451 100644 --- a/OpenSim/Framework/Monitoring/Watchdog.cs +++ b/OpenSim/Framework/Monitoring/Watchdog.cs @@ -96,7 +96,7 @@ namespace OpenSim.Framework.Monitoring FirstTick = Environment.TickCount & Int32.MaxValue; LastTick = FirstTick; - Stat + Stat = new Stat( name, string.Format("Last update of thread {0}", name), @@ -180,6 +180,30 @@ namespace OpenSim.Framework.Monitoring m_watchdogTimer.Elapsed += WatchdogTimerElapsed; } + public static void Stop() + { + if(m_threads == null) + return; + + lock(m_threads) + { + m_enabled = false; + if(m_watchdogTimer != null) + { + m_watchdogTimer.Dispose(); + m_watchdogTimer = null; + } + + foreach(ThreadWatchdogInfo twi in m_threads.Values) + { + Thread t = twi.Thread; + if(t.IsAlive) + t.Abort(); + } + m_threads.Clear(); + } + } + /// /// Add a thread to the watchdog tracker. /// @@ -230,14 +254,12 @@ namespace OpenSim.Framework.Monitoring twi.Cleanup(); m_threads.Remove(threadID); - return true; } else { m_log.WarnFormat( "[WATCHDOG]: Requested to remove thread with ID {0} but this is not being monitored", threadID); - return false; } } @@ -317,6 +339,8 @@ namespace OpenSim.Framework.Monitoring /// private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) { + if(!m_enabled) + return; int now = Environment.TickCount & Int32.MaxValue; int msElapsed = now - LastWatchdogThreadTick; @@ -332,27 +356,36 @@ namespace OpenSim.Framework.Monitoring if (callback != null) { List callbackInfos = null; + List threadsToRemove = null; + + const ThreadState thgone = ThreadState.Stopped; lock (m_threads) { - foreach (ThreadWatchdogInfo threadInfo in m_threads.Values) + foreach(ThreadWatchdogInfo threadInfo in m_threads.Values) { - if (threadInfo.Thread.ThreadState == ThreadState.Stopped) + if(!m_enabled) + return; + if((threadInfo.Thread.ThreadState & thgone) != 0) { - RemoveThread(threadInfo.Thread.ManagedThreadId); + if(threadsToRemove == null) + threadsToRemove = new List(); - if (callbackInfos == null) + threadsToRemove.Add(threadInfo); +/* + if(callbackInfos == null) callbackInfos = new List(); callbackInfos.Add(threadInfo); +*/ } - else if (!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout) + else if(!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout) { threadInfo.IsTimedOut = true; - if (threadInfo.AlarmIfTimeout) + if(threadInfo.AlarmIfTimeout) { - if (callbackInfos == null) + if(callbackInfos == null) callbackInfos = new List(); // Send a copy of the watchdog info to prevent race conditions where the watchdog @@ -361,9 +394,13 @@ namespace OpenSim.Framework.Monitoring } } } + + if(threadsToRemove != null) + foreach(ThreadWatchdogInfo twi in threadsToRemove) + RemoveThread(twi.Thread.ManagedThreadId); } - if (callbackInfos != null) + if(callbackInfos != null) foreach (ThreadWatchdogInfo callbackInfo in callbackInfos) callback(callbackInfo); } @@ -377,4 +414,4 @@ namespace OpenSim.Framework.Monitoring m_watchdogTimer.Start(); } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/Monitoring/WorkManager.cs b/OpenSim/Framework/Monitoring/WorkManager.cs index d1a74ce..5d9b185 100644 --- a/OpenSim/Framework/Monitoring/WorkManager.cs +++ b/OpenSim/Framework/Monitoring/WorkManager.cs @@ -36,16 +36,16 @@ namespace OpenSim.Framework.Monitoring /// Manages various work items in the simulator. /// /// - /// Currently, here work can be started + /// Currently, here work can be started /// * As a long-running and monitored thread. /// * In a thread that will never timeout but where the job is expected to eventually complete. /// * In a threadpool thread that will timeout if it takes a very long time to complete (> 10 mins). /// * As a job which will be run in a single-threaded job engine. Such jobs must not incorporate delays (sleeps, /// network waits, etc.). - /// + /// /// This is an evolving approach to better manage the work that OpenSimulator is asked to do from a very diverse /// range of sources (client actions, incoming network, outgoing network calls, etc.). - /// + /// /// Util.FireAndForget is still available to insert jobs in the threadpool, though this is equivalent to /// WorkManager.RunInThreadPool(). /// @@ -57,7 +57,7 @@ namespace OpenSim.Framework.Monitoring static WorkManager() { - JobEngine = new JobEngine("Non-blocking non-critical job engine", "JOB ENGINE"); + JobEngine = new JobEngine("Non-blocking non-critical job engine", "JOB ENGINE", 30000); StatsManager.RegisterStat( new Stat( @@ -82,6 +82,12 @@ namespace OpenSim.Framework.Monitoring HandleControlCommand); } + public static void Stop() + { + JobEngine.Stop(); + Watchdog.Stop(); + } + /// /// Start a new long-lived thread. /// @@ -121,6 +127,7 @@ namespace OpenSim.Framework.Monitoring Thread thread = new Thread(start); thread.Priority = priority; thread.IsBackground = isBackground; + thread.Name = name; Watchdog.ThreadWatchdogInfo twi = new Watchdog.ThreadWatchdogInfo(thread, timeout, name) @@ -129,7 +136,6 @@ namespace OpenSim.Framework.Monitoring Watchdog.AddThread(twi, name, log:log); thread.Start(); - thread.Name = name; return thread; } @@ -143,7 +149,7 @@ namespace OpenSim.Framework.Monitoring /// Name of the thread public static void RunInThread(WaitCallback callback, object obj, string name, bool log = false) { - if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest) + if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest) { Culture.SetCurrentCulture(); callback(obj); @@ -168,7 +174,7 @@ namespace OpenSim.Framework.Monitoring } /// - /// Run the callback via a threadpool thread. + /// Run the callback via a threadpool thread. /// /// /// Such jobs may run after some delay but must always complete. @@ -176,9 +182,9 @@ namespace OpenSim.Framework.Monitoring /// /// /// The name of the job. This is used in monitoring and debugging. - public static void RunInThreadPool(System.Threading.WaitCallback callback, object obj, string name) + public static void RunInThreadPool(System.Threading.WaitCallback callback, object obj, string name, bool timeout = true) { - Util.FireAndForget(callback, obj, name); + Util.FireAndForget(callback, obj, name, timeout); } /// @@ -187,17 +193,17 @@ namespace OpenSim.Framework.Monitoring /// /// This differs from direct scheduling (e.g. Util.FireAndForget) in that a job can be run in the job /// engine if it is running, where all jobs are currently performed in sequence on a single thread. This is - /// to prevent observed overload and server freeze problems when there are hundreds of connections which all attempt to + /// to prevent observed overload and server freeze problems when there are hundreds of connections which all attempt to /// perform work at once (e.g. in conference situations). With lower numbers of connections, the small - /// delay in performing jobs in sequence rather than concurrently has not been notiecable in testing, though a future more + /// delay in performing jobs in sequence rather than concurrently has not been notiecable in testing, though a future more /// sophisticated implementation could perform jobs concurrently when the server is under low load. - /// + /// /// However, be advised that some callers of this function rely on all jobs being performed in sequence if any /// jobs are performed in sequence (i.e. if jobengine is active or not). Therefore, expanding the jobengine /// beyond a single thread will require considerable thought. - /// + /// /// Also, any jobs submitted must be guaranteed to complete within a reasonable timeframe (e.g. they cannot - /// incorporate a network delay with a long timeout). At the moment, work that could suffer such issues + /// incorporate a network delay with a long timeout). At the moment, work that could suffer such issues /// should still be run directly with RunInThread(), Util.FireAndForget(), etc. This is another area where /// the job engine could be improved and so CPU utilization improved by better management of concurrency within /// OpenSimulator. @@ -211,10 +217,10 @@ namespace OpenSim.Framework.Monitoring /// If set to true then extra logging is performed. public static void RunJob( string jobType, WaitCallback callback, object obj, string name, - bool canRunInThisThread = false, bool mustNotTimeout = false, + bool canRunInThisThread = false, bool mustNotTimeout = false, bool log = false) { - if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest) + if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest) { Culture.SetCurrentCulture(); callback(obj); @@ -225,10 +231,8 @@ namespace OpenSim.Framework.Monitoring JobEngine.QueueJob(name, () => callback(obj)); else if (canRunInThisThread) callback(obj); - else if (mustNotTimeout) - RunInThread(callback, obj, name, log); else - Util.FireAndForget(callback, obj, name); + Util.FireAndForget(callback, obj, name, !mustNotTimeout); } private static void HandleControlCommand(string module, string[] args) @@ -272,16 +276,16 @@ namespace OpenSim.Framework.Monitoring MainConsole.Instance.Output("Usage: debug jobengine log "); return; } - + // int logLevel; int logLevel = int.Parse(args[3]); // if (ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out logLevel)) - // { + // { JobEngine.LogLevel = logLevel; MainConsole.Instance.OutputFormat("Set debug log level to {0}", JobEngine.LogLevel); // } } - else + else { MainConsole.Instance.OutputFormat("Unrecognized job engine subcommand {0}", subCommand); } diff --git a/OpenSim/Framework/MuteData.cs b/OpenSim/Framework/MuteData.cs new file mode 100644 index 0000000..7c946d6 --- /dev/null +++ b/OpenSim/Framework/MuteData.cs @@ -0,0 +1,41 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenMetaverse; + +namespace OpenSim.Framework +{ + public class MuteData + { + public UUID AgentID; + public UUID MuteID; + public string MuteName; + public int MuteType; + public int MuteFlags; + public int Stamp; + } +} diff --git a/OpenSim/Framework/NetworkServersInfo.cs b/OpenSim/Framework/NetworkServersInfo.cs index 4b7d4c7..dfe9695 100644 --- a/OpenSim/Framework/NetworkServersInfo.cs +++ b/OpenSim/Framework/NetworkServersInfo.cs @@ -41,6 +41,7 @@ namespace OpenSim.Framework // "Out of band" managemnt https public bool ssl_listener = false; + public bool ssl_external = false; public uint https_port = 0; public string cert_path = String.Empty; public string cert_pass = String.Empty; @@ -64,6 +65,7 @@ namespace OpenSim.Framework // "Out of band management https" ssl_listener = config.Configs["Network"].GetBoolean("https_listener",false); + ssl_external = config.Configs["Network"].GetBoolean("https_external",false); if( ssl_listener) { cert_path = config.Configs["Network"].GetString("cert_path",String.Empty); diff --git a/OpenSim/Framework/NetworkUtil.cs b/OpenSim/Framework/NetworkUtil.cs index 2e94b0d..93c9446 100644 --- a/OpenSim/Framework/NetworkUtil.cs +++ b/OpenSim/Framework/NetworkUtil.cs @@ -40,7 +40,7 @@ namespace OpenSim.Framework /// Handles NAT translation in a 'manner of speaking' /// Allows you to return multiple different external /// hostnames depending on the requestors network - /// + /// /// This enables standard port forwarding techniques /// to work correctly with OpenSim. /// @@ -145,7 +145,7 @@ namespace OpenSim.Framework byte[] subnetBytes = subnet.Value.GetAddressBytes(); byte[] localBytes = subnet.Key.GetAddressBytes(); byte[] destBytes = destination.GetAddressBytes(); - + if (subnetBytes.Length != destBytes.Length || subnetBytes.Length != localBytes.Length) return null; diff --git a/OpenSim/Framework/OSChatMessage.cs b/OpenSim/Framework/OSChatMessage.cs index 455756d..7450be2 100644 --- a/OpenSim/Framework/OSChatMessage.cs +++ b/OpenSim/Framework/OSChatMessage.cs @@ -51,12 +51,11 @@ namespace OpenSim.Framework protected object m_senderObject; protected ChatTypeEnum m_type; protected UUID m_fromID; - protected UUID m_toID; + protected UUID m_destination = UUID.Zero; public OSChatMessage() { m_position = new Vector3(); - m_toID = UUID.Zero; } /// @@ -104,15 +103,6 @@ namespace OpenSim.Framework set { m_from = value; } } - /// - /// The name of the sender (needed for scripts) - /// - public string To - { - get { return m_from; } - set { m_from = value; } - } - #region IEventArgs Members /// TODO: Sender and SenderObject should just be Sender and of @@ -142,13 +132,10 @@ namespace OpenSim.Framework set { m_fromID = value; } } - /// - /// The single recipient or all if not set. - /// - public UUID TargetUUID + public UUID Destination { - get { return m_toID; } - set { m_toID = value; } + get { return m_destination; } + set { m_destination = value; } } /// diff --git a/OpenSim/Framework/ObjectChangeData.cs b/OpenSim/Framework/ObjectChangeData.cs new file mode 100644 index 0000000..8d56291 --- /dev/null +++ b/OpenSim/Framework/ObjectChangeData.cs @@ -0,0 +1,80 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenMetaverse; + +namespace OpenSim.Framework +{ + public enum ObjectChangeType : uint + { + // bits definitions + Position = 0x01, + Rotation = 0x02, + Scale = 0x04, + Group = 0x08, + UniformScale = 0x10, + + // macros from above + // single prim + primP = 0x01, + primR = 0x02, + primPR = 0x03, + primS = 0x04, + primPS = 0x05, + primRS = 0x06, + primPSR = 0x07, + + primUS = 0x14, + primPUS = 0x15, + primRUS = 0x16, + primPUSR = 0x17, + + // group + groupP = 0x09, + groupR = 0x0A, + groupPR = 0x0B, + groupS = 0x0C, + groupPS = 0x0D, + groupRS = 0x0E, + groupPSR = 0x0F, + + groupUS = 0x1C, + groupPUS = 0x1D, + groupRUS = 0x1E, + groupPUSR = 0x1F, + + PRSmask = 0x07 + } + + public struct ObjectChangeData + { + public Quaternion rotation; + public Vector3 position; + public Vector3 scale; + public ObjectChangeType change; + } +} diff --git a/OpenSim/Framework/OutboundUrlFilter.cs b/OpenSim/Framework/OutboundUrlFilter.cs index baa3647..63ae361 100644 --- a/OpenSim/Framework/OutboundUrlFilter.cs +++ b/OpenSim/Framework/OutboundUrlFilter.cs @@ -49,8 +49,8 @@ namespace OpenSim.Framework private List m_blacklistExceptionEndPoints; public OutboundUrlFilter( - string name, - List blacklistNetworks, List blacklistEndPoints, + string name, + List blacklistNetworks, List blacklistEndPoints, List blacklistExceptionNetworks, List blacklistExceptionEndPoints) { Name = name; @@ -79,7 +79,7 @@ namespace OpenSim.Framework if (networkConfig != null) { configBlacklist = networkConfig.GetString("OutboundDisallowForUserScripts", configBlacklist); - configBlacklistExceptions + configBlacklistExceptions = networkConfig.GetString("OutboundDisallowForUserScriptsExcept", configBlacklistExceptions); } @@ -98,7 +98,7 @@ namespace OpenSim.Framework string fullConfigEntry, string filterName, out List networks, out List endPoints) { // Parse blacklist - string[] configBlacklistEntries + string[] configBlacklistEntries = fullConfigEntry.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); configBlacklistEntries = configBlacklistEntries.Select(e => e.Trim()).ToArray(); @@ -129,7 +129,7 @@ namespace OpenSim.Framework if (!Uri.TryCreate("http://" + configEntry, UriKind.Absolute, out configEntryUri)) { m_log.ErrorFormat( - "[OUTBOUND URL FILTER]: EndPoint entry [{0}] is invalid endpoint for {1}", + "[OUTBOUND URL FILTER]: EndPoint entry [{0}] is invalid endpoint for {1}", configEntry, filterName); continue; @@ -184,14 +184,14 @@ namespace OpenSim.Framework foreach (IPEndPoint ep in endPoints) { // m_log.DebugFormat( -// "[OUTBOUND URL FILTER]: Checking [{0}:{1}] against endpoint [{2}]", +// "[OUTBOUND URL FILTER]: Checking [{0}:{1}] against endpoint [{2}]", // addr, port, ep); if (addr.Equals(ep.Address) && port == ep.Port) { // m_log.DebugFormat( // "[OUTBOUND URL FILTER]: Found [{0}:{1}] in endpoint [{2}]", addr, port, ep); - + return true; } } @@ -212,7 +212,17 @@ namespace OpenSim.Framework // Check that we are permitted to make calls to this endpoint. bool foundIpv4Address = false; - IPAddress[] addresses = Dns.GetHostAddresses(url.Host); + IPAddress[] addresses = null; + + try + { + addresses = Dns.GetHostAddresses(url.Host); + } + catch + { + // If there is a DNS error, we can't stop the script! + return true; + } foreach (IPAddress addr in addresses) { @@ -228,7 +238,7 @@ namespace OpenSim.Framework // m_log.DebugFormat("[OUTBOUND URL FILTER]: Found [{0}] in blacklist for {1}", url, Name); // Check blacklist exceptions - allowed + allowed = OutboundUrlFilter.IsInNetwork( addr, url.Port, m_blacklistExceptionNetworks, m_blacklistExceptionEndPoints, Name); @@ -253,4 +263,4 @@ namespace OpenSim.Framework return allowed; } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/ParcelMediaCommandEnum.cs b/OpenSim/Framework/ParcelMediaCommandEnum.cs index 93c41ec..e714382 100644 --- a/OpenSim/Framework/ParcelMediaCommandEnum.cs +++ b/OpenSim/Framework/ParcelMediaCommandEnum.cs @@ -27,7 +27,7 @@ namespace OpenSim.Framework { - public enum ParcelMediaCommandEnum + public enum ParcelMediaCommandEnum : int { Stop = 0, Pause = 1, diff --git a/OpenSim/Framework/PermissionsUtil.cs b/OpenSim/Framework/PermissionsUtil.cs index d785a78..e50d4df 100644 --- a/OpenSim/Framework/PermissionsUtil.cs +++ b/OpenSim/Framework/PermissionsUtil.cs @@ -60,28 +60,57 @@ namespace OpenSim.Framework str += "C"; if ((perms & (int)PermissionMask.Transfer) != 0) str += "T"; + if ((perms & (int)PermissionMask.Export) != 0) + str += "X"; if (str == "") str = "."; return str; } - /// - /// Applies an object's folded permissions to its regular permissions. - /// - /// The folded permissions. Only the lowest 7 bits are examined. - /// The permissions variable to modify. - public static void ApplyFoldedPermissions(uint foldedPerms, ref uint mainPerms) + public static void ApplyFoldedPermissions(uint foldedSourcePerms, ref uint targetPerms) + { + uint folded = foldedSourcePerms & (uint)PermissionMask.FoldedMask; + if(folded == 0 || folded == (uint)PermissionMask.FoldedMask) // invalid we need to ignore, or nothing to do + return; + + folded <<= (int)PermissionMask.FoldingShift; + folded |= ~(uint)PermissionMask.UnfoldedMask; + + uint tmp = targetPerms; + tmp &= folded; + targetPerms = tmp; + } + + // do not touch MOD + public static void ApplyNoModFoldedPermissions(uint foldedSourcePerms, ref uint target) { - if ((foldedPerms & 7) == 0) - return; // assume that if the folded permissions are 0 then this means that they weren't actually recorded + uint folded = foldedSourcePerms & (uint)PermissionMask.FoldedMask; + if(folded == 0 || folded == (uint)PermissionMask.FoldedMask) // invalid we need to ignore, or nothing to do + return; - if ((foldedPerms & ((uint)PermissionMask.Copy >> 13)) == 0) - mainPerms &= ~(uint)PermissionMask.Copy; - if ((foldedPerms & ((uint)PermissionMask.Transfer >> 13)) == 0) - mainPerms &= ~(uint)PermissionMask.Transfer; - if ((foldedPerms & ((uint)PermissionMask.Modify >> 13)) == 0) - mainPerms &= ~(uint)PermissionMask.Modify; + folded <<= (int)PermissionMask.FoldingShift; + folded |= (~(uint)PermissionMask.UnfoldedMask | (uint)PermissionMask.Modify); + + uint tmp = target; + tmp &= folded; + target = tmp; } + public static uint FixAndFoldPermissions(uint perms) + { + uint tmp = perms; + + // C & T rule + if((tmp & (uint)(PermissionMask.Copy | PermissionMask.Transfer)) == 0) + tmp |= (uint)PermissionMask.Transfer; + + // unlock + tmp |= (uint)PermissionMask.Move; + + tmp &= ~(uint)PermissionMask.FoldedMask; + tmp |= ((tmp >> (int)PermissionMask.FoldingShift) & (uint)PermissionMask.FoldedMask); + + return tmp; + } } } diff --git a/OpenSim/Framework/PhysicsInertia.cs b/OpenSim/Framework/PhysicsInertia.cs new file mode 100644 index 0000000..fa83de8 --- /dev/null +++ b/OpenSim/Framework/PhysicsInertia.cs @@ -0,0 +1,263 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using System.Text; +using System.IO; +using System.Xml; + +namespace OpenSim.Framework +{ + public class PhysicsInertiaData + { + public float TotalMass; // the total mass of a linkset + public Vector3 CenterOfMass; // the center of mass position relative to root part position + public Vector3 Inertia; // (Ixx, Iyy, Izz) moment of inertia relative to center of mass and principal axis in local coords + public Vector4 InertiaRotation; // if principal axis don't match local axis, the principal axis rotation + // or the upper triangle of the inertia tensor + // Ixy (= Iyx), Ixz (= Izx), Iyz (= Izy)) + + public PhysicsInertiaData() + { + } + + public PhysicsInertiaData(PhysicsInertiaData source) + { + TotalMass = source.TotalMass; + CenterOfMass = source.CenterOfMass; + Inertia = source.Inertia; + InertiaRotation = source.InertiaRotation; + } + + private XmlTextWriter writer; + + private void XWint(string name, int i) + { + writer.WriteElementString(name, i.ToString()); + } + + private void XWfloat(string name, float f) + { + writer.WriteElementString(name, f.ToString(Culture.FormatProvider)); + } + + private void XWVector(string name, Vector3 vec) + { + writer.WriteStartElement(name); + writer.WriteElementString("X", vec.X.ToString(Culture.FormatProvider)); + writer.WriteElementString("Y", vec.Y.ToString(Culture.FormatProvider)); + writer.WriteElementString("Z", vec.Z.ToString(Culture.FormatProvider)); + writer.WriteEndElement(); + } + + private void XWVector4(string name, Vector4 quat) + { + writer.WriteStartElement(name); + writer.WriteElementString("X", quat.X.ToString(Culture.FormatProvider)); + writer.WriteElementString("Y", quat.Y.ToString(Culture.FormatProvider)); + writer.WriteElementString("Z", quat.Z.ToString(Culture.FormatProvider)); + writer.WriteElementString("W", quat.W.ToString(Culture.FormatProvider)); + writer.WriteEndElement(); + } + + public void ToXml2(XmlTextWriter twriter) + { + writer = twriter; + writer.WriteStartElement("PhysicsInertia"); + + XWfloat("MASS", TotalMass); + XWVector("CM", CenterOfMass); + XWVector("INERTIA", Inertia); + XWVector4("IROT", InertiaRotation); + + writer.WriteEndElement(); + writer = null; + } + + XmlReader reader; + + private int XRint() + { + return reader.ReadElementContentAsInt(); + } + + private float XRfloat() + { + return reader.ReadElementContentAsFloat(); + } + + public Vector3 XRvector() + { + Vector3 vec; + reader.ReadStartElement(); + vec.X = reader.ReadElementContentAsFloat(); + vec.Y = reader.ReadElementContentAsFloat(); + vec.Z = reader.ReadElementContentAsFloat(); + reader.ReadEndElement(); + return vec; + } + + public Vector4 XRVector4() + { + Vector4 q; + reader.ReadStartElement(); + q.X = reader.ReadElementContentAsFloat(); + q.Y = reader.ReadElementContentAsFloat(); + q.Z = reader.ReadElementContentAsFloat(); + q.W = reader.ReadElementContentAsFloat(); + reader.ReadEndElement(); + return q; + } + + public static bool EReadProcessors( + Dictionary processors, + XmlReader xtr) + { + bool errors = false; + + string nodeName = string.Empty; + while (xtr.NodeType != XmlNodeType.EndElement) + { + nodeName = xtr.Name; + + Action p = null; + if (processors.TryGetValue(xtr.Name, out p)) + { + try + { + p(); + } + catch + { + errors = true; + if (xtr.NodeType == XmlNodeType.EndElement) + xtr.Read(); + } + } + else + { + xtr.ReadOuterXml(); // ignore + } + } + + return errors; + } + + public string ToXml2() + { + using (StringWriter sw = new StringWriter()) + { + using (XmlTextWriter xwriter = new XmlTextWriter(sw)) + { + ToXml2(xwriter); + } + + return sw.ToString(); + } + } + + public static PhysicsInertiaData FromXml2(string text) + { + if (text == String.Empty) + return null; + + bool error; + PhysicsInertiaData v; + UTF8Encoding enc = new UTF8Encoding(); + using(MemoryStream ms = new MemoryStream(enc.GetBytes(text))) + using(XmlTextReader xreader = new XmlTextReader(ms)) + { + xreader.ProhibitDtd = true; + + v = new PhysicsInertiaData(); + v.FromXml2(xreader, out error); + } + + if (error) + return null; + + return v; + } + + public static PhysicsInertiaData FromXml2(XmlReader reader) + { + PhysicsInertiaData data = new PhysicsInertiaData(); + + bool errors = false; + + data.FromXml2(reader, out errors); + if (errors) + return null; + + return data; + } + + private void FromXml2(XmlReader _reader, out bool errors) + { + errors = false; + reader = _reader; + + Dictionary m_XmlProcessors = new Dictionary(); + + m_XmlProcessors.Add("MASS", ProcessXR_Mass); + m_XmlProcessors.Add("CM", ProcessXR_CM); + m_XmlProcessors.Add("INERTIA", ProcessXR_Inertia); + m_XmlProcessors.Add("IROT", ProcessXR_InertiaRotation); + + reader.ReadStartElement("PhysicsInertia", String.Empty); + + errors = EReadProcessors( + m_XmlProcessors, + reader); + + reader.ReadEndElement(); + reader = null; + } + + private void ProcessXR_Mass() + { + TotalMass = XRfloat(); + } + + private void ProcessXR_CM() + { + CenterOfMass = XRvector(); + } + + private void ProcessXR_Inertia() + { + Inertia = XRvector(); + } + + private void ProcessXR_InertiaRotation() + { + InertiaRotation = XRVector4(); + } + } +} diff --git a/OpenSim/Framework/PluginLoader.cs b/OpenSim/Framework/PluginLoader.cs index d12aa61..1e5e8bf 100644 --- a/OpenSim/Framework/PluginLoader.cs +++ b/OpenSim/Framework/PluginLoader.cs @@ -245,13 +245,22 @@ namespace OpenSim.Framework // occasionally seems to corrupt its addin cache // Hence, as a temporary solution we'll remove it before each startup + string customDir = Environment.GetEnvironmentVariable ("MONO_ADDINS_REGISTRY"); + string v0 = "addin-db-000"; + string v1 = "addin-db-001"; + if (customDir != null && customDir != String.Empty) + { + v0 = Path.Combine(customDir, v0); + v1 = Path.Combine(customDir, v1); + } try { - if (Directory.Exists(dir + "/addin-db-000")) - Directory.Delete(dir + "/addin-db-000", true); + if (Directory.Exists(v0)) + Directory.Delete(v0, true); + + if (Directory.Exists(v1)) + Directory.Delete(v1, true); - if (Directory.Exists(dir + "/addin-db-001")) - Directory.Delete(dir + "/addin-db-001", true); } catch (IOException) { diff --git a/OpenSim/Framework/PluginManager.cs b/OpenSim/Framework/PluginManager.cs index 0117096..0c94fcb 100644 --- a/OpenSim/Framework/PluginManager.cs +++ b/OpenSim/Framework/PluginManager.cs @@ -44,17 +44,17 @@ namespace OpenSim.Framework /// /// Manager for registries and plugins /// - public class PluginManager : SetupService - { - public AddinRegistry PluginRegistry; + public class PluginManager : SetupService + { + public AddinRegistry PluginRegistry; - public PluginManager(AddinRegistry registry): base (registry) + public PluginManager(AddinRegistry registry): base (registry) { - PluginRegistry = registry; + PluginRegistry = registry; - } + } - /// + /// /// Installs the plugin. /// /// @@ -97,14 +97,14 @@ namespace OpenSim.Framework Addin addin = PluginRegistry.GetAddin(aentry.Addin.Id); PluginRegistry.DisableAddin(addin.Id); addin.Enabled = false; - + MainConsole.Instance.Output("Installation Success"); ListInstalledAddins(out res); result = res; return true; - } + } else - { + { MainConsole.Instance.Output("Installation Failed"); result = res; return false; @@ -159,11 +159,11 @@ namespace OpenSim.Framework { Dictionary res = new Dictionary(); - Addin[] addins = GetSortedAddinList("RobustPlugin"); - if(addins.Count() < 1) - { - MainConsole.Instance.Output("Error!"); - } + Addin[] addins = GetSortedAddinList("RobustPlugin"); + if(addins.Count() < 1) + { + MainConsole.Instance.Output("Error!"); + } int count = 0; foreach (Addin addin in addins) { @@ -377,7 +377,7 @@ namespace OpenSim.Framework r["enabled"] = rep.Enabled == true ? true : false; r["name"] = rep.Name; r["url"] = rep.Url; - + res.Add(count.ToString(), r); count++; } @@ -493,7 +493,7 @@ namespace OpenSim.Framework } - + #region Util private void Testing() { @@ -537,15 +537,15 @@ namespace OpenSim.Framework ArrayList xlist = new ArrayList(); ArrayList list = new ArrayList(); - try - { - list.AddRange(PluginRegistry.GetAddins()); - } - catch (Exception) - { - Addin[] x = xlist.ToArray(typeof(Addin)) as Addin[]; - return x; - } + try + { + list.AddRange(PluginRegistry.GetAddins()); + } + catch (Exception) + { + Addin[] x = xlist.ToArray(typeof(Addin)) as Addin[]; + return x; + } foreach (Addin addin in list) { @@ -559,5 +559,5 @@ namespace OpenSim.Framework return addins; } #endregion Util - } + } } diff --git a/OpenSim/Framework/PrimeNumberHelper.cs b/OpenSim/Framework/PrimeNumberHelper.cs index 477c274..5a1b3b2 100644 --- a/OpenSim/Framework/PrimeNumberHelper.cs +++ b/OpenSim/Framework/PrimeNumberHelper.cs @@ -35,7 +35,7 @@ namespace OpenSim.Framework public static class PrimeNumberHelper { /// - /// Precalculated prime numbers. + /// Precalculated prime numbers. /// private static readonly int[] Primes = new int[] { diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index c8a5376..6e7a038 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs @@ -238,8 +238,8 @@ namespace OpenSim.Framework SculptTexture = prim.Sculpt.SculptTexture; SculptType = (byte)prim.Sculpt.Type; } - else - { + else + { SculptType = (byte)OpenMetaverse.SculptType.None; } } @@ -328,6 +328,72 @@ namespace OpenSim.Framework return shape; } + public static PrimitiveBaseShape CreateMesh(int numberOfFaces, UUID meshAssetID) + { + PrimitiveBaseShape shape = new PrimitiveBaseShape(); + + shape._pathScaleX = 100; + shape._pathScaleY = 100; + + if(numberOfFaces <= 0) // oops ? + numberOfFaces = 1; + + switch(numberOfFaces) + { + case 1: // torus + shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Curve1; + shape._pathScaleY = 150; + break; + + case 2: // torus with hollow (a sl viewer whould see 4 faces on a hollow sphere) + shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Curve1; + shape.ProfileHollow = 27500; + shape._pathScaleY = 150; + break; + + case 3: // cylinder + shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + break; + + case 4: // cylinder with hollow + shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + shape.ProfileHollow = 27500; + break; + + case 5: // prism + shape.ProfileCurve = (byte)ProfileShape.EquilateralTriangle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + break; + + case 6: // box + shape.ProfileCurve = (byte)ProfileShape.Square | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + break; + + case 7: // box with hollow + shape.ProfileCurve = (byte)ProfileShape.Square | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + shape.ProfileHollow = 27500; + break; + + default: // 8 faces box with cut + shape.ProfileCurve = (byte)ProfileShape.Square | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + shape.ProfileBegin = 9375; + break; + } + + shape.SculptEntry = true; + shape.SculptType = (byte)OpenMetaverse.SculptType.Mesh; + shape.SculptTexture = meshAssetID; + + return shape; + } + public void SetScale(float side) { _scale = new Vector3(side, side, side); @@ -728,7 +794,12 @@ namespace OpenSim.Framework return _lightColorR; } set { - _lightColorR = value; + if (value < 0) + _lightColorR = 0; + else if (value > 1.0f) + _lightColorR = 1.0f; + else + _lightColorR = value; } } @@ -737,7 +808,12 @@ namespace OpenSim.Framework return _lightColorG; } set { - _lightColorG = value; + if (value < 0) + _lightColorG = 0; + else if (value > 1.0f) + _lightColorG = 1.0f; + else + _lightColorG = value; } } @@ -746,7 +822,12 @@ namespace OpenSim.Framework return _lightColorB; } set { - _lightColorB = value; + if (value < 0) + _lightColorB = 0; + else if (value > 1.0f) + _lightColorB = 1.0f; + else + _lightColorB = value; } } @@ -755,7 +836,12 @@ namespace OpenSim.Framework return _lightColorA; } set { - _lightColorA = value; + if (value < 0) + _lightColorA = 0; + else if (value > 1.0f) + _lightColorA = 1.0f; + else + _lightColorA = value; } } @@ -869,6 +955,11 @@ namespace OpenSim.Framework public ulong GetMeshKey(Vector3 size, float lod) { + return GetMeshKey(size, lod, false); + } + + public ulong GetMeshKey(Vector3 size, float lod, bool convex) + { ulong hash = 5381; hash = djb2(hash, this.PathCurve); @@ -914,6 +1005,9 @@ namespace OpenSim.Framework hash = djb2(hash, scaleBytes[i]); } + if(convex) + hash = djb2(hash, 0xa5); + return hash; } @@ -1417,7 +1511,7 @@ namespace OpenSim.Framework prim.Textures = this.Textures; prim.Properties = new Primitive.ObjectProperties(); - prim.Properties.Name = "Primitive"; + prim.Properties.Name = "Object"; prim.Properties.Description = ""; prim.Properties.CreatorID = UUID.Zero; prim.Properties.GroupID = UUID.Zero; @@ -1488,35 +1582,50 @@ namespace OpenSim.Framework { MediaList ml = new MediaList(); ml.ReadXml(rawXml); + if(ml.Count == 0) + return null; return ml; } public void ReadXml(string rawXml) { - using (StringReader sr = new StringReader(rawXml)) + try { - using (XmlTextReader xtr = new XmlTextReader(sr)) + using (StringReader sr = new StringReader(rawXml)) { - xtr.MoveToContent(); + using (XmlTextReader xtr = new XmlTextReader(sr)) + { + xtr.ProhibitDtd = true; - string type = xtr.GetAttribute("type"); - //m_log.DebugFormat("[MOAP]: Loaded media texture entry with type {0}", type); + xtr.MoveToContent(); - if (type != MEDIA_TEXTURE_TYPE) - return; + string type = xtr.GetAttribute("type"); + //m_log.DebugFormat("[MOAP]: Loaded media texture entry with type {0}", type); - xtr.ReadStartElement("OSMedia"); + if (type != MEDIA_TEXTURE_TYPE) + return; - OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml()); - foreach (OSD osdMe in osdMeArray) - { - MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry()); - Add(me); - } + xtr.ReadStartElement("OSMedia"); + OSD osdp = OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml()); + if(osdp == null || !(osdp is OSDArray)) + return; - xtr.ReadEndElement(); + OSDArray osdMeArray = osdp as OSDArray; + if(osdMeArray.Count == 0) + return; + + foreach (OSD osdMe in osdMeArray) + { + MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry()); + Add(me); + } + } } } + catch + { + m_log.Debug("PrimitiveBaseShape] error decoding MOAP xml" ); + } } public void ReadXml(XmlReader reader) diff --git a/OpenSim/Framework/PriorityQueue.cs b/OpenSim/Framework/PriorityQueue.cs index e7a7f7f..22ffcdc 100644 --- a/OpenSim/Framework/PriorityQueue.cs +++ b/OpenSim/Framework/PriorityQueue.cs @@ -45,7 +45,8 @@ namespace OpenSim.Framework /// /// Total number of queues (priorities) available /// - public const uint NumberOfQueues = 12; + + public const uint NumberOfQueues = 12; // includes immediate queues, m_queueCounts need to be set acording /// /// Number of queuest (priorities) that are processed immediately @@ -56,11 +57,14 @@ namespace OpenSim.Framework private Dictionary m_lookupTable; // internal state used to ensure the deqeues are spread across the priority - // queues "fairly". queuecounts is the amount to pull from each queue in + // queues "fairly". queuecounts is the amount to pull from each queue in // each pass. weighted towards the higher priority queues private uint m_nextQueue = 0; private uint m_countFromQueue = 0; - private uint[] m_queueCounts = { 8, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1 }; + // first queues are imediate, so no counts +// private uint[] m_queueCounts = { 0, 0, 8, 4, 4, 2, 2, 2, 2, 1, 1, 1 }; + private uint[] m_queueCounts = {0, 0, 8, 8, 5, 4, 3, 2, 1, 1, 1, 1}; + // this is ava, ava, attach, <10m, 20,40,80,160m,320,640,1280, + // next request is a counter of the number of updates queued, it provides // a total ordering on the updates coming through the queue and is more @@ -101,7 +105,7 @@ namespace OpenSim.Framework int count = 0; for (int i = 0; i < m_heaps.Length; ++i) count += m_heaps[i].Count; - + return count; } } @@ -109,7 +113,7 @@ namespace OpenSim.Framework /// /// Enqueue an item into the specified priority queue /// - public bool Enqueue(uint pqueue, IEntityUpdate value) + public bool Enqueue(uint pqueue, EntityUpdate value) { LookupItem lookup; @@ -130,14 +134,29 @@ namespace OpenSim.Framework return true; } + + public void Remove(List ids) + { + LookupItem lookup; + + foreach (uint localid in ids) + { + if (m_lookupTable.TryGetValue(localid, out lookup)) + { + lookup.Heap.Remove(lookup.Handle); + m_lookupTable.Remove(localid); + } + } + } + /// /// Remove an item from one of the queues. Specifically, it removes the /// oldest item from the next queue in order to provide fair access to /// all of the queues /// - public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue) + public bool TryDequeue(out EntityUpdate value, out Int32 timeinqueue) { - // If there is anything in priority queue 0, return it first no + // If there is anything in imediate queues, return it first no // matter what else. Breaks fairness. But very useful. for (int iq = 0; iq < NumberOfImmediateQueues; iq++) { @@ -151,36 +170,35 @@ namespace OpenSim.Framework return true; } } - + // To get the fair queing, we cycle through each of the - // queues when finding an element to dequeue. + // queues when finding an element to dequeue. // We pull (NumberOfQueues - QueueIndex) items from each queue in order // to give lower numbered queues a higher priority and higher percentage - // of the bandwidth. - + // of the bandwidth. + // Check for more items to be pulled from the current queue if (m_heaps[m_nextQueue].Count > 0 && m_countFromQueue > 0) { m_countFromQueue--; - + MinHeapItem item = m_heaps[m_nextQueue].RemoveMin(); m_lookupTable.Remove(item.Value.Entity.LocalId); timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); value = item.Value; - + return true; } - + // Find the next non-immediate queue with updates in it - for (int i = 0; i < NumberOfQueues; ++i) + for (uint i = NumberOfImmediateQueues; i < NumberOfQueues; ++i) { - m_nextQueue = (uint)((m_nextQueue + 1) % NumberOfQueues); + m_nextQueue++; + if(m_nextQueue >= NumberOfQueues) + m_nextQueue = NumberOfImmediateQueues; + m_countFromQueue = m_queueCounts[m_nextQueue]; - // if this is one of the immediate queues, just skip it - if (m_nextQueue < NumberOfImmediateQueues) - continue; - if (m_heaps[m_nextQueue].Count > 0) { m_countFromQueue--; @@ -189,19 +207,39 @@ namespace OpenSim.Framework m_lookupTable.Remove(item.Value.Entity.LocalId); timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); value = item.Value; + return true; + } + } + timeinqueue = 0; + value = default(EntityUpdate); + return false; + } + + public bool TryOrderedDequeue(out EntityUpdate value, out Int32 timeinqueue) + { + // If there is anything in imediate queues, return it first no + // matter what else. Breaks fairness. But very useful. + for (int iq = 0; iq < NumberOfQueues; iq++) + { + if (m_heaps[iq].Count > 0) + { + MinHeapItem item = m_heaps[iq].RemoveMin(); + m_lookupTable.Remove(item.Value.Entity.LocalId); + timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); + value = item.Value; return true; } } timeinqueue = 0; - value = default(IEntityUpdate); + value = default(EntityUpdate); return false; } /// /// Reapply the prioritization function to each of the updates currently - /// stored in the priority queues. + /// stored in the priority queues. /// { - private IEntityUpdate value; - internal IEntityUpdate Value { + private EntityUpdate value; + internal EntityUpdate Value { get { return this.value; } @@ -290,7 +328,7 @@ namespace OpenSim.Framework this.pqueue = pqueue; } - internal MinHeapItem(uint pqueue, UInt64 entryorder, IEntityUpdate value) + internal MinHeapItem(uint pqueue, UInt64 entryorder, EntityUpdate value) { this.entrytime = Util.EnvironmentTickCount(); this.entryorder = entryorder; diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index 79fbd96..75ed999 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -40,6 +40,7 @@ using OpenMetaverse.StructuredData; namespace OpenSim.Framework { + [Serializable] public class RegionLightShareData : ICloneable { public bool valid = false; @@ -101,6 +102,11 @@ namespace OpenSim.Framework private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly string LogHeader = "[REGION INFO]"; + + public bool commFailTF = false; + public ConfigurationMember configMember; + public string DataStore = String.Empty; + public string RegionFile = String.Empty; public bool isSandbox = false; public bool Persistent = true; @@ -124,7 +130,7 @@ namespace OpenSim.Framework private float m_physPrimMin = 0; private int m_physPrimMax = 0; private bool m_clampPrimSize = false; - private int m_objectCapacity = 0; + private int m_objectCapacity = 15000; private int m_maxPrimsPerUser = -1; private int m_linksetCapacity = 0; private string m_regionType = String.Empty; @@ -132,8 +138,6 @@ namespace OpenSim.Framework protected uint m_httpPort; protected string m_serverURI; protected string m_regionName = String.Empty; - protected bool Allow_Alternate_Ports; - public bool m_allow_alternate_ports; protected string m_externalHostName; protected IPEndPoint m_internalEndPoint; protected uint m_remotingPort; @@ -141,6 +145,7 @@ namespace OpenSim.Framework public string RemotingAddress; public UUID ScopeID = UUID.Zero; private UUID m_maptileStaticUUID = UUID.Zero; + private bool m_resolveAddress = false; public uint WorldLocX = 0; public uint WorldLocY = 0; @@ -170,6 +175,9 @@ namespace OpenSim.Framework /// public uint RegionSizeZ = Constants.RegionHeight; + // If entering avatar has no specific coords, this is where they land + public Vector3 DefaultLandingPoint = new Vector3(128, 128, 30); + private Dictionary m_extraSettings = new Dictionary(); // Apparently, we're applying the same estatesettings regardless of whether it's local or remote. @@ -368,7 +376,7 @@ namespace OpenSim.Framework } public string MaptileStaticFile { get; private set; } - + /// /// The port by which http communication occurs with the region (most noticeably, CAPS communication) /// @@ -381,17 +389,17 @@ namespace OpenSim.Framework /// /// A well-formed URI for the host region server (namely "http://" + ExternalHostName) /// - + public string ServerURI { - get { + get { if ( m_serverURI != string.Empty ) { return m_serverURI; } else { return "http://" + m_externalHostName + ":" + m_httpPort + "/"; } - } - set { + } + set { if ( value.EndsWith("/") ) { m_serverURI = value; } else { @@ -412,6 +420,7 @@ namespace OpenSim.Framework set { m_remotingPort = value; } } + /// /// This accessor can throw all the exceptions that Dns.GetHostAddresses can throw. /// @@ -419,42 +428,7 @@ namespace OpenSim.Framework /// public IPEndPoint ExternalEndPoint { - get - { - // Old one defaults to IPv6 - //return new IPEndPoint(Dns.GetHostAddresses(m_externalHostName)[0], m_internalEndPoint.Port); - - IPAddress ia = null; - // If it is already an IP, don't resolve it - just return directly - if (IPAddress.TryParse(m_externalHostName, out ia)) - return new IPEndPoint(ia, m_internalEndPoint.Port); - - // Reset for next check - ia = null; - try - { - foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName)) - { - if (ia == null) - ia = Adr; - - if (Adr.AddressFamily == AddressFamily.InterNetwork) - { - ia = Adr; - break; - } - } - } - catch (SocketException e) - { - throw new Exception( - "Unable to resolve local hostname " + m_externalHostName + " innerException of type '" + - e + "' attached to this exception", e); - } - - return new IPEndPoint(ia, m_internalEndPoint.Port); - } - + get { return Util.getEndPoint(m_externalHostName, m_internalEndPoint.Port); } set { m_externalHostName = value.ToString(); } } @@ -527,7 +501,7 @@ namespace OpenSim.Framework return null; } - private void SetExtraSetting(string key, string value) + public void SetExtraSetting(string key, string value) { string keylower = key.ToLower(); m_extraSettings[keylower] = value; @@ -535,7 +509,7 @@ namespace OpenSim.Framework private void ReadNiniConfig(IConfigSource source, string name) { -// bool creatingNew = false; + bool creatingNew = false; if (source.Configs.Count == 0) { @@ -559,7 +533,7 @@ namespace OpenSim.Framework source.AddConfig(name); -// creatingNew = true; + creatingNew = true; } if (name == String.Empty) @@ -663,18 +637,19 @@ namespace OpenSim.Framework } m_internalEndPoint = new IPEndPoint(address, port); - // AllowAlternatePorts + // ResolveAddress // - allKeys.Remove("AllowAlternatePorts"); - if (config.Contains("AllowAlternatePorts")) + allKeys.Remove("ResolveAddress"); + if (config.Contains("ResolveAddress")) { - m_allow_alternate_ports = config.GetBoolean("AllowAlternatePorts", true); + m_resolveAddress = config.GetBoolean("ResolveAddress", false); } else { - m_allow_alternate_ports = Convert.ToBoolean(MainConsole.Instance.CmdPrompt("Allow alternate ports", "False")); + if (creatingNew) + m_resolveAddress = Convert.ToBoolean(MainConsole.Instance.CmdPrompt("Resolve hostname to IP on start (for running inside Docker)", "False")); - config.Set("AllowAlternatePorts", m_allow_alternate_ports.ToString()); + config.Set("ResolveAddress", m_resolveAddress.ToString()); } // ExternalHostName @@ -697,15 +672,36 @@ namespace OpenSim.Framework "[REGIONINFO]: Resolving SYSTEMIP to {0} for external hostname of region {1}", m_externalHostName, name); } - else + else if (!m_resolveAddress) { m_externalHostName = externalName; } + else + { + IPAddress[] addrs = Dns.GetHostAddresses(externalName); + if (addrs.Length != 1) // If it is ambiguous or not resolveable, use it literally + m_externalHostName = externalName; + else + m_externalHostName = addrs[0].ToString(); + } // RegionType m_regionType = config.GetString("RegionType", String.Empty); allKeys.Remove("RegionType"); + // Get Default Landing Location (Defaults to 128,128) + string temp_location = config.GetString("DefaultLanding", "<128, 128, 30>"); + Vector3 temp_vector; + + if (Vector3.TryParse(temp_location, out temp_vector)) + DefaultLandingPoint = temp_vector; + else + m_log.ErrorFormat("[RegionInfo]: Unable to parse DefaultLanding for '{0}'. The value given was '{1}'", RegionName, temp_location); + + allKeys.Remove("DefaultLanding"); + + DoDefaultLandingSanityChecks(); + #region Prim and map stuff m_nonphysPrimMin = config.GetFloat("NonPhysicalPrimMin", 0); @@ -719,11 +715,11 @@ namespace OpenSim.Framework m_physPrimMax = config.GetInt("PhysicalPrimMax", 0); allKeys.Remove("PhysicalPrimMax"); - + m_clampPrimSize = config.GetBoolean("ClampPrimSize", false); allKeys.Remove("ClampPrimSize"); - - m_objectCapacity = config.GetInt("MaxPrims", 15000); + + m_objectCapacity = config.GetInt("MaxPrims", m_objectCapacity); allKeys.Remove("MaxPrims"); m_maxPrimsPerUser = config.GetInt("MaxPrimsPerUser", -1); @@ -736,12 +732,12 @@ namespace OpenSim.Framework string mapTileStaticUUID = config.GetString("MaptileStaticUUID", UUID.Zero.ToString()); if (UUID.TryParse(mapTileStaticUUID.Trim(), out m_maptileStaticUUID)) { - config.Set("MaptileStaticUUID", m_maptileStaticUUID.ToString()); + config.Set("MaptileStaticUUID", m_maptileStaticUUID.ToString()); } MaptileStaticFile = config.GetString("MaptileStaticFile", String.Empty); allKeys.Remove("MaptileStaticFile"); - + #endregion AgentCapacity = config.GetInt("MaxAgents", 100); @@ -758,6 +754,48 @@ namespace OpenSim.Framework } } + // Make sure DefaultLanding is within region borders with a buffer zone 5 meters from borders + private void DoDefaultLandingSanityChecks() + { + // Sanity Check Default Landing + float buffer_zone = 5f; + + bool ValuesCapped = false; + + // Minimum Positions + if (DefaultLandingPoint.X < buffer_zone) + { + DefaultLandingPoint.X = buffer_zone; + ValuesCapped = true; + } + + if (DefaultLandingPoint.Y < buffer_zone) + { + DefaultLandingPoint.Y = buffer_zone; + ValuesCapped = true; + } + + // Maximum Positions + if (DefaultLandingPoint.X > RegionSizeX - buffer_zone) + { + DefaultLandingPoint.X = RegionSizeX - buffer_zone; + ValuesCapped = true; + } + + if (DefaultLandingPoint.Y > RegionSizeY - buffer_zone) + { + DefaultLandingPoint.Y = RegionSizeY - buffer_zone; + ValuesCapped = true; + } + + // Height + if (DefaultLandingPoint.Z < 0f) + DefaultLandingPoint.Z = 0f; + + if (ValuesCapped == true) + m_log.WarnFormat("[RegionInfo]: The default landing location for {0} has been capped to {1}", RegionName, DefaultLandingPoint); + } + // Make sure user specified region sizes are sane. // Must be multiples of legacy region size (256). private void DoRegionSizeSanityChecks() @@ -823,20 +861,20 @@ namespace OpenSim.Framework string location = String.Format("{0},{1}", RegionLocX, RegionLocY); config.Set("Location", location); - if (RegionSizeX > 0) - config.Set("SizeX", RegionSizeX); + if (DataStore != String.Empty) + config.Set("Datastore", DataStore); - if (RegionSizeY > 0) + if (RegionSizeX != Constants.RegionSize || RegionSizeY != Constants.RegionSize) + { + config.Set("SizeX", RegionSizeX); config.Set("SizeY", RegionSizeY); - -// if (RegionSizeZ > 0) -// config.Set("SizeZ", RegionSizeZ); + // if (RegionSizeZ > 0) + // config.Set("SizeZ", RegionSizeZ); + } config.Set("InternalAddress", m_internalEndPoint.Address.ToString()); config.Set("InternalPort", m_internalEndPoint.Port); - config.Set("AllowAlternatePorts", m_allow_alternate_ports.ToString()); - config.Set("ExternalHostName", m_externalHostName); if (m_nonphysPrimMin > 0) @@ -847,10 +885,10 @@ namespace OpenSim.Framework if (m_physPrimMin > 0) config.Set("PhysicalPrimMax", m_physPrimMin); - + if (m_physPrimMax > 0) config.Set("PhysicalPrimMax", m_physPrimMax); - + config.Set("ClampPrimSize", m_clampPrimSize.ToString()); if (m_objectCapacity > 0) @@ -901,6 +939,222 @@ namespace OpenSim.Framework throw new Exception("Invalid file type for region persistence."); } + public void loadConfigurationOptionsFromMe() + { + configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_UUID_NULL_FREE, + "UUID of Region (Default is recommended, random UUID)", + RegionID.ToString(), true); + configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Region Name", RegionName, true); + + configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Grid Location (X Axis)", RegionLocX.ToString(), true); + configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Grid Location (Y Axis)", RegionLocY.ToString(), true); + configMember.addConfigurationOption("sim_size_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Size of region in X dimension", RegionSizeX.ToString(), true); + configMember.addConfigurationOption("sim_size_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Size of region in Y dimension", RegionSizeY.ToString(), true); + configMember.addConfigurationOption("sim_size_z", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Size of region in Z dimension", RegionSizeZ.ToString(), true); + + //m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false); + configMember.addConfigurationOption("internal_ip_address", + ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS, + "Internal IP Address for incoming UDP client connections", + m_internalEndPoint.Address.ToString(), + true); + configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Internal IP Port for incoming UDP client connections", + m_internalEndPoint.Port.ToString(), true); + configMember.addConfigurationOption("external_host_name", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "External Host Name", m_externalHostName, true); + configMember.addConfigurationOption("lastmap_uuid", ConfigurationOption.ConfigurationTypes.TYPE_UUID, + "Last Map UUID", lastMapUUID.ToString(), true); + configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true); + + configMember.addConfigurationOption("nonphysical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, + "Minimum size for nonphysical prims", m_nonphysPrimMin.ToString(), true); + + configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true); + + configMember.addConfigurationOption("physical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, + "Minimum size for nonphysical prims", m_physPrimMin.ToString(), true); + + configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Maximum size for physical prims", m_physPrimMax.ToString(), true); + + configMember.addConfigurationOption("clamp_prim_size", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, + "Clamp prims to max size", m_clampPrimSize.ToString(), true); + + configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Max objects this sim will hold", m_objectCapacity.ToString(), true); + + configMember.addConfigurationOption("linkset_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Max prims an object will hold", m_linksetCapacity.ToString(), true); + + configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Max avatars this sim will hold",AgentCapacity.ToString(), true); + + configMember.addConfigurationOption("scope_id", ConfigurationOption.ConfigurationTypes.TYPE_UUID, + "Scope ID for this region", ScopeID.ToString(), true); + + configMember.addConfigurationOption("region_type", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Free form string describing the type of region", String.Empty, true); + + configMember.addConfigurationOption("region_static_maptile", ConfigurationOption.ConfigurationTypes.TYPE_UUID, + "UUID of a texture to use as the map for this region", m_maptileStaticUUID.ToString(), true); + } + + public void loadConfigurationOptions() + { + configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_UUID, + "UUID of Region (Default is recommended, random UUID)", + UUID.Random().ToString(), true); + configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Region Name", "OpenSim Test", false); + + configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Grid Location (X Axis)", "1000", false); + configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Grid Location (Y Axis)", "1000", false); + configMember.addConfigurationOption("sim_size_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Size of region in X dimension", Constants.RegionSize.ToString(), false); + configMember.addConfigurationOption("sim_size_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Size of region in Y dimension", Constants.RegionSize.ToString(), false); + configMember.addConfigurationOption("sim_size_z", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Size of region in Z dimension", Constants.RegionHeight.ToString(), false); + + //m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false); + configMember.addConfigurationOption("internal_ip_address", + ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS, + "Internal IP Address for incoming UDP client connections", "0.0.0.0", + false); + configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Internal IP Port for incoming UDP client connections", + ConfigSettings.DefaultRegionHttpPort.ToString(), false); + configMember.addConfigurationOption("external_host_name", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "External Host Name", "127.0.0.1", false); + configMember.addConfigurationOption("lastmap_uuid", ConfigurationOption.ConfigurationTypes.TYPE_UUID, + "Last Map UUID", lastMapUUID.ToString(), true); + + configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true); + + configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Maximum size for nonphysical prims", "0", true); + + configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Maximum size for physical prims", "0", true); + + configMember.addConfigurationOption("clamp_prim_size", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, + "Clamp prims to max size", "false", true); + + configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Max objects this sim will hold", "15000", true); + + configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Max avatars this sim will hold", "100", true); + + configMember.addConfigurationOption("scope_id", ConfigurationOption.ConfigurationTypes.TYPE_UUID, + "Scope ID for this region", UUID.Zero.ToString(), true); + + configMember.addConfigurationOption("region_type", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Region Type", String.Empty, true); + + configMember.addConfigurationOption("region_static_maptile", ConfigurationOption.ConfigurationTypes.TYPE_UUID, + "UUID of a texture to use as the map for this region", String.Empty, true); + } + + public bool handleIncomingConfiguration(string configuration_key, object configuration_result) + { + switch (configuration_key) + { + case "sim_UUID": + RegionID = (UUID) configuration_result; + originRegionID = (UUID) configuration_result; + break; + case "sim_name": + RegionName = (string) configuration_result; + break; + case "sim_location_x": + RegionLocX = (uint) configuration_result; + break; + case "sim_location_y": + RegionLocY = (uint) configuration_result; + break; + case "sim_size_x": + RegionSizeX = (uint) configuration_result; + break; + case "sim_size_y": + RegionSizeY = (uint) configuration_result; + break; + case "sim_size_z": + RegionSizeZ = (uint) configuration_result; + break; + case "datastore": + DataStore = (string) configuration_result; + break; + case "internal_ip_address": + IPAddress address = (IPAddress) configuration_result; + m_internalEndPoint = new IPEndPoint(address, 0); + break; + case "internal_ip_port": + m_internalEndPoint.Port = (int) configuration_result; + break; + case "external_host_name": + if ((string) configuration_result != "SYSTEMIP") + { + m_externalHostName = (string) configuration_result; + } + else + { + m_externalHostName = Util.GetLocalHost().ToString(); + } + break; + case "lastmap_uuid": + lastMapUUID = (UUID)configuration_result; + break; + case "lastmap_refresh": + lastMapRefresh = (string)configuration_result; + break; + case "nonphysical_prim_max": + m_nonphysPrimMax = (int)configuration_result; + break; + case "physical_prim_max": + m_physPrimMax = (int)configuration_result; + break; + case "clamp_prim_size": + m_clampPrimSize = (bool)configuration_result; + break; + case "object_capacity": + m_objectCapacity = (int)configuration_result; + break; + case "linkset_capacity": + m_linksetCapacity = (int)configuration_result; + break; + case "agent_capacity": + AgentCapacity = (int)configuration_result; + break; + case "scope_id": + ScopeID = (UUID)configuration_result; + break; + case "region_type": + m_regionType = (string)configuration_result; + break; + case "region_static_maptile": + m_maptileStaticUUID = (UUID)configuration_result; + break; + } + + return true; + } + + public void SaveLastMapUUID(UUID mapUUID) { lastMapUUID = mapUUID; @@ -928,7 +1182,6 @@ namespace OpenSim.Framework if ((RemotingAddress != null) && !RemotingAddress.Equals("")) args["remoting_address"] = OSD.FromString(RemotingAddress); args["remoting_port"] = OSD.FromString(RemotingPort.ToString()); - args["allow_alt_ports"] = OSD.FromBoolean(m_allow_alternate_ports); if ((proxyUrl != null) && !proxyUrl.Equals("")) args["proxy_url"] = OSD.FromString(proxyUrl); if (RegionType != String.Empty) @@ -983,8 +1236,6 @@ namespace OpenSim.Framework RemotingAddress = args["remoting_address"].AsString(); if (args["remoting_port"] != null) UInt32.TryParse(args["remoting_port"].AsString(), out m_remotingPort); - if (args["allow_alt_ports"] != null) - m_allow_alternate_ports = args["allow_alt_ports"].AsBoolean(); if (args["proxy_url"] != null) proxyUrl = args["proxy_url"].AsString(); if (args["region_type"] != null) @@ -1004,5 +1255,29 @@ namespace OpenSim.Framework regionInfo.ServerURI = serverURI; return regionInfo; } + + public int getInternalEndPointPort() + { + return m_internalEndPoint.Port; + } + + public Dictionary ToKeyValuePairs() + { + Dictionary kvp = new Dictionary(); + kvp["uuid"] = RegionID.ToString(); + kvp["locX"] = RegionLocX.ToString(); + kvp["locY"] = RegionLocY.ToString(); + kvp["external_ip_address"] = ExternalEndPoint.Address.ToString(); + kvp["external_port"] = ExternalEndPoint.Port.ToString(); + kvp["external_host_name"] = ExternalHostName; + kvp["http_port"] = HttpPort.ToString(); + kvp["internal_ip_address"] = InternalEndPoint.Address.ToString(); + kvp["internal_port"] = InternalEndPoint.Port.ToString(); + // TODO: Remove in next major version + kvp["alternate_ports"] = "False"; + kvp["server_uri"] = ServerURI; + + return kvp; + } } } diff --git a/OpenSim/Framework/RegionSettings.cs b/OpenSim/Framework/RegionSettings.cs index a895c40..c2947a2 100644 --- a/OpenSim/Framework/RegionSettings.cs +++ b/OpenSim/Framework/RegionSettings.cs @@ -91,7 +91,7 @@ namespace OpenSim.Framework string[] parts = str.Split(','); if (parts.Length != 3) throw new ArgumentException("Invalid string: " + str); - + SpawnPoint sp = new SpawnPoint(); sp.Yaw = float.Parse(parts[0]); sp.Pitch = float.Parse(parts[1]); @@ -105,7 +105,7 @@ namespace OpenSim.Framework public delegate void SaveDelegate(RegionSettings rs); public event SaveDelegate OnSave; - + /// /// These appear to be terrain textures that are shipped with the client. /// @@ -454,24 +454,24 @@ namespace OpenSim.Framework get { return m_LoadedCreationDateTime; } set { m_LoadedCreationDateTime = value; } } - + public String LoadedCreationDate { - get - { + get + { TimeSpan ts = new TimeSpan(0, 0, LoadedCreationDateTime); DateTime stamp = new DateTime(1970, 1, 1) + ts; - return stamp.ToLongDateString(); + return stamp.ToLongDateString(); } } public String LoadedCreationTime { - get - { + get + { TimeSpan ts = new TimeSpan(0, 0, LoadedCreationDateTime); DateTime stamp = new DateTime(1970, 1, 1) + ts; - return stamp.ToLongTimeString(); + return stamp.ToLongTimeString(); } } @@ -482,6 +482,28 @@ namespace OpenSim.Framework set { m_LoadedCreationID = value; } } + private bool m_GodBlockSearch = false; + public bool GodBlockSearch + { + get { return m_GodBlockSearch; } + set { m_GodBlockSearch = value; } + } + + private bool m_Casino = false; + public bool Casino + { + get { return m_Casino; } + set { m_Casino = value; } + } + + // Telehub support + private bool m_TelehubEnabled = false; + public bool HasTelehub + { + get { return m_TelehubEnabled; } + set { m_TelehubEnabled = value; } + } + /// /// Connected Telehub object /// @@ -520,4 +542,4 @@ namespace OpenSim.Framework l_SpawnPoints.Clear(); } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/RestClient.cs b/OpenSim/Framework/RestClient.cs index 7080ca5..4939cf7 100644 --- a/OpenSim/Framework/RestClient.cs +++ b/OpenSim/Framework/RestClient.cs @@ -156,7 +156,7 @@ namespace OpenSim.Framework public void Dispose() { Dispose(true); - GC.SuppressFinalize(this); + GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) @@ -388,10 +388,10 @@ namespace OpenSim.Framework m_log.Error(string.Format("[REST CLIENT] Error fetching resource from server: {0} ", _request.Address.ToString()), e); } } - return null; } + if (_asyncException != null) throw _asyncException; @@ -413,7 +413,7 @@ namespace OpenSim.Framework _request = (HttpWebRequest) WebRequest.Create(buildUri()); _request.KeepAlive = false; _request.ContentType = "application/xml"; - _request.Timeout = 900000; + _request.Timeout = 90000; _request.Method = RequestMethod; _asyncException = null; _request.ContentLength = src.Length; @@ -428,18 +428,23 @@ namespace OpenSim.Framework if (WebUtil.DebugLevel >= 5) WebUtil.LogOutgoingDetail(string.Format("SEND {0}: ", reqnum), src); - Stream dst = _request.GetRequestStream(); - - byte[] buf = new byte[1024]; - int length = src.Read(buf, 0, 1024); - while (length > 0) - { - dst.Write(buf, 0, length); - length = src.Read(buf, 0, 1024); - } - + try { + using (Stream dst = _request.GetRequestStream()) + { +// m_log.Debug("[REST]: GetRequestStream is ok"); + + byte[] buf = new byte[1024]; + int length = src.Read(buf, 0, 1024); +// m_log.Debug("[REST]: First Read is ok"); + while (length > 0) + { + dst.Write(buf, 0, length); + length = src.Read(buf, 0, 1024); + } + } + _response = (HttpWebResponse)_request.GetResponse(); } catch (WebException e) @@ -468,7 +473,8 @@ namespace OpenSim.Framework } } - _response.Close(); + if (_response != null) + _response.Close(); // IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request); @@ -673,4 +679,4 @@ namespace OpenSim.Framework } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/SLUtil.cs b/OpenSim/Framework/SLUtil.cs index e66d5be..9458625 100644 --- a/OpenSim/Framework/SLUtil.cs +++ b/OpenSim/Framework/SLUtil.cs @@ -44,7 +44,7 @@ namespace OpenSim.Framework Material = -2 } - + #region SL / file extension / content-type conversions /// @@ -175,10 +175,10 @@ namespace OpenSim.Framework new TypeMapping(AssetType.Folder, FolderType.CurrentOutfit, "application/vnd.ll.currentoutfitfolder", "currentoutfitfolder"), new TypeMapping(AssetType.Folder, FolderType.Outfit, "application/vnd.ll.outfitfolder", "outfitfolder"), new TypeMapping(AssetType.Folder, FolderType.MyOutfits, "application/vnd.ll.myoutfitsfolder", "myoutfitsfolder"), - + // This next mappping is an asset to inventory item mapping. // Note: LL stores folders as assets of type Folder = 8, and it has a corresponding InventoryType = 8 - // OpenSim doesn't store folders as assets, so this mapping should only be used when parsing things from the viewer to the server + // OpenSim doesn't store folders as assets, so this mapping should only be used when parsing things from the viewer to the server new TypeMapping(AssetType.Folder, InventoryType.Folder, "application/vnd.ll.folder", "folder"), // OpenSim specific @@ -198,7 +198,7 @@ namespace OpenSim.Framework inventory2Content = new Dictionary(); content2Asset = new Dictionary(); content2Inventory = new Dictionary(); - + foreach (TypeMapping mapping in MAPPINGS) { sbyte assetType = mapping.AssetTypeCode; @@ -226,7 +226,7 @@ namespace OpenSim.Framework } } } - + public static string SLAssetTypeToContentType(int assetType) { string contentType; @@ -406,7 +406,7 @@ namespace OpenSim.Framework if(data[0] == "inv_item") { skipInventoryItem(reader); - } + } else if (line.IndexOf('{') >= 0) { throw new NotANotecardFormatException(reader.LineNumber); @@ -462,7 +462,7 @@ namespace OpenSim.Framework { int length = Int32.Parse(data[2]); notecardString = reader.getBlock(length); - } + } else if (line.IndexOf('{') >= 0) { throw new NotANotecardFormatException(reader.LineNumber); diff --git a/OpenSim/Framework/Serialization/ArchiveConstants.cs b/OpenSim/Framework/Serialization/ArchiveConstants.cs index ab3c285..9081411 100644 --- a/OpenSim/Framework/Serialization/ArchiveConstants.cs +++ b/OpenSim/Framework/Serialization/ArchiveConstants.cs @@ -72,12 +72,12 @@ namespace OpenSim.Framework.Serialization /// Path for region settings. /// public const string SETTINGS_PATH = "settings/"; - + /// /// Path for region settings. /// public const string LANDDATA_PATH = "landdata/"; - + /// /// Path for user profiles /// diff --git a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs index 55640ac..af130a5 100644 --- a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs +++ b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs @@ -106,13 +106,13 @@ namespace OpenSim.Framework.Serialization.External { errors = true; parseExceptionAction(nodeToFill, nodeName, e); - + if (xtr.EOF) { m_log.Debug("[ExternalRepresentationUtils]: Aborting ExecuteReadProcessors due to unexpected end of XML"); break; } - + if (++numErrors == 10) { m_log.Debug("[ExternalRepresentationUtils]: Aborting ExecuteReadProcessors due to too many parsing errors"); @@ -156,6 +156,7 @@ namespace OpenSim.Framework.Serialization.External return xml; XmlDocument doc = new XmlDocument(); + doc.XmlResolver=null; doc.LoadXml(xml); XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart"); @@ -220,7 +221,7 @@ namespace OpenSim.Framework.Serialization.External using (StringWriter sw = new StringWriter()) using (XmlTextWriter writer = new XmlTextWriter(sw)) using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null)) - using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment })) + using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment, ProhibitDtd = true})) { TransformXml(reader, writer, sceneName, homeURL, userService, scopeID); @@ -369,7 +370,7 @@ namespace OpenSim.Framework.Serialization.External break; case XmlNodeType.XmlDeclaration: - // For various reasons, not all serializations have xml declarations (or consistent ones) + // For various reasons, not all serializations have xml declarations (or consistent ones) // and as it's embedded inside a byte stream we don't need it anyway, so ignore. break; diff --git a/OpenSim/Framework/Serialization/External/LandDataSerializer.cs b/OpenSim/Framework/Serialization/External/LandDataSerializer.cs index e42d56f..33ffd83 100644 --- a/OpenSim/Framework/Serialization/External/LandDataSerializer.cs +++ b/OpenSim/Framework/Serialization/External/LandDataSerializer.cs @@ -178,6 +178,7 @@ namespace OpenSim.Framework.Serialization.External using (XmlTextReader reader = new XmlTextReader(new StringReader(serializedLandData))) { + reader.ProhibitDtd = true; reader.ReadStartElement("LandData"); ExternalRepresentationUtils.ExecuteReadProcessors(landData, m_ldProcessors, reader); diff --git a/OpenSim/Framework/Serialization/External/OspResolver.cs b/OpenSim/Framework/Serialization/External/OspResolver.cs index fa7160f..a1e9d55 100644 --- a/OpenSim/Framework/Serialization/External/OspResolver.cs +++ b/OpenSim/Framework/Serialization/External/OspResolver.cs @@ -35,13 +35,13 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Framework.Serialization { /// - /// Resolves OpenSim Profile Anchors (OSPA). An OSPA is a string used to provide information for + /// Resolves OpenSim Profile Anchors (OSPA). An OSPA is a string used to provide information for /// identifying user profiles or supplying a simple name if no profile is available. /// public class OspResolver { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + public const string OSPA_PREFIX = "ospa:"; public const string OSPA_NAME_KEY = "n"; public const string OSPA_NAME_VALUE_SEPARATOR = " "; @@ -76,7 +76,7 @@ namespace OpenSim.Framework.Serialization return null; } - + /// /// Make an OSPA given a user name /// @@ -89,17 +89,17 @@ namespace OpenSim.Framework.Serialization // m_log.DebugFormat("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName); // System.Console.WriteLine("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName); - + return ospa; } - + /// /// Resolve an osp string into the most suitable internal OpenSim identifier. /// - /// + /// /// In some cases this will be a UUID if a suitable profile exists on the system. In other cases, this may /// just return the same identifier after creating a temporary profile. - /// + /// /// /// /// @@ -111,14 +111,14 @@ namespace OpenSim.Framework.Serialization if (!ospa.StartsWith(OSPA_PREFIX)) { // m_log.DebugFormat("[OSP RESOLVER]: ResolveOspa() got unrecognized format [{0}]", ospa); - return UUID.Zero; + return UUID.Zero; } // m_log.DebugFormat("[OSP RESOLVER]: Resolving {0}", ospa); - + string ospaMeat = ospa.Substring(OSPA_PREFIX.Length); string[] ospaTuples = ospaMeat.Split(OSPA_TUPLE_SEPARATOR_ARRAY); - + foreach (string tuple in ospaTuples) { int tupleSeparatorIndex = tuple.IndexOf(OSPA_PAIR_SEPARATOR); @@ -128,17 +128,17 @@ namespace OpenSim.Framework.Serialization m_log.WarnFormat("[OSP RESOLVER]: Ignoring non-tuple component {0} in OSPA {1}", tuple, ospa); continue; } - + string key = tuple.Remove(tupleSeparatorIndex).Trim(); string value = tuple.Substring(tupleSeparatorIndex + 1).Trim(); - + if (OSPA_NAME_KEY == key) return ResolveOspaName(value, userService); } - + return UUID.Zero; } - + /// /// Hash a profile name into a UUID /// @@ -148,7 +148,7 @@ namespace OpenSim.Framework.Serialization { return new UUID(Utils.MD5(Encoding.Unicode.GetBytes(name)), 0); } - + /// /// Resolve an OSPI name by querying existing persistent user profiles. If there is no persistent user profile /// then a temporary user profile is inserted in the cache. @@ -164,13 +164,13 @@ namespace OpenSim.Framework.Serialization return UUID.Zero; int nameSeparatorIndex = name.IndexOf(OSPA_NAME_VALUE_SEPARATOR); - + if (nameSeparatorIndex < 0) { m_log.WarnFormat("[OSP RESOLVER]: Ignoring unseparated name {0}", name); return UUID.Zero; } - + string firstName = name.Remove(nameSeparatorIndex).TrimEnd(); string lastName = name.Substring(nameSeparatorIndex + 1).TrimStart(); @@ -178,14 +178,14 @@ namespace OpenSim.Framework.Serialization if (account != null) { // m_log.DebugFormat( -// "[OSP RESOLVER]: Found user account with uuid {0} for {1} {2}", +// "[OSP RESOLVER]: Found user account with uuid {0} for {1} {2}", // account.PrincipalID, firstName, lastName); - + return account.PrincipalID; } // else // { -// m_log.DebugFormat("[OSP RESOLVER]: No resolved OSPA user account for {0}", name); +// m_log.DebugFormat("[OSP RESOLVER]: No resolved OSPA user account for {0}", name); // } // XXX: Disable temporary user profile creation for now as implementation is incomplete - justincc @@ -194,11 +194,11 @@ namespace OpenSim.Framework.Serialization tempUserProfile.FirstName = firstName; tempUserProfile.SurName = lastName; tempUserProfile.ID = HashName(tempUserProfile.Name); - + m_log.DebugFormat( "[OSP RESOLVER]: Adding temporary user profile for {0} {1}", tempUserProfile.Name, tempUserProfile.ID); commsManager.UserService.AddTemporaryUserProfile(tempUserProfile); - + return tempUserProfile.ID; */ diff --git a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs index 19468c3..fd21f3e 100644 --- a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs +++ b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs @@ -50,7 +50,7 @@ namespace OpenSim.Framework.Serialization.External { return Deserialize(Encoding.ASCII.GetString(serializedSettings, 0, serializedSettings.Length)); } - + /// /// Deserialize settings /// @@ -60,14 +60,15 @@ namespace OpenSim.Framework.Serialization.External public static RegionSettings Deserialize(string serializedSettings) { RegionSettings settings = new RegionSettings(); - + StringReader sr = new StringReader(serializedSettings); XmlTextReader xtr = new XmlTextReader(sr); - + xtr.ProhibitDtd = true; + xtr.ReadStartElement("RegionSettings"); - + xtr.ReadStartElement("General"); - + while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement) { switch (xtr.Name) @@ -113,10 +114,10 @@ namespace OpenSim.Framework.Serialization.External break; } } - + xtr.ReadEndElement(); xtr.ReadStartElement("GroundTextures"); - + while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement) { switch (xtr.Name) @@ -159,10 +160,10 @@ namespace OpenSim.Framework.Serialization.External break; } } - + xtr.ReadEndElement(); xtr.ReadStartElement("Terrain"); - + while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement) { switch (xtr.Name) @@ -212,19 +213,19 @@ namespace OpenSim.Framework.Serialization.External xtr.Close(); sr.Close(); - + return settings; } - + public static string Serialize(RegionSettings settings) { StringWriter sw = new StringWriter(); XmlTextWriter xtw = new XmlTextWriter(sw); xtw.Formatting = Formatting.Indented; xtw.WriteStartDocument(); - + xtw.WriteStartElement("RegionSettings"); - + xtw.WriteStartElement("General"); xtw.WriteElementString("AllowDamage", settings.AllowDamage.ToString()); xtw.WriteElementString("AllowLandResell", settings.AllowLandResell.ToString()); @@ -255,7 +256,7 @@ namespace OpenSim.Framework.Serialization.External xtw.WriteElementString("ElevationHighSE", settings.Elevation2SE.ToString()); xtw.WriteElementString("ElevationHighNE", settings.Elevation2NE.ToString()); xtw.WriteEndElement(); - + xtw.WriteStartElement("Terrain"); xtw.WriteElementString("WaterHeight", settings.WaterHeight.ToString()); xtw.WriteElementString("TerrainRaiseLimit", settings.TerrainRaiseLimit.ToString()); @@ -275,12 +276,12 @@ namespace OpenSim.Framework.Serialization.External xtw.WriteElementString("SpawnPoint", sp.ToString()); } xtw.WriteEndElement(); - + xtw.WriteEndElement(); - + xtw.Close(); sw.Close(); - + return sw.ToString(); } } diff --git a/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs b/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs index 994cede..12194ad 100644 --- a/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs +++ b/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs @@ -36,9 +36,9 @@ using log4net; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Services.Interfaces; - + namespace OpenSim.Framework.Serialization.External -{ +{ /// /// Serialize and deserialize user inventory items as an external format. /// @@ -49,14 +49,14 @@ namespace OpenSim.Framework.Serialization.External private static Dictionary> m_InventoryItemXmlProcessors = new Dictionary>(); - #region InventoryItemBase Processor initialization + #region InventoryItemBase Processor initialization static UserInventoryItemSerializer() { m_InventoryItemXmlProcessors.Add("Name", ProcessName); m_InventoryItemXmlProcessors.Add("ID", ProcessID); m_InventoryItemXmlProcessors.Add("InvType", ProcessInvType); m_InventoryItemXmlProcessors.Add("CreatorUUID", ProcessCreatorUUID); - m_InventoryItemXmlProcessors.Add("CreatorID", ProcessCreatorID); + m_InventoryItemXmlProcessors.Add("CreatorID", ProcessCreatorID); m_InventoryItemXmlProcessors.Add("CreatorData", ProcessCreatorData); m_InventoryItemXmlProcessors.Add("CreationDate", ProcessCreationDate); m_InventoryItemXmlProcessors.Add("Owner", ProcessOwner); @@ -73,7 +73,7 @@ namespace OpenSim.Framework.Serialization.External m_InventoryItemXmlProcessors.Add("GroupID", ProcessGroupID); m_InventoryItemXmlProcessors.Add("GroupOwned", ProcessGroupOwned); } - #endregion + #endregion #region InventoryItemBase Processors private static void ProcessName(InventoryItemBase item, XmlReader reader) @@ -189,7 +189,7 @@ namespace OpenSim.Framework.Serialization.External { return Deserialize(Encoding.ASCII.GetString(serialization, 0, serialization.Length)); } - + /// /// Deserialize settings /// @@ -202,6 +202,8 @@ namespace OpenSim.Framework.Serialization.External using (XmlTextReader reader = new XmlTextReader(new StringReader(serialization))) { + reader.ProhibitDtd = true; + reader.ReadStartElement("InventoryItem"); ExternalRepresentationUtils.ExecuteReadProcessors( @@ -212,8 +214,8 @@ namespace OpenSim.Framework.Serialization.External //m_log.DebugFormat("[XXX]: parsed InventoryItemBase {0} - {1}", obj.Name, obj.UUID); return item; - } - + } + public static string Serialize(InventoryItemBase inventoryItem, Dictionary options, IUserAccountService userAccountService) { StringWriter sw = new StringWriter(); @@ -294,11 +296,11 @@ namespace OpenSim.Framework.Serialization.External } writer.WriteEndElement(); - + writer.Close(); sw.Close(); - + return sw.ToString(); - } + } } } diff --git a/OpenSim/Framework/Serialization/External/UserProfileSerializer.cs b/OpenSim/Framework/Serialization/External/UserProfileSerializer.cs index c685a15..34eaa99 100644 --- a/OpenSim/Framework/Serialization/External/UserProfileSerializer.cs +++ b/OpenSim/Framework/Serialization/External/UserProfileSerializer.cs @@ -42,31 +42,31 @@ namespace OpenSim.Framework.Serialization.External { public const int MAJOR_VERSION = 0; public const int MINOR_VERSION = 1; - + public static string Serialize(UUID userID, string firstName, string lastName) { StringWriter sw = new StringWriter(); XmlTextWriter xtw = new XmlTextWriter(sw); xtw.Formatting = Formatting.Indented; xtw.WriteStartDocument(); - + xtw.WriteStartElement("user_profile"); xtw.WriteAttributeString("major_version", MAJOR_VERSION.ToString()); xtw.WriteAttributeString("minor_version", MINOR_VERSION.ToString()); - + xtw.WriteElementString("name", firstName + " " + lastName); xtw.WriteElementString("id", userID.ToString()); xtw.WriteElementString("about", ""); - + // Not sure if we're storing this yet, need to take a look // xtw.WriteElementString("Url", profile.Url); // or, indeed, interests xtw.WriteEndElement(); - + xtw.Close(); sw.Close(); - + return sw.ToString(); } } diff --git a/OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs b/OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs index acec20f..7dfb87b 100644 --- a/OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs @@ -2,7 +2,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("OpenSim.Framework.Serialization")] @@ -14,8 +14,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] @@ -25,9 +25,9 @@ using System.Runtime.InteropServices; // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("0.8.3.*")] +[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] diff --git a/OpenSim/Framework/Serialization/TarArchiveWriter.cs b/OpenSim/Framework/Serialization/TarArchiveWriter.cs index 2a3bc48..a5c3d0a 100644 --- a/OpenSim/Framework/Serialization/TarArchiveWriter.cs +++ b/OpenSim/Framework/Serialization/TarArchiveWriter.cs @@ -113,7 +113,7 @@ namespace OpenSim.Framework.Serialization lock (m_bw) { m_bw.Write(finalZeroPadding); - + m_bw.Flush(); m_bw.Close(); } @@ -149,7 +149,7 @@ namespace OpenSim.Framework.Serialization { // m_log.DebugFormat( // "[TAR ARCHIVE WRITER]: Data for {0} is {1} bytes", filePath, (null == data ? "null" : data.Length.ToString())); - + byte[] header = new byte[512]; // file path field (100) @@ -208,18 +208,18 @@ namespace OpenSim.Framework.Serialization { // Write out header m_bw.Write(header); - + // Write out data // An IOException occurs if we try to write out an empty array in Mono 2.6 if (data.Length > 0) m_bw.Write(data); - + if (data.Length % 512 != 0) { int paddingRequired = 512 - (data.Length % 512); - + //m_log.DebugFormat("[TAR ARCHIVE WRITER]: Padding data with {0} bytes", paddingRequired); - + byte[] padding = new byte[paddingRequired]; m_bw.Write(padding); } diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 5ce978e..81dd357 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -65,11 +65,12 @@ namespace OpenSim.Framework.Servers /// This will control a periodic log printout of the current 'show stats' (if they are active) for this /// server. /// + private int m_periodDiagnosticTimerMS = 60 * 60 * 1000; private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000); - + /// - /// Random uuid for private data + /// Random uuid for private data /// protected string m_osSecret = String.Empty; @@ -83,9 +84,8 @@ namespace OpenSim.Framework.Servers { // Random uuid for private data m_osSecret = UUID.Random().ToString(); - } - + /// /// Must be overriden by child classes for their own server specific startup behaviour. /// @@ -104,26 +104,33 @@ namespace OpenSim.Framework.Servers m_periodicDiagnosticsTimer.Interval = m_periodDiagnosticTimerMS; m_periodicDiagnosticsTimer.Enabled = true; } - } + } protected override void ShutdownSpecific() - { - m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting..."); + { + Watchdog.Enabled = false; + base.ShutdownSpecific(); + + MainServer.Stop(); + + Thread.Sleep(5000); + Util.StopThreadPool(); + WorkManager.Stop(); + Thread.Sleep(1000); RemovePIDFile(); - base.ShutdownSpecific(); + m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting..."); - if (!SuppressExit) - System.Diagnostics.Process.GetCurrentProcess().Kill(); -//// Environment.Exit(0); + if (!SuppressExit) + Environment.Exit(0); } - + /// /// Provides a list of help topics that are available. Overriding classes should append their topics to the /// information returned when the base method is called. /// - /// + /// /// /// A list of strings that represent different help topics on which more information is available /// @@ -147,20 +154,38 @@ namespace OpenSim.Framework.Servers /// Performs initialisation of the scene, such as loading configuration from disk. /// public virtual void Startup() - { - StartupSpecific(); - + { + m_log.Info("[STARTUP]: Beginning startup processing"); + + m_log.Info("[STARTUP]: version: " + m_version + Environment.NewLine); + // clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and + // the clr version number doesn't match the project version number under Mono. + //m_log.Info("[STARTUP]: Virtual machine runtime version: " + Environment.Version + Environment.NewLine); + m_log.InfoFormat( + "[STARTUP]: Operating system version: {0}, .NET platform {1}, {2}-bit\n", + Environment.OSVersion, Environment.OSVersion.Platform, Util.Is64BitProcess() ? "64" : "32"); + + try + { + StartupSpecific(); + } + catch(Exception e) + { + m_log.Fatal("Fatal error: " + e.ToString()); + Environment.Exit(1); + } + TimeSpan timeTaken = DateTime.Now - m_startuptime; - - MainConsole.Instance.OutputFormat( - "PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED. Non-script portion of startup took {0}m {1}s.", - timeTaken.Minutes, timeTaken.Seconds); + +// MainConsole.Instance.OutputFormat( +// "PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED. Non-script portion of startup took {0}m {1}s.", +// timeTaken.Minutes, timeTaken.Seconds); } - public string osSecret + public string osSecret { // Secret uuid for the simulator - get { return m_osSecret; } + get { return m_osSecret; } } public string StatReport(IOSHttpRequest httpRequest) @@ -169,8 +194,8 @@ namespace OpenSim.Framework.Servers if (httpRequest.Query.ContainsKey("callback")) { return httpRequest.Query["callback"].ToString() + "(" + StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");"; - } - else + } + else { return StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version); } diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index f252bd5..f4ba02f 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -58,7 +58,7 @@ namespace OpenSim.Framework.Servers.HttpServer /// /// This is a pending websocket request before it got an sucessful upgrade response. - /// The consumer must call handler.HandshakeAndUpgrade() to signal to the handler to + /// The consumer must call handler.HandshakeAndUpgrade() to signal to the handler to /// start the connection and optionally provide an origin authentication method. /// /// @@ -104,7 +104,7 @@ namespace OpenSim.Framework.Servers.HttpServer new Dictionary(); protected Dictionary m_WebSocketHandlers = - new Dictionary(); + new Dictionary(); protected uint m_port; protected uint m_sslport; @@ -253,7 +253,7 @@ namespace OpenSim.Framework.Servers.HttpServer return new List(m_rpcHandlers.Keys); } - // JsonRPC + // JsonRPC public bool AddJsonRPCHandler(string method, JsonRPCMethod handler) { lock(jsonRpcHandlers) @@ -399,10 +399,10 @@ namespace OpenSim.Framework.Servers.HttpServer Stream requestStream = req.InputStream; + string requestBody; Encoding encoding = Encoding.UTF8; - StreamReader reader = new StreamReader(requestStream, encoding); - - string requestBody = reader.ReadToEnd(); + using(StreamReader reader = new StreamReader(requestStream, encoding)) + requestBody = reader.ReadToEnd(); Hashtable keysvals = new Hashtable(); Hashtable headervals = new Hashtable(); @@ -458,10 +458,11 @@ namespace OpenSim.Framework.Servers.HttpServer dWebSocketRequestDelegate(req.Url.AbsolutePath, new WebSocketHttpServerHandler(req, context, 8192)); return; } - + OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); resp.ReuseContext = true; - HandleRequest(req, resp); +// resp.ReuseContext = false; + HandleRequest(req, resp); // !!!HACK ALERT!!! // There seems to be a bug in the underlying http code that makes subsequent requests @@ -552,7 +553,7 @@ namespace OpenSim.Framework.Servers.HttpServer LogIncomingToStreamHandler(request, requestHandler); response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. - + if (requestHandler is IStreamedRequestHandler) { IStreamedRequestHandler streamedRequestHandler = requestHandler as IStreamedRequestHandler; @@ -565,13 +566,10 @@ namespace OpenSim.Framework.Servers.HttpServer IGenericHTTPHandler HTTPRequestHandler = requestHandler as IGenericHTTPHandler; Stream requestStream = request.InputStream; + string requestBody; Encoding encoding = Encoding.UTF8; - StreamReader reader = new StreamReader(requestStream, encoding); - - string requestBody = reader.ReadToEnd(); - - reader.Close(); - //requestStream.Close(); + using(StreamReader reader = new StreamReader(requestStream, encoding)) + requestBody = reader.ReadToEnd(); Hashtable keysvals = new Hashtable(); Hashtable headervals = new Hashtable(); @@ -628,16 +626,16 @@ namespace OpenSim.Framework.Servers.HttpServer case "text/html": if (DebugLevel >= 3) LogIncomingToContentTypeHandler(request); - + buffer = HandleHTTPRequest(request, response); break; - + case "application/llsd+xml": case "application/xml+llsd": case "application/llsd+json": if (DebugLevel >= 3) LogIncomingToContentTypeHandler(request); - + buffer = HandleLLSDRequests(request, response); break; @@ -647,7 +645,7 @@ namespace OpenSim.Framework.Servers.HttpServer buffer = HandleJsonRpcRequests(request, response); break; - + case "text/xml": case "application/xml": case "application/json": @@ -664,7 +662,7 @@ namespace OpenSim.Framework.Servers.HttpServer { if (DebugLevel >= 3) LogIncomingToContentTypeHandler(request); - + buffer = HandleLLSDRequests(request, response); } // m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl); @@ -672,23 +670,24 @@ namespace OpenSim.Framework.Servers.HttpServer { if (DebugLevel >= 3) LogIncomingToContentTypeHandler(request); - + buffer = HandleHTTPRequest(request, response); } else { if (DebugLevel >= 3) LogIncomingToXmlRpcHandler(request); - + // generic login request. buffer = HandleXmlRpcRequests(request, response); } - + break; } } - request.InputStream.Close(); + if(request.InputStream.CanRead) + request.InputStream.Dispose(); if (buffer != null) { @@ -759,7 +758,7 @@ namespace OpenSim.Framework.Servers.HttpServer // Every month or so this will wrap and give bad numbers, not really a problem // since its just for reporting int tickdiff = requestEndTick - requestStartTick; - if (tickdiff > 3000 && requestHandler != null && requestHandler.Name != "GetTexture") + if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture")) { m_log.InfoFormat( "[LOGHTTP] Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms", @@ -970,7 +969,7 @@ namespace OpenSim.Framework.Servers.HttpServer // private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler) // { // agentHandler = null; -// +// // lock (m_agentHandlers) // { // foreach (IHttpAgentHandler handler in m_agentHandlers.Values) @@ -996,7 +995,7 @@ namespace OpenSim.Framework.Servers.HttpServer { String requestBody; - Stream requestStream = request.InputStream; + Stream requestStream = Util.Copy(request.InputStream); Stream innerStream = null; try { @@ -1007,9 +1006,8 @@ namespace OpenSim.Framework.Servers.HttpServer } using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8)) - { requestBody = reader.ReadToEnd(); - } + } finally { @@ -1024,6 +1022,19 @@ namespace OpenSim.Framework.Servers.HttpServer string responseString = String.Empty; XmlRpcRequest xmlRprcRequest = null; + bool gridproxy = false; + if (requestBody.Contains("encoding=\"utf-8")) + { + int channelindx = -1; + int optionsindx = requestBody.IndexOf(">options<"); + if(optionsindx >0) + { + channelindx = requestBody.IndexOf(">channel<"); + if (optionsindx < channelindx) + gridproxy = true; + } + } + try { xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody); @@ -1081,6 +1092,8 @@ namespace OpenSim.Framework.Servers.HttpServer } xmlRprcRequest.Params.Add(request.Headers.Get(xff)); // Param[3] + if (gridproxy) + xmlRprcRequest.Params.Add("gridproxy"); // Param[4] try { xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint); @@ -1154,7 +1167,7 @@ namespace OpenSim.Framework.Servers.HttpServer return buffer; } - // JsonRpc (v2.0 only) + // JsonRpc (v2.0 only) // Batch requests not yet supported private byte[] HandleJsonRpcRequests(OSHttpRequest request, OSHttpResponse response) { @@ -1171,7 +1184,7 @@ namespace OpenSim.Framework.Servers.HttpServer jsonRpcResponse.Error.Code = ErrorCode.InternalError; jsonRpcResponse.Error.Message = e.Message; } - + requestStream.Close(); if (jsonRpcRequest != null) @@ -1236,7 +1249,7 @@ namespace OpenSim.Framework.Servers.HttpServer string responseData = string.Empty; responseData = jsonRpcResponse.Serialize(); - + byte[] buffer = Encoding.UTF8.GetBytes(responseData); return buffer; } @@ -1246,12 +1259,10 @@ namespace OpenSim.Framework.Servers.HttpServer //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request"); Stream requestStream = request.InputStream; + string requestBody; Encoding encoding = Encoding.UTF8; - StreamReader reader = new StreamReader(requestStream, encoding); - - string requestBody = reader.ReadToEnd(); - reader.Close(); - requestStream.Close(); + using(StreamReader reader = new StreamReader(requestStream, encoding)) + requestBody= reader.ReadToEnd(); //m_log.DebugFormat("[OGP]: {0}:{1}", request.RawUrl, requestBody); response.KeepAlive = true; @@ -1516,7 +1527,7 @@ namespace OpenSim.Framework.Servers.HttpServer } } } - + if (String.IsNullOrEmpty(bestMatch)) { llsdHandler = null; @@ -1575,15 +1586,10 @@ namespace OpenSim.Framework.Servers.HttpServer byte[] buffer; Stream requestStream = request.InputStream; - + string requestBody; Encoding encoding = Encoding.UTF8; - StreamReader reader = new StreamReader(requestStream, encoding); - - string requestBody = reader.ReadToEnd(); - // avoid warning for now - reader.ReadToEnd(); - reader.Close(); - requestStream.Close(); + using(StreamReader reader = new StreamReader(requestStream, encoding)) + requestBody = reader.ReadToEnd(); Hashtable keysvals = new Hashtable(); Hashtable headervals = new Hashtable(); @@ -1732,10 +1738,40 @@ namespace OpenSim.Framework.Servers.HttpServer internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response) { - //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response"); - int responsecode = (int)responsedata["int_response_code"]; - string responseString = (string)responsedata["str_response_string"]; - string contentType = (string)responsedata["content_type"]; + int responsecode; + string responseString = String.Empty; + byte[] responseData = null; + string contentType; + + if (responsedata == null) + { + responsecode = 500; + responseString = "No response could be obtained"; + contentType = "text/plain"; + responsedata = new Hashtable(); + } + else + { + try + { + //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response"); + responsecode = (int)responsedata["int_response_code"]; + if (responsedata["bin_response_data"] != null) + responseData = (byte[])responsedata["bin_response_data"]; + else + responseString = (string)responsedata["str_response_string"]; + contentType = (string)responsedata["content_type"]; + if (responseString == null) + responseString = String.Empty; + } + catch + { + responsecode = 500; + responseString = "No response could be obtained"; + contentType = "text/plain"; + responsedata = new Hashtable(); + } + } if (responsedata.ContainsKey("error_status_text")) { @@ -1745,16 +1781,19 @@ namespace OpenSim.Framework.Servers.HttpServer { response.ProtocolVersion = (string)responsedata["http_protocol_version"]; } - +/* if (responsedata.ContainsKey("keepalive")) { bool keepalive = (bool)responsedata["keepalive"]; response.KeepAlive = keepalive; - } if (responsedata.ContainsKey("reusecontext")) response.ReuseContext = (bool) responsedata["reusecontext"]; +*/ + // disable this things + response.KeepAlive = false; + response.ReuseContext = false; // Cross-Origin Resource Sharing with simple requests if (responsedata.ContainsKey("access_control_allow_origin")) @@ -1768,8 +1807,11 @@ namespace OpenSim.Framework.Servers.HttpServer contentType = "text/html"; } + + // The client ignores anything but 200 here for web login, so ensure that this is 200 for that + response.StatusCode = responsecode; if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently) @@ -1780,25 +1822,40 @@ namespace OpenSim.Framework.Servers.HttpServer response.AddHeader("Content-Type", contentType); + if (responsedata.ContainsKey("headers")) + { + Hashtable headerdata = (Hashtable)responsedata["headers"]; + + foreach (string header in headerdata.Keys) + response.AddHeader(header, headerdata[header].ToString()); + } + byte[] buffer; - if (!(contentType.Contains("image") - || contentType.Contains("x-shockwave-flash") - || contentType.Contains("application/x-oar") - || contentType.Contains("application/vnd.ll.mesh"))) + if (responseData != null) { - // Text - buffer = Encoding.UTF8.GetBytes(responseString); + buffer = responseData; } else { - // Binary! - buffer = Convert.FromBase64String(responseString); - } + if (!(contentType.Contains("image") + || contentType.Contains("x-shockwave-flash") + || contentType.Contains("application/x-oar") + || contentType.Contains("application/vnd.ll.mesh"))) + { + // Text + buffer = Encoding.UTF8.GetBytes(responseString); + } + else + { + // Binary! + buffer = Convert.FromBase64String(responseString); + } - response.SendChunked = false; - response.ContentLength64 = buffer.Length; - response.ContentEncoding = Encoding.UTF8; + response.SendChunked = false; + response.ContentLength64 = buffer.Length; + response.ContentEncoding = Encoding.UTF8; + } return buffer; } @@ -1831,8 +1888,8 @@ namespace OpenSim.Framework.Servers.HttpServer response.SendChunked = false; response.ContentLength64 = buffer.Length; response.ContentEncoding = Encoding.UTF8; - - + + return buffer; } @@ -1886,7 +1943,8 @@ namespace OpenSim.Framework.Servers.HttpServer m_httpListener2.Start(64); // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events - PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 3, 25000); + + PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 2, 25000); PollServiceRequestManager.Start(); HTTPDRunning = true; @@ -1908,7 +1966,7 @@ namespace OpenSim.Framework.Servers.HttpServer throw e; } - m_requestsProcessedStat + m_requestsProcessedStat = new Stat( "HTTPRequestsServed", "Number of inbound HTTP requests processed", @@ -1920,7 +1978,7 @@ namespace OpenSim.Framework.Servers.HttpServer MeasuresOfInterest.AverageChangeOverTime, stat => stat.Value = RequestNumber, StatVerbosity.Debug); - + StatsManager.RegisterStat(m_requestsProcessedStat); } @@ -1937,7 +1995,9 @@ namespace OpenSim.Framework.Servers.HttpServer public void httpServerException(object source, Exception exception) { - m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1} ", source.ToString(), exception.Message), exception); + if (source.ToString() == "HttpServer.HttpListener" && exception.ToString().StartsWith("Mono.Security.Protocol.Tls.TlsException")) + return; + m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString()); /* if (HTTPDRunning)// && NotSocketErrors > 5) { @@ -1957,7 +2017,8 @@ namespace OpenSim.Framework.Servers.HttpServer try { - PollServiceRequestManager.Stop(); + if(PollServiceRequestManager != null) + PollServiceRequestManager.Stop(); m_httpListener2.ExceptionThrown -= httpServerException; //m_httpListener2.DisconnectHandler = null; @@ -1984,6 +2045,7 @@ namespace OpenSim.Framework.Servers.HttpServer public void RemoveHTTPHandler(string httpMethod, string path) { + if (path == null) return; // Caps module isn't loaded, tries to remove handler where path = null lock (m_HTTPHandlers) { if (httpMethod != null && httpMethod.Length == 0) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs index d4a1ec3..01d95e9 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs @@ -69,13 +69,13 @@ namespace OpenSim.Framework.Servers.HttpServer { StatsManager.RegisterStat( new Stat( - "requests", - "requests", - "Number of requests received by this service endpoint", - "requests", - "service", - string.Format("{0}:{1}", httpMethod, path), - StatType.Pull, + "requests", + "requests", + "Number of requests received by this service endpoint", + "requests", + "service", + string.Format("{0}:{1}", httpMethod, path), + StatType.Pull, MeasuresOfInterest.AverageChangeOverTime, s => s.Value = RequestsReceived, StatVerbosity.Debug)); diff --git a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs index 41aa19b..7fc9f0b 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs @@ -47,7 +47,7 @@ namespace OpenSim.Framework.Servers.HttpServer : base(httpMethod, path, name, description) {} protected BaseStreamHandler(string httpMethod, string path, IServiceAuth auth) - : base(httpMethod, path, null, null) + : base(httpMethod, path, null, null) { m_Auth = auth; } @@ -62,7 +62,7 @@ namespace OpenSim.Framework.Servers.HttpServer HttpStatusCode statusCode; if (!m_Auth.Authenticate(httpRequest.Headers, httpResponse.AddHeader, out statusCode)) - { + { httpResponse.StatusCode = (int)statusCode; httpResponse.ContentType = "text/plain"; return new byte[0]; diff --git a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandlerBasicDOSProtector.cs b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandlerBasicDOSProtector.cs index 1b88545..9619e03 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandlerBasicDOSProtector.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandlerBasicDOSProtector.cs @@ -37,7 +37,7 @@ namespace OpenSim.Framework.Servers.HttpServer /// public abstract class BaseStreamHandlerBasicDOSProtector : BaseRequestHandler, IStreamedRequestHandler { - + private readonly BasicDosProtectorOptions _options; private readonly BasicDOSProtector _dosProtector; @@ -63,7 +63,7 @@ namespace OpenSim.Framework.Servers.HttpServer result = ThrottledRequest(path, request, httpRequest, httpResponse); if (_options.MaxConcurrentSessions > 0) _dosProtector.ProcessEnd(clientstring, endpoint); - + RequestsHandled++; return result; @@ -81,7 +81,7 @@ namespace OpenSim.Framework.Servers.HttpServer return new byte[0]; } - + private string GetRemoteAddr(IOSHttpRequest httpRequest) { string remoteaddr = string.Empty; @@ -101,7 +101,7 @@ namespace OpenSim.Framework.Servers.HttpServer clientstring = GetRemoteAddr(httpRequest); return clientstring; - + } } } diff --git a/OpenSim/Framework/Servers/HttpServer/GenericHTTPBasicDOSProtector.cs b/OpenSim/Framework/Servers/HttpServer/GenericHTTPBasicDOSProtector.cs index cd4b8ff..98d33e4 100644 --- a/OpenSim/Framework/Servers/HttpServer/GenericHTTPBasicDOSProtector.cs +++ b/OpenSim/Framework/Servers/HttpServer/GenericHTTPBasicDOSProtector.cs @@ -33,7 +33,7 @@ namespace OpenSim.Framework.Servers.HttpServer { private readonly GenericHTTPMethod _normalMethod; private readonly GenericHTTPMethod _throttledMethod; - + private readonly BasicDosProtectorOptions _options; private readonly BasicDOSProtector _dosProtector; @@ -41,7 +41,7 @@ namespace OpenSim.Framework.Servers.HttpServer { _normalMethod = normalMethod; _throttledMethod = throttledMethod; - + _options = options; _dosProtector = new BasicDOSProtector(_options); } @@ -60,7 +60,7 @@ namespace OpenSim.Framework.Servers.HttpServer return process; } - + private string GetRemoteAddr(Hashtable request) { string remoteaddr = ""; diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs index d162bc1..3a04074 100644 --- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs @@ -45,26 +45,26 @@ namespace OpenSim.Framework.Servers.HttpServer // // the handlers - it is NOT required to be an actual agent header // // value. // bool AddAgentHandler(string agent, IHttpAgentHandler handler); - + /// /// Add a handler for an HTTP request. /// /// - /// This handler can actually be invoked either as - /// - /// http://:/?method= - /// + /// This handler can actually be invoked either as + /// + /// http://:/?method= + /// /// or - /// + /// /// http://: - /// + /// /// if the method name starts with a slash. For example, AddHTTPHandler("/object/", ...) on a standalone region /// server will register a handler that can be invoked with either - /// + /// /// http://localhost:9000/?method=/object/ - /// + /// /// or - /// + /// /// http://localhost:9000/object/ /// /// In addition, the handler invoked by the HTTP server for any request is the one when best matches the request @@ -87,7 +87,7 @@ namespace OpenSim.Framework.Servers.HttpServer /// handle the LLSD response /// bool AddLLSDHandler(string path, LLSDMethod handler); - + /// /// Add a stream handler to the http server. If the handler already exists, then nothing happens. /// @@ -98,7 +98,7 @@ namespace OpenSim.Framework.Servers.HttpServer bool AddXmlRPCHandler(string method, XmlRpcMethod handler, bool keepAlive); bool AddJsonRPCHandler(string method, JsonRPCMethod handler); - + /// /// Websocket HTTP server handlers. /// @@ -108,7 +108,7 @@ namespace OpenSim.Framework.Servers.HttpServer void RemoveWebSocketHandler(string servicepath); - + /// /// Gets the XML RPC handler for given method name /// @@ -125,7 +125,7 @@ namespace OpenSim.Framework.Servers.HttpServer // /// // /// // bool RemoveAgentHandler(string agent, IHttpAgentHandler handler); - + /// /// Remove an HTTP handler /// @@ -134,15 +134,15 @@ namespace OpenSim.Framework.Servers.HttpServer void RemoveHTTPHandler(string httpMethod, string path); void RemovePollServiceHTTPHandler(string httpMethod, string path); - + bool RemoveLLSDHandler(string path, LLSDMethod handler); - + void RemoveStreamHandler(string httpMethod, string path); void RemoveXmlRPCHandler(string method); void RemoveJsonRPCHandler(string method); - + string GetHTTP404(string host); string GetHTTP500(); diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs index b8541cb..62d92fb 100644 --- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs @@ -83,7 +83,7 @@ namespace OpenSim.Framework.Servers.HttpServer { void Handle(string path, Stream request, Stream response, IOSHttpRequest httpReqbuest, IOSHttpResponse httpResponse); } - + public interface IGenericHTTPHandler : IRequestHandler { Hashtable Handle(string path, Hashtable request); diff --git a/OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs index 2fe1a7d..411ee31 100644 --- a/OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs @@ -43,7 +43,7 @@ namespace OpenSim.Framework.Servers.HttpServer public class JsonRpcRequestManager { static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + public JsonRpcRequestManager() { } @@ -77,6 +77,9 @@ namespace OpenSim.Framework.Servers.HttpServer if (parameters == null) throw new ArgumentNullException("parameters"); + if(string.IsNullOrWhiteSpace(uri)) + return false; + OSDMap request = new OSDMap(); request.Add("jsonrpc", OSD.FromString("2.0")); request.Add("id", OSD.FromString(jsonId)); @@ -185,6 +188,6 @@ namespace OpenSim.Framework.Servers.HttpServer return true; } - + } } diff --git a/OpenSim/Framework/Servers/HttpServer/JsonRpcResponse.cs b/OpenSim/Framework/Servers/HttpServer/JsonRpcResponse.cs index 2c50587..91d284b 100644 --- a/OpenSim/Framework/Servers/HttpServer/JsonRpcResponse.cs +++ b/OpenSim/Framework/Servers/HttpServer/JsonRpcResponse.cs @@ -144,7 +144,7 @@ namespace OpenSim.Framework.Servers.HttpServer { } - return result; + return result; } } } diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs index 05ec6dc..1a6b8cf 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs @@ -155,11 +155,11 @@ namespace OpenSim.Framework.Servers.HttpServer private string _userAgent; internal IHttpRequest IHttpRequest - { + { get { return _request; } } - internal IHttpClientContext IHttpClientContext + internal IHttpClientContext IHttpClientContext { get { return _context; } } @@ -192,19 +192,19 @@ namespace OpenSim.Framework.Servers.HttpServer // ignore } } - + if (null != req.Headers["content-type"]) _contentType = _request.Headers["content-type"]; if (null != req.Headers["user-agent"]) _userAgent = req.Headers["user-agent"]; - + if (null != req.Headers["remote_addr"]) { try { IPAddress addr = IPAddress.Parse(req.Headers["remote_addr"]); // sometimes req.Headers["remote_port"] returns a comma separated list, so use - // the first one in the list and log it + // the first one in the list and log it string[] strPorts = req.Headers["remote_port"].Split(new char[] { ',' }); if (strPorts.Length > 1) { @@ -216,7 +216,7 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (FormatException) { - _log.ErrorFormat("[OSHttpRequest]: format exception on addr/port {0}:{1}, ignoring", + _log.ErrorFormat("[OSHttpRequest]: format exception on addr/port {0}:{1}, ignoring", req.Headers["remote_addr"], req.Headers["remote_port"]); } } diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs index 89fb5d4..d7744fc 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs @@ -115,7 +115,7 @@ namespace OpenSim.Framework.Servers.HttpServer public bool KeepAlive { - get + get { return _httpResponse.Connection == ConnectionType.KeepAlive; } @@ -148,6 +148,7 @@ namespace OpenSim.Framework.Servers.HttpServer _httpResponse.Connection = ConnectionType.Close; _httpResponse.KeepAlive = 0; } + else { _httpResponse.Connection = ConnectionType.KeepAlive; @@ -320,6 +321,7 @@ namespace OpenSim.Framework.Servers.HttpServer public void Send() { _httpResponse.Body.Flush(); + _httpResponse.Send(); } diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs index a736c8b..88e3068 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs @@ -91,7 +91,7 @@ namespace OpenSim.Framework.Servers.HttpServer /// 300 Redirect: different presentation forms available, take a pick /// RedirectMultipleChoices = 300, - + /// /// 301 Redirect: requested resource has moved and now lives somewhere else /// diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs index 9477100..7150aad 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs @@ -46,13 +46,15 @@ namespace OpenSim.Framework.Servers.HttpServer public RequestMethod Request; public UUID Id; public int TimeOutms; - public EventType Type; + public EventType Type; public enum EventType : int { - LongPoll = 0, + Poll = 0, LslHttp = 1, - Inventory = 2 + Inventory = 2, + Texture = 3, + Mesh = 4 } public string Url { get; set; } @@ -80,7 +82,7 @@ namespace OpenSim.Framework.Servers.HttpServer NoEvents = pNoEvents; Id = pId; TimeOutms = pTimeOutms; - Type = EventType.LongPoll; + Type = EventType.Poll; } } } diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs index caf0e98..fefcb20 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs @@ -27,6 +27,7 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Reflection; using System.Text; using HttpServer; @@ -44,6 +45,24 @@ namespace OpenSim.Framework.Servers.HttpServer public readonly IHttpRequest Request; public readonly int RequestTime; public readonly UUID RequestID; + public int contextHash; + + private void GenContextHash() + { + Random rnd = new Random(); + contextHash = 0; + if (Request.Headers["remote_addr"] != null) + contextHash = (Request.Headers["remote_addr"]).GetHashCode() << 16; + else + contextHash = rnd.Next() << 16; + if (Request.Headers["remote_port"] != null) + { + string[] strPorts = Request.Headers["remote_port"].Split(new char[] { ',' }); + contextHash += Int32.Parse(strPorts[0]); + } + else + contextHash += rnd.Next() & 0xffff; + } public PollServiceHttpRequest( PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) @@ -53,6 +72,7 @@ namespace OpenSim.Framework.Servers.HttpServer Request = pRequest; RequestTime = System.Environment.TickCount; RequestID = UUID.Random(); + GenContextHash(); } internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata) @@ -62,36 +82,69 @@ namespace OpenSim.Framework.Servers.HttpServer byte[] buffer = server.DoHTTPGruntWork(responsedata, response); + if(Request.Body.CanRead) + Request.Body.Dispose(); + response.SendChunked = false; response.ContentLength64 = buffer.Length; response.ContentEncoding = Encoding.UTF8; + response.ReuseContext = false; try { response.OutputStream.Write(buffer, 0, buffer.Length); + response.OutputStream.Flush(); + response.Send(); + buffer = null; } catch (Exception ex) { m_log.Warn("[POLL SERVICE WORKER THREAD]: Error ", ex); } - finally + + PollServiceArgs.RequestsHandled++; + } + + internal void DoHTTPstop(BaseHttpServer server) + { + OSHttpResponse response + = new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext); + + if(Request.Body.CanRead) + Request.Body.Dispose(); + + response.SendChunked = false; + response.ContentLength64 = 0; + response.ContentEncoding = Encoding.UTF8; + response.ReuseContext = false; + response.KeepAlive = false; + response.SendChunked = false; + response.StatusCode = 503; + + try { - //response.OutputStream.Close(); - try - { - response.OutputStream.Flush(); - response.Send(); - - //if (!response.KeepAlive && response.ReuseContext) - // response.FreeContext(); - } - catch (Exception e) - { - m_log.Warn("[POLL SERVICE WORKER THREAD]: Error ", e); - } - - PollServiceArgs.RequestsHandled++; + response.OutputStream.Flush(); + response.Send(); } + catch (Exception e) + { + } + } + } + + class PollServiceHttpRequestComparer : IEqualityComparer + { + public bool Equals(PollServiceHttpRequest b1, PollServiceHttpRequest b2) + { + if (b1.contextHash != b2.contextHash) + return false; + bool b = Object.ReferenceEquals(b1.HttpContext, b2.HttpContext); + return b; + } + + public int GetHashCode(PollServiceHttpRequest b2) + { + return (int)b2.contextHash; } } } \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index 28bba70..c6a3e65 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs @@ -44,200 +44,183 @@ namespace OpenSim.Framework.Servers.HttpServer { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - /// - /// Is the poll service request manager running? - /// - /// - /// Can be running either synchronously or asynchronously - /// - public bool IsRunning { get; private set; } - - /// - /// Is the poll service performing responses asynchronously (with its own threads) or synchronously (via - /// external calls)? - /// - public bool PerformResponsesAsync { get; private set; } - - /// - /// Number of responses actually processed and sent to viewer (or aborted due to error). - /// - public int ResponsesProcessed { get; private set; } - private readonly BaseHttpServer m_server; + private Dictionary> m_bycontext; private BlockingQueue m_requests = new BlockingQueue(); - private static List m_longPollRequests = new List(); + private static Queue m_retryRequests = new Queue(); private uint m_WorkerThreadCount = 0; private Thread[] m_workerThreads; + private Thread m_retrysThread; - private SmartThreadPool m_threadPool = new SmartThreadPool(20000, 12, 2); + private bool m_running = false; -// private int m_timeout = 1000; // increase timeout 250; now use the event one + private SmartThreadPool m_threadPool; public PollServiceRequestManager( BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout) { m_server = pSrv; - PerformResponsesAsync = performResponsesAsync; m_WorkerThreadCount = pWorkerThreadCount; m_workerThreads = new Thread[m_WorkerThreadCount]; - StatsManager.RegisterStat( - new Stat( - "QueuedPollResponses", - "Number of poll responses queued for processing.", - "", - "", - "httpserver", - m_server.Port.ToString(), - StatType.Pull, - MeasuresOfInterest.AverageChangeOverTime, - stat => stat.Value = m_requests.Count(), - StatVerbosity.Debug)); - - StatsManager.RegisterStat( - new Stat( - "ProcessedPollResponses", - "Number of poll responses processed.", - "", - "", - "httpserver", - m_server.Port.ToString(), - StatType.Pull, - MeasuresOfInterest.AverageChangeOverTime, - stat => stat.Value = ResponsesProcessed, - StatVerbosity.Debug)); + PollServiceHttpRequestComparer preqCp = new PollServiceHttpRequestComparer(); + m_bycontext = new Dictionary>(preqCp); + + STPStartInfo startInfo = new STPStartInfo(); + startInfo.IdleTimeout = 30000; + startInfo.MaxWorkerThreads = 20; + startInfo.MinWorkerThreads = 1; + startInfo.ThreadPriority = ThreadPriority.Normal; + startInfo.StartSuspended = true; + startInfo.ThreadPoolName = "PoolService"; + + m_threadPool = new SmartThreadPool(startInfo); } public void Start() { - IsRunning = true; - - if (PerformResponsesAsync) + m_running = true; + m_threadPool.Start(); + //startup worker threads + for (uint i = 0; i < m_WorkerThreadCount; i++) { - //startup worker threads - for (uint i = 0; i < m_WorkerThreadCount; i++) - { - m_workerThreads[i] - = WorkManager.StartThread( - PoolWorkerJob, - string.Format("PollServiceWorkerThread{0}:{1}", i, m_server.Port), - ThreadPriority.Normal, - false, - false, - null, - int.MaxValue); - } - - WorkManager.StartThread( - this.CheckLongPollThreads, - string.Format("LongPollServiceWatcherThread:{0}", m_server.Port), - ThreadPriority.Normal, - false, - true, - null, - 1000 * 60 * 10); + m_workerThreads[i] + = WorkManager.StartThread( + PoolWorkerJob, + string.Format("PollServiceWorkerThread {0}:{1}", i, m_server.Port), + ThreadPriority.Normal, + true, + false, + null, + int.MaxValue); } + + m_retrysThread = WorkManager.StartThread( + this.CheckRetries, + string.Format("PollServiceWatcherThread:{0}", m_server.Port), + ThreadPriority.Normal, + true, + true, + null, + 1000 * 60 * 10); + + } private void ReQueueEvent(PollServiceHttpRequest req) { - if (IsRunning) + if (m_running) { - // delay the enqueueing for 100ms. There's no need to have the event - // actively on the queue - Timer t = new Timer(self => { - ((Timer)self).Dispose(); - m_requests.Enqueue(req); - }); - - t.Change(100, Timeout.Infinite); - + lock (m_retryRequests) + m_retryRequests.Enqueue(req); } } public void Enqueue(PollServiceHttpRequest req) { - if (IsRunning) + lock (m_bycontext) { - if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) + Queue ctxQeueue; + if (m_bycontext.TryGetValue(req, out ctxQeueue)) { - lock (m_longPollRequests) - m_longPollRequests.Add(req); + ctxQeueue.Enqueue(req); } else - m_requests.Enqueue(req); + { + ctxQeueue = new Queue(); + m_bycontext[req] = ctxQeueue; + EnqueueInt(req); + } } } - private void CheckLongPollThreads() + public void byContextDequeue(PollServiceHttpRequest req) { - // The only purpose of this thread is to check the EQs for events. - // If there are events, that thread will be placed in the "ready-to-serve" queue, m_requests. - // If there are no events, that thread will be back to its "waiting" queue, m_longPollRequests. - // All other types of tasks (Inventory handlers, http-in, etc) don't have the long-poll nature, - // so if they aren't ready to be served by a worker thread (no events), they are placed - // directly back in the "ready-to-serve" queue by the worker thread. - while (IsRunning) + Queue ctxQeueue; + lock (m_bycontext) { - Thread.Sleep(500); - Watchdog.UpdateThread(); - -// List not_ready = new List(); - lock (m_longPollRequests) + if (m_bycontext.TryGetValue(req, out ctxQeueue)) { - if (m_longPollRequests.Count > 0 && IsRunning) + if (ctxQeueue.Count > 0) + { + PollServiceHttpRequest newreq = ctxQeueue.Dequeue(); + EnqueueInt(newreq); + } + else { - List ready = m_longPollRequests.FindAll(req => - (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id) || // there are events in this EQ - (Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) // no events, but timeout - ); + m_bycontext.Remove(req); + } + } + } + } - ready.ForEach(req => - { - m_requests.Enqueue(req); - m_longPollRequests.Remove(req); - }); + public void EnqueueInt(PollServiceHttpRequest req) + { + if (m_running) + m_requests.Enqueue(req); + } - } + private void CheckRetries() + { + while (m_running) + { + Thread.Sleep(100); // let the world move .. back to faster rate + Watchdog.UpdateThread(); + lock (m_retryRequests) + { + while (m_retryRequests.Count > 0 && m_running) + m_requests.Enqueue(m_retryRequests.Dequeue()); } } } public void Stop() { - IsRunning = false; -// m_timeout = -10000; // cause all to expire - Thread.Sleep(1000); // let the world move + m_running = false; + + Thread.Sleep(100); // let the world move foreach (Thread t in m_workerThreads) Watchdog.AbortThread(t.ManagedThreadId); - PollServiceHttpRequest wreq; + m_threadPool.Shutdown(); + + // any entry in m_bycontext should have a active request on the other queues + // so just delete contents to easy GC + foreach (Queue qu in m_bycontext.Values) + qu.Clear(); + m_bycontext.Clear(); - lock (m_longPollRequests) + try + { + foreach (PollServiceHttpRequest req in m_retryRequests) + { + req.DoHTTPstop(m_server); + } + } + catch { - if (m_longPollRequests.Count > 0 && IsRunning) - m_longPollRequests.ForEach(req => m_requests.Enqueue(req)); } + PollServiceHttpRequest wreq; + + m_retryRequests.Clear(); + while (m_requests.Count() > 0) { try { wreq = m_requests.Dequeue(0); - ResponsesProcessed++; - wreq.DoHTTPGruntWork( - m_server, wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id)); + wreq.DoHTTPstop(m_server); } catch { } } - m_longPollRequests.Clear(); m_requests.Clear(); } @@ -245,87 +228,69 @@ namespace OpenSim.Framework.Servers.HttpServer private void PoolWorkerJob() { - while (IsRunning) + while (m_running) { + PollServiceHttpRequest req = m_requests.Dequeue(4500); Watchdog.UpdateThread(); - WaitPerformResponse(); - } - } - - public void WaitPerformResponse() - { - PollServiceHttpRequest req = m_requests.Dequeue(5000); -// m_log.DebugFormat("[YYY]: Dequeued {0}", (req == null ? "null" : req.PollServiceArgs.Type.ToString())); - - if (req != null) - { - try + if (req != null) { - if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) + try { - Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id); - - if (responsedata == null) - return; - - // This is the event queue. - // Even if we're not running we can still perform responses by explicit request. - if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll - || !PerformResponsesAsync) - { - try - { - ResponsesProcessed++; - req.DoHTTPGruntWork(m_server, responsedata); - } - catch (ObjectDisposedException e) // Browser aborted before we could read body, server closed the stream - { - // Ignore it, no need to reply - m_log.Error(e); - } - } - else + if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) { + Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id); + m_threadPool.QueueWorkItem(x => { try { - ResponsesProcessed++; req.DoHTTPGruntWork(m_server, responsedata); } - catch (ObjectDisposedException e) // Browser aborted before we could read body, server closed the stream + catch (ObjectDisposedException) { - // Ignore it, no need to reply - m_log.Error(e); } - catch (Exception e) + finally { - m_log.Error(e); + byContextDequeue(req); } - return null; }, null); } - } - else - { - if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) - { - ResponsesProcessed++; - req.DoHTTPGruntWork( - m_server, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); - } else { - ReQueueEvent(req); + if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) + { + m_threadPool.QueueWorkItem(x => + { + try + { + req.DoHTTPGruntWork(m_server, + req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); + } + catch (ObjectDisposedException) + { + // Ignore it, no need to reply + } + finally + { + byContextDequeue(req); + } + return null; + }, null); + } + else + { + ReQueueEvent(req); + } } } - } - catch (Exception e) - { - m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); + catch (Exception e) + { + m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); + } } } } + } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs b/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs index 5e630dc..9b663ba 100644 --- a/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs @@ -2,7 +2,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("OpenSim.Framework.Servers.HttpServer")] @@ -14,8 +14,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] @@ -25,9 +25,9 @@ using System.Runtime.InteropServices; // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("0.8.3.*")] +[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] diff --git a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs index bd55657..67fc14e 100644 --- a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs @@ -54,6 +54,8 @@ namespace OpenSim.Framework.Servers.HttpServer TRequest deserial; using (XmlTextReader xmlReader = new XmlTextReader(request)) { + xmlReader.ProhibitDtd = true; + XmlSerializer deserializer = new XmlSerializer(typeof (TRequest)); deserial = (TRequest) deserializer.Deserialize(xmlReader); } diff --git a/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs b/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs index ad69cd2..158befa 100644 --- a/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs +++ b/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs @@ -210,6 +210,8 @@ namespace OpenSim.Framework.Servers.HttpServer { try { + xmlReader.ProhibitDtd = true; + XmlSerializer deserializer = new XmlSerializer(typeof(RestSessionObject)); deserial = (RestSessionObject)deserializer.Deserialize(xmlReader); } @@ -269,6 +271,8 @@ namespace OpenSim.Framework.Servers.HttpServer { try { + xmlReader.ProhibitDtd = true; + XmlSerializer deserializer = new XmlSerializer(typeof(TRequest)); deserial = (TRequest)deserializer.Deserialize(xmlReader); } @@ -291,5 +295,5 @@ namespace OpenSim.Framework.Servers.HttpServer serializer.Serialize(xmlWriter, response); } } - } + } } \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs index 0305dee..dfc2715 100644 --- a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs @@ -50,11 +50,10 @@ namespace OpenSim.Framework.Servers.HttpServer protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { + string requestBody; Encoding encoding = Encoding.UTF8; - StreamReader streamReader = new StreamReader(request, encoding); - - string requestBody = streamReader.ReadToEnd(); - streamReader.Close(); + using(StreamReader streamReader = new StreamReader(request,encoding)) + requestBody = streamReader.ReadToEnd(); string param = GetParam(path); string responseString = m_restMethod(requestBody, path, param, httpRequest, httpResponse); diff --git a/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs b/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs index c2925e3..c8af90f 100644 --- a/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs @@ -75,7 +75,7 @@ namespace OpenSim.Framework.Servers.HttpServer public event PongDelegate OnPong; /// - /// This is a regular HTTP Request... This may be removed in the future. + /// This is a regular HTTP Request... This may be removed in the future. /// // public event RegularHttpRequestDelegate OnRegularHttpRequest; @@ -93,9 +93,9 @@ namespace OpenSim.Framework.Servers.HttpServer /// When the websocket is closed, this will be fired. /// public event CloseDelegate OnClose; - + /// - /// Set this delegate to allow your module to validate the origin of the + /// Set this delegate to allow your module to validate the origin of the /// Websocket request. Primary line of defense against cross site scripting /// public ValidateHandshake HandshakeValidateMethodOverride = null; @@ -181,7 +181,7 @@ namespace OpenSim.Framework.Servers.HttpServer { throw new InvalidOperationException("The socket has been shutdown"); } - } + } set { if (_networkContext != null && _networkContext.Socket != null) @@ -194,8 +194,8 @@ namespace OpenSim.Framework.Servers.HttpServer } /// - /// This triggers the websocket to start the upgrade process... - /// This is a Generalized Networking 'common sense' helper method. Some people expect to call Start() instead + /// This triggers the websocket to start the upgrade process... + /// This is a Generalized Networking 'common sense' helper method. Some people expect to call Start() instead /// of the more context appropriate HandshakeAndUpgrade() /// public void Start() @@ -261,7 +261,7 @@ namespace OpenSim.Framework.Servers.HttpServer acceptKey = GenerateAcceptKey(websocketKey); string rawaccept = string.Format(HandshakeAcceptText, acceptKey); SendUpgradeSuccess(rawaccept); - + } else @@ -282,7 +282,7 @@ namespace OpenSim.Framework.Servers.HttpServer } /// - /// Generates a handshake response key string based on the client's + /// Generates a handshake response key string based on the client's /// provided key to prove to the client that we're allowing the Websocket /// upgrade of our own free will and we were not coerced into doing it. /// @@ -298,7 +298,7 @@ namespace OpenSim.Framework.Servers.HttpServer SHA1 hashobj = SHA1.Create(); string ret = Convert.ToBase64String(hashobj.ComputeHash(Encoding.UTF8.GetBytes(acceptkey))); hashobj.Clear(); - + return ret; } @@ -310,11 +310,11 @@ namespace OpenSim.Framework.Servers.HttpServer { // Create a new websocket state so we can keep track of data in between network reads. WebSocketState socketState = new WebSocketState() { ReceivedBytes = new List(), Header = WebsocketFrameHeader.HeaderDefault(), FrameComplete = true}; - + byte[] bhandshakeResponse = Encoding.UTF8.GetBytes(pHandshakeResponse); - - + + try { @@ -324,7 +324,7 @@ namespace OpenSim.Framework.Servers.HttpServer } // Begin reading the TCP stream before writing the Upgrade success message to the other side of the stream. _networkContext.Stream.BeginRead(_buffer, 0, _bufferLength, OnReceive, socketState); - + // Write the upgrade handshake success message _networkContext.Stream.Write(bhandshakeResponse, 0, bhandshakeResponse.Length); _networkContext.Stream.Flush(); @@ -345,7 +345,7 @@ namespace OpenSim.Framework.Servers.HttpServer catch (ObjectDisposedException) { Close(string.Empty); - } + } } /// @@ -369,7 +369,7 @@ namespace OpenSim.Framework.Servers.HttpServer /// /// This is our ugly Async OnReceive event handler. - /// This chunks the input stream based on the length of the provided buffer and processes out + /// This chunks the input stream based on the length of the provided buffer and processes out /// as many frames as it can. It then moves the unprocessed data to the beginning of the buffer. /// /// Our Async State from beginread @@ -390,7 +390,7 @@ namespace OpenSim.Framework.Servers.HttpServer if (_bufferPosition > _bufferLength) { - // Message too big for chunksize.. not sure how this happened... + // Message too big for chunksize.. not sure how this happened... //Close(string.Empty); } @@ -413,7 +413,7 @@ namespace OpenSim.Framework.Servers.HttpServer if (pheader.PayloadLen > (ulong) _maxPayloadBytes) { Close("Invalid Payload size"); - + return; } if (pheader.PayloadLen > 0) @@ -487,7 +487,7 @@ namespace OpenSim.Framework.Servers.HttpServer _socketState.ReceivedBytes.Clear(); _socketState.ExpectedBytes = 0; // do some processing - } + } } } if (offset > 0) @@ -504,7 +504,7 @@ namespace OpenSim.Framework.Servers.HttpServer } else { - // We can't read the stream anymore... + // We can't read the stream anymore... } } catch (IOException) @@ -533,7 +533,7 @@ namespace OpenSim.Framework.Servers.HttpServer textMessageFrame.Header.Opcode = WebSocketReader.OpCode.Text; textMessageFrame.Header.IsEnd = true; SendSocket(textMessageFrame.ToBytes()); - + } public void SendData(byte[] data) @@ -657,7 +657,7 @@ namespace OpenSim.Framework.Servers.HttpServer SendSocket(pongFrame.ToBytes()); break; case WebSocketReader.OpCode.Pong: - + PongDelegate pongD = OnPong; if (pongD != null) { @@ -701,7 +701,7 @@ namespace OpenSim.Framework.Servers.HttpServer { textD(this, new WebsocketTextEventArgs() { Data = Encoding.UTF8.GetString(psocketState.ReceivedBytes.ToArray()) }); } - + // Send Done Event! } break; @@ -719,7 +719,7 @@ namespace OpenSim.Framework.Servers.HttpServer { if (psocketState.ContinuationFrame.Header.Opcode == WebSocketReader.OpCode.Text) { - // Send Done event + // Send Done event TextDelegate textD = OnText; if (textD != null) { @@ -744,9 +744,9 @@ namespace OpenSim.Framework.Servers.HttpServer break; case WebSocketReader.OpCode.Close: Close(string.Empty); - + break; - + } psocketState.Header.SetDefault(); psocketState.ReceivedBytes.Clear(); @@ -837,12 +837,12 @@ namespace OpenSim.Framework.Servers.HttpServer } /// - /// Attempts to read a header off the provided buffer. Returns true, exports a WebSocketFrameheader, + /// Attempts to read a header off the provided buffer. Returns true, exports a WebSocketFrameheader, /// and an int to move the buffer forward when it reads a header. False when it can't read a header /// /// Bytes read from the stream /// Starting place in the stream to begin trying to read from - /// Lenth in the stream to try and read from. Provided for cases where the + /// Lenth in the stream to try and read from. Provided for cases where the /// buffer's length is larger then the data in it /// Outputs the read WebSocket frame header /// Informs the calling stream to move the buffer forward @@ -897,7 +897,7 @@ namespace OpenSim.Framework.Servers.HttpServer oHeader.PayloadLen = BitConverter.ToUInt16(pBuffer, pOffset + index); index += 2; break; - case 127: // we got more this is a bigger frame + case 127: // we got more this is a bigger frame // 8 bytes - uint64 - most significant bit 0 network byte order minumheadersize += 8; if (length < minumheadersize) @@ -909,7 +909,7 @@ namespace OpenSim.Framework.Servers.HttpServer oHeader.PayloadLen = BitConverter.ToUInt64(pBuffer, pOffset + index); index += 8; break; - + } //oHeader.PayloadLeft = oHeader.PayloadLen; // Start the count in case it's chunked over the network. This is different then frame fragmentation if (oHeader.IsMasked) @@ -937,9 +937,9 @@ namespace OpenSim.Framework.Servers.HttpServer /* * RFC6455 nib 0 1 2 3 4 5 6 7 -byt 0 1 2 3 -dec 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +byt 0 1 2 3 +dec 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) + @@ -963,7 +963,7 @@ dec 0 1 2 3 public static readonly WebSocketFrame DefaultFrame = new WebSocketFrame(){Header = new WebsocketFrameHeader(),WebSocketPayload = new byte[0]}; public WebsocketFrameHeader Header; public byte[] WebSocketPayload; - + public byte[] ToBytes() { Header.PayloadLen = (ulong)WebSocketPayload.Length; @@ -991,7 +991,7 @@ dec 0 1 2 3 public int Mask; /* byt 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +---------------+---------------+---------------+---------------+ | Octal 1 | Octal 2 | Octal 3 | Octal 4 | +---------------+---------------+---------------+---------------+ @@ -1002,11 +1002,11 @@ byt 0 1 2 3 public UInt64 PayloadLen; //public UInt64 PayloadLeft; - // Payload is X + Y + // Payload is X + Y //public UInt64 ExtensionDataLength; //public UInt64 ApplicationDataLength; public static readonly WebsocketFrameHeader ZeroHeader = WebsocketFrameHeader.HeaderDefault(); - + public void SetDefault() { @@ -1025,16 +1025,16 @@ byt 0 1 2 3 /// /// Returns a byte array representing the Frame header /// - /// This is the frame data payload. The header describes the size of the payload. + /// This is the frame data payload. The header describes the size of the payload. /// If payload is null, a Zero sized payload is assumed /// Returns a byte array representing the frame header public byte[] ToBytes(byte[] payload) { List result = new List(); - + // Squeeze in our opcode and our ending bit. result.Add((byte)((byte)Opcode | (IsEnd?0x80:0x00) )); - + // Again with the three different byte interpretations of size.. //bytesize @@ -1056,7 +1056,7 @@ byt 0 1 2 3 Array.Reverse(payloadLengthByte); result.AddRange(payloadLengthByte); } - + // Only add a payload if it's not null if (payload != null) { @@ -1155,5 +1155,5 @@ byt 0 1 2 3 } - + } diff --git a/OpenSim/Framework/Servers/HttpServer/XmlRpcBasicDOSProtector.cs b/OpenSim/Framework/Servers/HttpServer/XmlRpcBasicDOSProtector.cs index f212208..6b2c0ab 100644 --- a/OpenSim/Framework/Servers/HttpServer/XmlRpcBasicDOSProtector.cs +++ b/OpenSim/Framework/Servers/HttpServer/XmlRpcBasicDOSProtector.cs @@ -36,7 +36,7 @@ namespace OpenSim.Framework.Servers.HttpServer { private readonly XmlRpcMethod _normalMethod; private readonly XmlRpcMethod _throttledMethod; - + private readonly BasicDosProtectorOptions _options; private readonly BasicDOSProtector _dosProtector; @@ -44,7 +44,7 @@ namespace OpenSim.Framework.Servers.HttpServer { _normalMethod = normalMethod; _throttledMethod = throttledMethod; - + _options = options; _dosProtector = new BasicDOSProtector(_options); @@ -87,5 +87,5 @@ namespace OpenSim.Framework.Servers.HttpServer } - + } diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs index 57931d4..9b1d906 100644 --- a/OpenSim/Framework/Servers/MainServer.cs +++ b/OpenSim/Framework/Servers/MainServer.cs @@ -223,11 +223,11 @@ namespace OpenSim.Framework.Servers { handlers.AppendFormat( "Registered HTTP Handlers for server at {0}:{1}\n", httpServer.ListenIPAddress, httpServer.Port); - + handlers.AppendFormat("* XMLRPC:\n"); foreach (String s in httpServer.GetXmlRpcHandlerKeys()) handlers.AppendFormat("\t{0}\n", s); - + handlers.AppendFormat("* HTTP:\n"); foreach (String s in httpServer.GetHTTPHandlerKeys()) handlers.AppendFormat("\t{0}\n", s); @@ -235,19 +235,19 @@ namespace OpenSim.Framework.Servers handlers.AppendFormat("* HTTP (poll):\n"); foreach (String s in httpServer.GetPollServiceHandlerKeys()) handlers.AppendFormat("\t{0}\n", s); - + handlers.AppendFormat("* JSONRPC:\n"); foreach (String s in httpServer.GetJsonRpcHandlerKeys()) handlers.AppendFormat("\t{0}\n", s); - + // handlers.AppendFormat("* Agent:\n"); // foreach (String s in httpServer.GetAgentHandlerKeys()) // handlers.AppendFormat("\t{0}\n", s); - + handlers.AppendFormat("* LLSD:\n"); foreach (String s in httpServer.GetLLSDHandlerKeys()) handlers.AppendFormat("\t{0}\n", s); - + handlers.AppendFormat("* StreamHandlers ({0}):\n", httpServer.GetStreamHandlerKeys().Count); foreach (String s in httpServer.GetStreamHandlerKeys()) handlers.AppendFormat("\t{0}\n", s); @@ -334,7 +334,7 @@ namespace OpenSim.Framework.Servers { if (port == 0) return Instance; - + if (instance != null && port == Instance.Port) return Instance; @@ -353,5 +353,17 @@ namespace OpenSim.Framework.Servers return m_Servers[port]; } } + + public static void Stop() + { + lock (m_Servers) + { + foreach (BaseHttpServer httpServer in m_Servers.Values) + { + httpServer.Stop(); + } + } + } + } } \ No newline at end of file diff --git a/OpenSim/Framework/Servers/Properties/AssemblyInfo.cs b/OpenSim/Framework/Servers/Properties/AssemblyInfo.cs index 792c62e..4469e7c 100644 --- a/OpenSim/Framework/Servers/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Servers/Properties/AssemblyInfo.cs @@ -2,7 +2,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("OpenSim.Framework.Servers")] @@ -14,8 +14,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] @@ -25,7 +25,7 @@ using System.Runtime.InteropServices; // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs index 07a09e6..3c2dce8 100644 --- a/OpenSim/Framework/Servers/ServerBase.cs +++ b/OpenSim/Framework/Servers/ServerBase.cs @@ -56,7 +56,8 @@ namespace OpenSim.Framework.Servers protected ICommandConsole m_console; protected OpenSimAppender m_consoleAppender; - protected FileAppender m_logFileAppender; + protected FileAppender m_logFileAppender; + protected FileAppender m_statsLogFileAppender; protected DateTime m_startuptime; protected string m_startupDirectory = Environment.CurrentDirectory; @@ -81,7 +82,7 @@ namespace OpenSim.Framework.Servers { if (File.Exists(path)) m_log.ErrorFormat( - "[SERVER BASE]: Previous pid file {0} still exists on startup. Possibly previously unclean shutdown.", + "[SERVER BASE]: Previous pid file {0} still exists on startup. Possibly previously unclean shutdown.", path); try @@ -103,7 +104,7 @@ namespace OpenSim.Framework.Servers m_log.Warn(string.Format("[SERVER BASE]: Could not create PID file at {0} ", path), e); } } - + protected void RemovePIDFile() { if (m_pidFile != String.Empty) @@ -156,6 +157,10 @@ namespace OpenSim.Framework.Servers { m_logFileAppender = (FileAppender)appender; } + else if (appender.Name == "StatsLogFileAppender") + { + m_statsLogFileAppender = (FileAppender)appender; + } } if (null == m_consoleAppender) @@ -166,11 +171,11 @@ namespace OpenSim.Framework.Servers { // FIXME: This should be done through an interface rather than casting. m_consoleAppender.Console = (ConsoleBase)m_console; - + // If there is no threshold set then the threshold is effectively everything. if (null == m_consoleAppender.Threshold) m_consoleAppender.Threshold = Level.All; - + Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); } @@ -185,6 +190,18 @@ namespace OpenSim.Framework.Servers m_log.InfoFormat("[SERVER BASE]: Logging started to file {0}", m_logFileAppender.File); } + + if (m_statsLogFileAppender != null && startupConfig != null) + { + string cfgStatsFileName = startupConfig.GetString("StatsLogFile", null); + if (cfgStatsFileName != null) + { + m_statsLogFileAppender.File = cfgStatsFileName; + m_statsLogFileAppender.ActivateOptions(); + } + + m_log.InfoFormat("[SERVER BASE]: Stats Logging started to file {0}", m_statsLogFileAppender.File); + } } /// @@ -205,11 +222,11 @@ namespace OpenSim.Framework.Servers "General", false, "show uptime", "show uptime", "Show server uptime", HandleShow); m_console.Commands.AddCommand( - "General", false, "get log level", "get log level", "Get the current console logging level", + "General", false, "get log level", "get log level", "Get the current console logging level", (mod, cmd) => ShowLogLevel()); m_console.Commands.AddCommand( - "General", false, "set log level", "set log level ", + "General", false, "set log level", "set log level ", "Set the console logging level for this session.", HandleSetLogLevel); m_console.Commands.AddCommand( @@ -222,14 +239,14 @@ namespace OpenSim.Framework.Servers "config get [
] []", "Synonym for config show", HandleConfig); - + m_console.Commands.AddCommand( "General", false, "config show", "config show [
] []", - "Show config information", + "Show config information", "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine + "If a section is given but not a field, then all fields in that section are printed.", - HandleConfig); + HandleConfig); m_console.Commands.AddCommand( "General", false, "config save", @@ -258,18 +275,6 @@ namespace OpenSim.Framework.Servers (string module, string[] args) => Notice(GetThreadsReport())); m_console.Commands.AddCommand ( - "Debug", false, "debug comms set", - "debug comms set serialosdreq true|false", - "Set comms parameters. For debug purposes.", - HandleDebugCommsSet); - - m_console.Commands.AddCommand ( - "Debug", false, "debug comms status", - "debug comms status", - "Show current debug comms parameters.", - HandleDebugCommsStatus); - - m_console.Commands.AddCommand ( "Debug", false, "debug threadpool set", "debug threadpool set worker|iocp min|max ", "Set threadpool parameters. For debug purposes.", @@ -280,7 +285,7 @@ namespace OpenSim.Framework.Servers "debug threadpool status", "Show current debug threadpool parameters.", HandleDebugThreadpoolStatus); - + m_console.Commands.AddCommand( "Debug", false, "debug threadpool level", "debug threadpool level 0.." + Util.MAX_THREADPOOL_LEVEL, @@ -326,47 +331,13 @@ namespace OpenSim.Framework.Servers public void RegisterCommonComponents(IConfigSource configSource) { - IConfig networkConfig = configSource.Configs["Network"]; +// IConfig networkConfig = configSource.Configs["Network"]; - if (networkConfig != null) - { - WebUtil.SerializeOSDRequestsPerEndpoint = networkConfig.GetBoolean("SerializeOSDRequests", false); - } - m_serverStatsCollector = new ServerStatsCollector(); m_serverStatsCollector.Initialise(configSource); m_serverStatsCollector.Start(); } - private void HandleDebugCommsStatus(string module, string[] args) - { - Notice("serialosdreq is {0}", WebUtil.SerializeOSDRequestsPerEndpoint); - } - - private void HandleDebugCommsSet(string module, string[] args) - { - if (args.Length != 5) - { - Notice("Usage: debug comms set serialosdreq true|false"); - return; - } - - if (args[3] != "serialosdreq") - { - Notice("Usage: debug comms set serialosdreq true|false"); - return; - } - - bool setSerializeOsdRequests; - - if (!ConsoleUtil.TryParseConsoleBool(m_console, args[4], out setSerializeOsdRequests)) - return; - - WebUtil.SerializeOSDRequestsPerEndpoint = setSerializeOsdRequests; - - Notice("serialosdreq is now {0}", setSerializeOsdRequests); - } - private void HandleShowThreadpoolCallsActive(string module, string[] args) { List> calls = Util.GetFireAndForgetCallsInProgress().ToList(); @@ -432,7 +403,7 @@ namespace OpenSim.Framework.Servers ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads); Notice("Available worker threads: {0}", workerThreads); - Notice("Available IOCP threads: {0}", iocpThreads); + Notice("Available IOCP threads: {0}", iocpThreads); } private void HandleDebugThreadpoolSet(string module, string[] args) @@ -488,7 +459,7 @@ namespace OpenSim.Framework.Servers fail = true; } } - + if (fail) { Notice("ERROR: Could not set {0} {1} threads to {2}", poolType, bound, newThreads); @@ -582,7 +553,7 @@ namespace OpenSim.Framework.Servers if (cmdparams.Length > 0) { string firstParam = cmdparams[0].ToLower(); - + switch (firstParam) { case "set": @@ -633,12 +604,12 @@ namespace OpenSim.Framework.Servers { Notice("[{0}]", config.Name); foreach (string key in config.GetKeys()) - Notice(" {0} = {1}", key, config.GetString(key)); + Notice(" {0} = {1}", key, config.GetString(key)); } else { Notice( - "config get {0} {1} : {2}", + "config get {0} {1} : {2}", cmdparams[1], cmdparams[2], config.GetString(cmdparams[2])); } } @@ -692,10 +663,10 @@ namespace OpenSim.Framework.Servers } string rawLevel = cmd[3]; - + ILoggerRepository repository = LogManager.GetRepository(); Level consoleLevel = repository.LevelMap[rawLevel]; - + if (consoleLevel != null) m_consoleAppender.Threshold = consoleLevel; else @@ -770,9 +741,9 @@ namespace OpenSim.Framework.Servers protected void ShowInfo() { Notice(GetVersionText()); - Notice("Startup directory: " + m_startupDirectory); + Notice("Startup directory: " + m_startupDirectory); if (null != m_consoleAppender) - Notice(String.Format("Console log level: {0}", m_consoleAppender.Threshold)); + Notice(String.Format("Console log level: {0}", m_consoleAppender.Threshold)); } /// @@ -842,7 +813,7 @@ namespace OpenSim.Framework.Servers { StreamReader RevisionFile = File.OpenText(svnRevisionFileName); buildVersion = RevisionFile.ReadLine(); - buildVersion.Trim(); + buildVersion = buildVersion.Trim(); RevisionFile.Close(); } @@ -871,9 +842,9 @@ namespace OpenSim.Framework.Servers } } - protected string GetVersionText() + public string GetVersionText() { - return String.Format("Version: {0} (SIMULATION/{1} - SIMULATION/{2})", + return String.Format("Version: {0} (SIMULATION/{1} - SIMULATION/{2})", m_version, VersionInfo.SimulationServiceVersionSupportedMin, VersionInfo.SimulationServiceVersionSupportedMax); } @@ -898,7 +869,7 @@ namespace OpenSim.Framework.Servers foreach (Watchdog.ThreadWatchdogInfo twi in threads) { Thread t = twi.Thread; - + sb.AppendFormat( reportFormat, t.ManagedThreadId, @@ -911,16 +882,12 @@ namespace OpenSim.Framework.Servers sb.Append("\n"); } - sb.Append("\n"); + sb.Append(GetThreadPoolReport()); - // For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting - // zero active threads. + sb.Append("\n"); int totalThreads = Process.GetCurrentProcess().Threads.Count; if (totalThreads > 0) - sb.AppendFormat("Total threads active: {0}\n\n", totalThreads); - - sb.Append("Main threadpool (excluding script engine pools)\n"); - sb.Append(GetThreadPoolReport()); + sb.AppendFormat("Total process threads active: {0}\n\n", totalThreads); return sb.ToString(); } @@ -931,15 +898,46 @@ namespace OpenSim.Framework.Servers /// public static string GetThreadPoolReport() { + + StringBuilder sb = new StringBuilder(); + + // framework pool is alwasy active + int maxWorkers; + int minWorkers; + int curWorkers; + int maxComp; + int minComp; + int curComp; + + try + { + ThreadPool.GetMaxThreads(out maxWorkers, out maxComp); + ThreadPool.GetMinThreads(out minWorkers, out minComp); + ThreadPool.GetAvailableThreads(out curWorkers, out curComp); + curWorkers = maxWorkers - curWorkers; + curComp = maxComp - curComp; + + sb.Append("\nFramework main threadpool \n"); + sb.AppendFormat("workers: {0} ({1} / {2})\n", curWorkers, maxWorkers, minWorkers); + sb.AppendFormat("Completion: {0} ({1} / {2})\n", curComp, maxComp, minComp); + } + catch { } + + if ( + Util.FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem + || Util.FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem) + { + sb.AppendFormat("\nThread pool used: Framework main threadpool\n"); + return sb.ToString(); + } + string threadPoolUsed = null; int maxThreads = 0; int minThreads = 0; int allocatedThreads = 0; int inUseThreads = 0; int waitingCallbacks = 0; - int completionPortThreads = 0; - StringBuilder sb = new StringBuilder(); if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) { STPInfo stpi = Util.GetSmartThreadPoolInfo(); @@ -955,22 +953,10 @@ namespace OpenSim.Framework.Servers waitingCallbacks = stpi.WaitingCallbacks; } } - else if ( - Util.FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem - || Util.FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem) - { - threadPoolUsed = "BuiltInThreadPool"; - ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads); - ThreadPool.GetMinThreads(out minThreads, out completionPortThreads); - int availableThreads; - ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads); - inUseThreads = maxThreads - availableThreads; - allocatedThreads = -1; - waitingCallbacks = -1; - } - + if (threadPoolUsed != null) { + sb.Append("\nThreadpool (excluding script engine pools)\n"); sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed); sb.AppendFormat("Max threads : {0}\n", maxThreads); sb.AppendFormat("Min threads : {0}\n", minThreads); @@ -1005,7 +991,7 @@ namespace OpenSim.Framework.Servers MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId); else MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId); - } + } /// /// Console output is only possible if a console has been established. @@ -1020,13 +1006,13 @@ namespace OpenSim.Framework.Servers m_console.Output(msg); } } - + /// /// Console output is only possible if a console has been established. /// That is something that cannot be determined within this class. So /// all attempts to use the console MUST be verified. /// - /// + /// /// protected void Notice(string format, params object[] components) { diff --git a/OpenSim/Framework/Servers/Tests/OSHttpTests.cs b/OpenSim/Framework/Servers/Tests/OSHttpTests.cs index 5c0e0df..e5f7043 100644 --- a/OpenSim/Framework/Servers/Tests/OSHttpTests.cs +++ b/OpenSim/Framework/Servers/Tests/OSHttpTests.cs @@ -39,9 +39,331 @@ using OpenSim.Tests.Common; namespace OpenSim.Framework.Servers.Tests { +/* + [TestFixture] public class OSHttpTests : OpenSimTestCase - { + { + // we need an IHttpClientContext for our tests + public class TestHttpClientContext: IHttpClientContext + { + private bool _secured; + public bool IsSecured + { + get { return _secured; } + } + public bool Secured + { + get { return _secured; } + } + + public TestHttpClientContext(bool secured) + { + _secured = secured; + } + + public void Disconnect(SocketError error) {} + public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body) {} + public void Respond(string httpVersion, HttpStatusCode statusCode, string reason) {} + public void Respond(string body) {} + public void Send(byte[] buffer) {} + public void Send(byte[] buffer, int offset, int size) {} + public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body, string contentType) {} + public void Close() { } + public bool EndWhenDone { get { return false;} set { return;}} + + public HTTPNetworkContext GiveMeTheNetworkStreamIKnowWhatImDoing() + { + return new HTTPNetworkContext(); + } + + public event EventHandler Disconnected = delegate { }; + /// + /// A request have been received in the context. + /// + public event EventHandler RequestReceived = delegate { }; + + public bool CanSend { get { return true; } } + public string RemoteEndPoint { get { return ""; } } + public string RemoteEndPointAddress { get { return ""; } } + public string RemoteEndPointPort { get { return ""; } } + } + + public class TestHttpRequest: IHttpRequest + { + private string _uriPath; + public bool BodyIsComplete + { + get { return true; } + } + public string[] AcceptTypes + { + get {return _acceptTypes; } + } + private string[] _acceptTypes; + public Stream Body + { + get { return _body; } + set { _body = value;} + } + private Stream _body; + public ConnectionType Connection + { + get { return _connection; } + set { _connection = value; } + } + private ConnectionType _connection; + public int ContentLength + { + get { return _contentLength; } + set { _contentLength = value; } + } + private int _contentLength; + public NameValueCollection Headers + { + get { return _headers; } + } + private NameValueCollection _headers = new NameValueCollection(); + public string HttpVersion + { + get { return _httpVersion; } + set { _httpVersion = value; } + } + private string _httpVersion = null; + public string Method + { + get { return _method; } + set { _method = value; } + } + private string _method = null; + public HttpInput QueryString + { + get { return _queryString; } + } + private HttpInput _queryString = null; + public Uri Uri + { + get { return _uri; } + set { _uri = value; } + } + private Uri _uri = null; + public string[] UriParts + { + get { return _uri.Segments; } + } + public HttpParam Param + { + get { return null; } + } + public HttpForm Form + { + get { return null; } + } + public bool IsAjax + { + get { return false; } + } + public RequestCookies Cookies + { + get { return null; } + } + + public TestHttpRequest() {} + + public TestHttpRequest(string contentEncoding, string contentType, string userAgent, + string remoteAddr, string remotePort, string[] acceptTypes, + ConnectionType connectionType, int contentLength, Uri uri) + { + _headers["content-encoding"] = contentEncoding; + _headers["content-type"] = contentType; + _headers["user-agent"] = userAgent; + _headers["remote_addr"] = remoteAddr; + _headers["remote_port"] = remotePort; + + _acceptTypes = acceptTypes; + _connection = connectionType; + _contentLength = contentLength; + _uri = uri; + } + + public void DecodeBody(FormDecoderProvider providers) {} + public void SetCookies(RequestCookies cookies) {} + public void AddHeader(string name, string value) + { + _headers.Add(name, value); + } + public int AddToBody(byte[] bytes, int offset, int length) + { + return 0; + } + public void Clear() {} + + public object Clone() + { + TestHttpRequest clone = new TestHttpRequest(); + clone._acceptTypes = _acceptTypes; + clone._connection = _connection; + clone._contentLength = _contentLength; + clone._uri = _uri; + clone._headers = new NameValueCollection(_headers); + + return clone; + } + public IHttpResponse CreateResponse(IHttpClientContext context) + { + return new HttpResponse(context, this); + } + /// + /// Path and query (will be merged with the host header) and put in Uri + /// + /// + public string UriPath + { + get { return _uriPath; } + set + { + _uriPath = value; + + } + } + + } + + public class TestHttpResponse: IHttpResponse + { + public Stream Body + { + get { return _body; } + + set { _body = value; } + } + private Stream _body; + + public string ProtocolVersion + { + get { return _protocolVersion; } + set { _protocolVersion = value; } + } + private string _protocolVersion; + + public bool Chunked + { + get { return _chunked; } + + set { _chunked = value; } + } + private bool _chunked; + + public ConnectionType Connection + { + get { return _connection; } + + set { _connection = value; } + } + private ConnectionType _connection; + + public Encoding Encoding + { + get { return _encoding; } + + set { _encoding = value; } + } + private Encoding _encoding; + + public int KeepAlive + { + get { return _keepAlive; } + + set { _keepAlive = value; } + } + private int _keepAlive; + + public HttpStatusCode Status + { + get { return _status; } + + set { _status = value; } + } + private HttpStatusCode _status; + + public string Reason + { + get { return _reason; } + + set { _reason = value; } + } + private string _reason; + + public long ContentLength + { + get { return _contentLength; } + + set { _contentLength = value; } + } + private long _contentLength; + + public string ContentType + { + get { return _contentType; } + + set { _contentType = value; } + } + private string _contentType; + + public bool HeadersSent + { + get { return _headersSent; } + } + private bool _headersSent; + + public bool Sent + { + get { return _sent; } + } + private bool _sent; + + public ResponseCookies Cookies + { + get { return _cookies; } + } + private ResponseCookies _cookies = null; + + public TestHttpResponse() + { + _headersSent = false; + _sent = false; + } + + public void AddHeader(string name, string value) {} + public void Send() + { + if (!_headersSent) SendHeaders(); + if (_sent) throw new InvalidOperationException("stuff already sent"); + _sent = true; + } + + public void SendBody(byte[] buffer, int offset, int count) + { + if (!_headersSent) SendHeaders(); + _sent = true; + } + public void SendBody(byte[] buffer) + { + if (!_headersSent) SendHeaders(); + _sent = true; + } + + public void SendHeaders() + { + if (_headersSent) throw new InvalidOperationException("headers already sent"); + _headersSent = true; + } + + public void Redirect(Uri uri) {} + public void Redirect(string url) {} + } + + public OSHttpRequest req0; public OSHttpRequest req1; @@ -52,22 +374,22 @@ namespace OpenSim.Framework.Servers.Tests [TestFixtureSetUp] public void Init() { - TestHttpRequest threq0 = new TestHttpRequest("utf-8", "text/xml", "OpenSim Test Agent", "192.168.0.1", "4711", - new string[] {"text/xml"}, - ConnectionType.KeepAlive, 4711, + TestHttpRequest threq0 = new TestHttpRequest("utf-8", "text/xml", "OpenSim Test Agent", "192.168.0.1", "4711", + new string[] {"text/xml"}, + ConnectionType.KeepAlive, 4711, new Uri("http://127.0.0.1/admin/inventory/Dr+Who/Tardis")); threq0.Method = "GET"; threq0.HttpVersion = HttpHelper.HTTP10; - TestHttpRequest threq1 = new TestHttpRequest("utf-8", "text/xml", "OpenSim Test Agent", "192.168.0.1", "4711", - new string[] {"text/xml"}, - ConnectionType.KeepAlive, 4711, + TestHttpRequest threq1 = new TestHttpRequest("utf-8", "text/xml", "OpenSim Test Agent", "192.168.0.1", "4711", + new string[] {"text/xml"}, + ConnectionType.KeepAlive, 4711, new Uri("http://127.0.0.1/admin/inventory/Dr+Who/Tardis?a=0&b=1&c=2")); threq1.Method = "POST"; threq1.HttpVersion = HttpHelper.HTTP11; threq1.Headers["x-wuff"] = "wuffwuff"; threq1.Headers["www-authenticate"] = "go away"; - + req0 = new OSHttpRequest(new TestHttpClientContext(false), threq0); req1 = new OSHttpRequest(new TestHttpClientContext(false), threq1); @@ -113,4 +435,5 @@ namespace OpenSim.Framework.Servers.Tests Assert.That(rsp0.ContentType, Is.EqualTo("text/xml")); } } -} \ No newline at end of file +*/ +} diff --git a/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs b/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs index 2d72cb8..480f2bb 100644 --- a/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs +++ b/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs @@ -47,7 +47,7 @@ namespace OpenSim.Framework.Servers.Tests { foreach (VersionInfo.Flavour flavour in Enum.GetValues(typeof(VersionInfo.Flavour))) { - Assert.AreEqual(VersionInfo.VERSIONINFO_VERSION_LENGTH, VersionInfo.GetVersionString("0.0.0", "0", flavour).Length, "0.0.0/" + flavour + " failed"); + Assert.AreEqual(VersionInfo.VERSIONINFO_VERSION_LENGTH, VersionInfo.GetVersionString("0.0.0", flavour).Length, "0.0.0/" + flavour + " failed"); } } } diff --git a/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs b/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs index 512ac4f..9126cfb 100644 --- a/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs +++ b/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs @@ -56,7 +56,7 @@ namespace OpenSim.Framework.ServiceAuth { // remove_me = section; m_Username = Util.GetConfigVarFromSections(config, "HttpAuthUsername", new string[] { "Network", section }, string.Empty); - m_Password = Util.GetConfigVarFromSections(config, "HttpAuthPassword", new string[] { "Network", section }, string.Empty); + m_Password = Util.GetConfigVarFromSections(config, "HttpAuthPassword", new string[] { "Network", section }, string.Empty); string str = m_Username + ":" + m_Password; byte[] encData_byte = Util.UTF8.GetBytes(str); diff --git a/OpenSim/Framework/ServiceAuth/CompoundAuthentication.cs b/OpenSim/Framework/ServiceAuth/CompoundAuthentication.cs index a49952c..79d6ff4 100644 --- a/OpenSim/Framework/ServiceAuth/CompoundAuthentication.cs +++ b/OpenSim/Framework/ServiceAuth/CompoundAuthentication.cs @@ -56,7 +56,7 @@ namespace OpenSim.Framework.ServiceAuth m_authentications.Remove(auth); } - public void AddAuthorization(NameValueCollection headers) + public void AddAuthorization(NameValueCollection headers) { foreach (IServiceAuth auth in m_authentications) auth.AddAuthorization(headers); diff --git a/OpenSim/Framework/SimStats.cs b/OpenSim/Framework/SimStats.cs index 3d8f32f..f19a270 100644 --- a/OpenSim/Framework/SimStats.cs +++ b/OpenSim/Framework/SimStats.cs @@ -32,7 +32,7 @@ namespace OpenSim.Framework { /// /// Enapsulate statistics for a simulator/scene. - /// + /// /// TODO: This looks very much like the OpenMetaverse SimStatsPacket. It should be much more generic stats /// storage. /// @@ -49,25 +49,31 @@ namespace OpenSim.Framework get { return m_regionY; } } private uint m_regionY; - + public SimStatsPacket.RegionBlock RegionBlock { get { return m_regionBlock; } } private SimStatsPacket.RegionBlock m_regionBlock; - + public SimStatsPacket.StatBlock[] StatsBlock { get { return m_statsBlock; } } private SimStatsPacket.StatBlock[] m_statsBlock; - + + public SimStatsPacket.StatBlock[] ExtraStatsBlock + { + get { return m_extraStatsBlock; } + } + private SimStatsPacket.StatBlock[] m_extraStatsBlock; + public uint RegionFlags { get { return m_regionFlags; } } private uint m_regionFlags; - + public uint ObjectCapacity { get { return m_objectCapacity; } @@ -79,10 +85,11 @@ namespace OpenSim.Framework get { return regionUUID; } } private UUID regionUUID; - + public SimStats( - uint regionX, uint regionY, uint regionFlags, uint objectCapacity, - SimStatsPacket.RegionBlock regionBlock, SimStatsPacket.StatBlock[] statsBlock, UUID pRUUID) + uint regionX, uint regionY, uint regionFlags, uint objectCapacity, + SimStatsPacket.RegionBlock regionBlock, SimStatsPacket.StatBlock[] statsBlock, + SimStatsPacket.StatBlock[] ExtraStatsBlock, UUID pRUUID) { regionUUID = pRUUID; m_regionX = regionX; @@ -91,6 +98,7 @@ namespace OpenSim.Framework m_objectCapacity = objectCapacity; m_regionBlock = regionBlock; m_statsBlock = statsBlock; + m_extraStatsBlock = ExtraStatsBlock; } } } diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs index 8af2c41..223d91f 100644 --- a/OpenSim/Framework/TaskInventoryDictionary.cs +++ b/OpenSim/Framework/TaskInventoryDictionary.cs @@ -27,9 +27,13 @@ using System; using System.Collections.Generic; +using System.Threading; +using System.Reflection; using System.Xml; +using System.Diagnostics; using System.Xml.Schema; using System.Xml.Serialization; +using log4net; using OpenMetaverse; namespace OpenSim.Framework @@ -47,6 +51,187 @@ namespace OpenSim.Framework // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem)); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Thread LockedByThread; +// private string WriterStack; + +// private Dictionary ReadLockers = +// new Dictionary(); + + /// + /// An advanced lock for inventory data + /// + private volatile System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim(); + + + ~TaskInventoryDictionary() + { + m_itemLock.Dispose(); + m_itemLock = null; + } + + /// + /// Are we readlocked by the calling thread? + /// + public bool IsReadLockedByMe() + { + if (m_itemLock.RecursiveReadCount > 0) + { + return true; + } + else + { + return false; + } + } + + /// + /// Lock our inventory list for reading (many can read, one can write) + /// + public void LockItemsForRead(bool locked) + { + if (locked) + { + if (m_itemLock.IsWriteLockHeld && LockedByThread != null) + { + if (!LockedByThread.IsAlive) + { + //Locked by dead thread, reset. + m_itemLock = new System.Threading.ReaderWriterLockSlim(); + } + } + + if (m_itemLock.RecursiveReadCount > 0) + { + m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); + try + { + // That call stack is useful for end users only. RealProgrammers need a full dump. Commented. + // StackTrace stackTrace = new StackTrace(); // get call stack + // StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) + // + // // write call stack method names + // foreach (StackFrame stackFrame in stackFrames) + // { + // m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name + // } + + // The below is far more useful +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); +// System.Console.WriteLine("------------------------------------------"); +// foreach (KeyValuePair kvp in ReadLockers) +// { +// System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name); +// System.Console.WriteLine("------------------------------------------"); +// } + } + catch + {} + m_itemLock.ExitReadLock(); + } + if (m_itemLock.RecursiveWriteCount > 0) + { + m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed."); +// try +// { +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("Locker's call stack:\n" + WriterStack); +// System.Console.WriteLine("------------------------------------------"); +// } +// catch +// {} + m_itemLock.ExitWriteLock(); + } + + while (!m_itemLock.TryEnterReadLock(60000)) + { + m_log.Error("Thread lock detected while trying to aquire READ lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); + //if (m_itemLock.IsWriteLockHeld) + //{ + m_itemLock = new System.Threading.ReaderWriterLockSlim(); +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("Locker's call stack:\n" + WriterStack); +// System.Console.WriteLine("------------------------------------------"); +// LockedByThread = null; +// ReadLockers.Clear(); + //} + } +// ReadLockers[Thread.CurrentThread] = Environment.StackTrace; + } + else + { + if (m_itemLock.RecursiveReadCount>0) + { + m_itemLock.ExitReadLock(); + } +// if (m_itemLock.RecursiveReadCount == 0) +// ReadLockers.Remove(Thread.CurrentThread); + } + } + + /// + /// Lock our inventory list for writing (many can read, one can write) + /// + public void LockItemsForWrite(bool locked) + { + if (locked) + { + //Enter a write lock, wait indefinately for one to open. + if (m_itemLock.RecursiveReadCount > 0) + { + m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); + m_itemLock.ExitReadLock(); + } + if (m_itemLock.RecursiveWriteCount > 0) + { + m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed."); + + m_itemLock.ExitWriteLock(); + } + while (!m_itemLock.TryEnterWriteLock(60000)) + { + if (m_itemLock.IsWriteLockHeld) + { + m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("Locker's call stack:\n" + WriterStack); +// System.Console.WriteLine("------------------------------------------"); + } + else + { + m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by a reader. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); +// System.Console.WriteLine("------------------------------------------"); +// foreach (KeyValuePair kvp in ReadLockers) +// { +// System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name); +// System.Console.WriteLine("------------------------------------------"); +// } + } + m_itemLock = new System.Threading.ReaderWriterLockSlim(); +// ReadLockers.Clear(); + } + + LockedByThread = Thread.CurrentThread; +// WriterStack = Environment.StackTrace; + } + else + { + if (m_itemLock.RecursiveWriteCount > 0) + { + m_itemLock.ExitWriteLock(); + } + } + } #region ICloneable Members @@ -54,14 +239,13 @@ namespace OpenSim.Framework { TaskInventoryDictionary clone = new TaskInventoryDictionary(); - lock (this) + m_itemLock.EnterReadLock(); + foreach (UUID uuid in Keys) { - foreach (UUID uuid in Keys) - { - clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone()); - } + clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone()); } - + m_itemLock.ExitReadLock(); + return clone; } diff --git a/OpenSim/Framework/TaskInventoryItem.cs b/OpenSim/Framework/TaskInventoryItem.cs index 307cb75..1cc32b3 100644 --- a/OpenSim/Framework/TaskInventoryItem.cs +++ b/OpenSim/Framework/TaskInventoryItem.cs @@ -59,6 +59,7 @@ namespace OpenSim.Framework private int _invType = 0; private UUID _itemID = UUID.Zero; private UUID _lastOwnerID = UUID.Zero; + private UUID _rezzerID = UUID.Zero; private string _name = String.Empty; private uint _nextOwnerMask = FULL_MASK_PERMISSIONS_GENERAL; private UUID _ownerID = UUID.Zero; @@ -254,6 +255,16 @@ namespace OpenSim.Framework } } + public UUID RezzerID + { + get { + return _rezzerID; + } + set { + _rezzerID = value; + } + } + public string Name { get { return _name; diff --git a/OpenSim/Framework/TerrainData.cs b/OpenSim/Framework/TerrainData.cs index 6b1be4e..5cec2b5 100644 --- a/OpenSim/Framework/TerrainData.cs +++ b/OpenSim/Framework/TerrainData.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.IO.Compression; using System.Reflection; using OpenMetaverse; @@ -48,6 +49,7 @@ namespace OpenSim.Framework public abstract float this[int x, int y] { get; set; } // Someday terrain will have caves + // at most holes :p public abstract float this[int x, int y, int z] { get; set; } public abstract bool IsTaintedAt(int xx, int yy); @@ -72,8 +74,8 @@ namespace OpenSim.Framework return new HeightmapTerrainData(pSizeX, pSizeY, pSizeZ, pFormatCode, pBlob); } - // return a special compressed representation of the heightmap in ints - public abstract int[] GetCompressedMap(); + // return a special compressed representation of the heightmap in ushort + public abstract float[] GetCompressedMap(); public abstract float CompressionFactor { get; } public abstract float[] GetFloatsSerialized(); @@ -94,14 +96,18 @@ namespace OpenSim.Framework { // Terrain is 'double[256,256]' Legacy256 = 11, + // Terrain is 'int32, int32, float[,]' where the ints are X and Y dimensions // The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256. Variable2D = 22, + Variable2DGzip = 23, + // Terrain is 'int32, int32, int32, int16[]' where the ints are X and Y dimensions // and third int is the 'compression factor'. The heights are compressed as - // "int compressedHeight = (int)(height * compressionFactor);" + // "ushort compressedHeight = (ushort)(height * compressionFactor);" // The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256. Compressed2D = 27, + // A revision that is not listed above or any revision greater than this value is 'Legacy256'. RevisionHigh = 1234 } @@ -109,7 +115,7 @@ namespace OpenSim.Framework // Version of terrain that is a heightmap. // This should really be 'LLOptimizedHeightmapTerrainData' as it includes knowledge // of 'patches' which are 16x16 terrain areas which can be sent separately to the viewer. - // The heighmap is kept as an array of integers. The integer values are converted to + // The heighmap is kept as an array of ushorts. The ushort values are converted to // and from floats by TerrainCompressionFactor. public class HeightmapTerrainData : TerrainData { @@ -119,12 +125,12 @@ namespace OpenSim.Framework // TerrainData.this[x, y] public override float this[int x, int y] { - get { return FromCompressedHeight(m_heightmap[x, y]); } - set { - int newVal = ToCompressedHeight(value); - if (m_heightmap[x, y] != newVal) + get { return m_heightmap[x, y]; } + set + { + if (m_heightmap[x, y] != value) { - m_heightmap[x, y] = newVal; + m_heightmap[x, y] = value; m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = true; } } @@ -164,10 +170,9 @@ namespace OpenSim.Framework // TerrainData.ClearLand(float) public override void ClearLand(float pHeight) { - int flatHeight = ToCompressedHeight(pHeight); for (int xx = 0; xx < SizeX; xx++) for (int yy = 0; yy < SizeY; yy++) - m_heightmap[xx, yy] = flatHeight; + m_heightmap[xx, yy] = pHeight; } // Return 'true' of the patch that contains these region coordinates has been modified. @@ -177,13 +182,15 @@ namespace OpenSim.Framework { int tx = xx / Constants.TerrainPatchSize; int ty = yy / Constants.TerrainPatchSize; - bool ret = m_taint[tx, ty]; + bool ret = m_taint[tx, ty]; if (ret && clearOnTest) m_taint[tx, ty] = false; return ret; } // Old form that clears the taint flag when we check it. + // ubit: this dangerus naming should be only check without clear + // keeping for old modules outthere public override bool IsTaintedAt(int xx, int yy) { return IsTaintedAt(xx, yy, true /* clearOnTest */); @@ -194,6 +201,7 @@ namespace OpenSim.Framework public override bool GetDatabaseBlob(out int DBRevisionCode, out Array blob) { bool ret = false; +/* save all as Variable2DGzip if (SizeX == Constants.RegionSize && SizeY == Constants.RegionSize) { DBRevisionCode = (int)DBTerrainRevision.Legacy256; @@ -202,10 +210,13 @@ namespace OpenSim.Framework } else { - DBRevisionCode = (int)DBTerrainRevision.Compressed2D; - blob = ToCompressedTerrainSerialization(); +*/ + DBRevisionCode = (int)DBTerrainRevision.Variable2DGzip; +// DBRevisionCode = (int)DBTerrainRevision.Variable2D; + blob = ToCompressedTerrainSerializationV2DGzip(); +// blob = ToCompressedTerrainSerializationV2D(); ret = true; - } +// } return ret; } @@ -214,9 +225,9 @@ namespace OpenSim.Framework public override float CompressionFactor { get { return m_compressionFactor; } } // TerrainData.GetCompressedMap - public override int[] GetCompressedMap() + public override float[] GetCompressedMap() { - int[] newMap = new int[SizeX * SizeY]; + float[] newMap = new float[SizeX * SizeY]; int ind = 0; for (int xx = 0; xx < SizeX; xx++) @@ -230,7 +241,7 @@ namespace OpenSim.Framework public override TerrainData Clone() { HeightmapTerrainData ret = new HeightmapTerrainData(SizeX, SizeY, SizeZ); - ret.m_heightmap = (int[,])this.m_heightmap.Clone(); + ret.m_heightmap = (float[,])this.m_heightmap.Clone(); return ret; } @@ -247,7 +258,7 @@ namespace OpenSim.Framework for (int jj = 0; jj < SizeY; jj++) for (int ii = 0; ii < SizeX; ii++) { - heights[idx++] = FromCompressedHeight(m_heightmap[ii, jj]); + heights[idx++] = m_heightmap[ii, jj]; } return heights; @@ -259,7 +270,7 @@ namespace OpenSim.Framework double[,] ret = new double[SizeX, SizeY]; for (int xx = 0; xx < SizeX; xx++) for (int yy = 0; yy < SizeY; yy++) - ret[xx, yy] = FromCompressedHeight(m_heightmap[xx, yy]); + ret[xx, yy] = (double)m_heightmap[xx, yy]; return ret; } @@ -267,19 +278,40 @@ namespace OpenSim.Framework // ============================================================= - private int[,] m_heightmap; + private float[,] m_heightmap; // Remember subregions of the heightmap that has changed. private bool[,] m_taint; - // To save space (especially for large regions), keep the height as a short integer // that is coded as the float height times the compression factor (usually '100' // to make for two decimal points). - public int ToCompressedHeight(double pHeight) + public short ToCompressedHeightshort(float pHeight) { - return (int)(pHeight * CompressionFactor); + // clamp into valid range + pHeight *= CompressionFactor; + if (pHeight < short.MinValue) + return short.MinValue; + else if (pHeight > short.MaxValue) + return short.MaxValue; + return (short)pHeight; } - public float FromCompressedHeight(int pHeight) + public ushort ToCompressedHeightushort(float pHeight) + { + // clamp into valid range + pHeight *= CompressionFactor; + if (pHeight < ushort.MinValue) + return ushort.MinValue; + else if (pHeight > ushort.MaxValue) + return ushort.MaxValue; + return (ushort)pHeight; + } + + public float FromCompressedHeight(short pHeight) + { + return ((float)pHeight) / CompressionFactor; + } + + public float FromCompressedHeight(ushort pHeight) { return ((float)pHeight) / CompressionFactor; } @@ -293,12 +325,12 @@ namespace OpenSim.Framework SizeZ = (int)Constants.RegionHeight; m_compressionFactor = 100.0f; - m_heightmap = new int[SizeX, SizeY]; + m_heightmap = new float[SizeX, SizeY]; for (int ii = 0; ii < SizeX; ii++) { for (int jj = 0; jj < SizeY; jj++) { - m_heightmap[ii, jj] = ToCompressedHeight(pTerrain[ii, jj]); + m_heightmap[ii, jj] = (float)pTerrain[ii, jj]; } } @@ -315,14 +347,15 @@ namespace OpenSim.Framework SizeY = pY; SizeZ = pZ; m_compressionFactor = 100.0f; - m_heightmap = new int[SizeX, SizeY]; + m_heightmap = new float[SizeX, SizeY]; m_taint = new bool[SizeX / Constants.TerrainPatchSize, SizeY / Constants.TerrainPatchSize]; // m_log.DebugFormat("{0} new by dimensions. sizeX={1}, sizeY={2}, sizeZ={3}", LogHeader, SizeX, SizeY, SizeZ); ClearTaint(); ClearLand(0f); } - public HeightmapTerrainData(int[] cmap, float pCompressionFactor, int pX, int pY, int pZ) : this(pX, pY, pZ) + public HeightmapTerrainData(float[] cmap, float pCompressionFactor, int pX, int pY, int pZ) + : this(pX, pY, pZ) { m_compressionFactor = pCompressionFactor; int ind = 0; @@ -333,12 +366,22 @@ namespace OpenSim.Framework } // Create a heighmap from a database blob - public HeightmapTerrainData(int pSizeX, int pSizeY, int pSizeZ, int pFormatCode, byte[] pBlob) : this(pSizeX, pSizeY, pSizeZ) + public HeightmapTerrainData(int pSizeX, int pSizeY, int pSizeZ, int pFormatCode, byte[] pBlob) + : this(pSizeX, pSizeY, pSizeZ) { switch ((DBTerrainRevision)pFormatCode) { + case DBTerrainRevision.Variable2DGzip: + FromCompressedTerrainSerializationV2DGZip(pBlob); + m_log.DebugFormat("{0} HeightmapTerrainData create from Variable2DGzip serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY); + break; + + case DBTerrainRevision.Variable2D: + FromCompressedTerrainSerializationV2D(pBlob); + m_log.DebugFormat("{0} HeightmapTerrainData create from Variable2D serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY); + break; case DBTerrainRevision.Compressed2D: - FromCompressedTerrainSerialization(pBlob); + FromCompressedTerrainSerialization2D(pBlob); m_log.DebugFormat("{0} HeightmapTerrainData create from Compressed2D serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY); break; default: @@ -373,50 +416,116 @@ namespace OpenSim.Framework return ret; } - // Just create an array of doubles. Presumes the caller implicitly knows the size. + // Presumes the caller implicitly knows the size. public void FromLegacyTerrainSerialization(byte[] pBlob) { // In case database info doesn't match real terrain size, initialize the whole terrain. ClearLand(); - using (MemoryStream mstr = new MemoryStream(pBlob)) + try { - using (BinaryReader br = new BinaryReader(mstr)) + using (MemoryStream mstr = new MemoryStream(pBlob)) { - for (int xx = 0; xx < (int)Constants.RegionSize; xx++) + using (BinaryReader br = new BinaryReader(mstr)) { - for (int yy = 0; yy < (int)Constants.RegionSize; yy++) + for (int xx = 0; xx < (int)Constants.RegionSize; xx++) { - float val = (float)br.ReadDouble(); - if (xx < SizeX && yy < SizeY) - m_heightmap[xx, yy] = ToCompressedHeight(val); + for (int yy = 0; yy < (int)Constants.RegionSize; yy++) + { + float val = (float)br.ReadDouble(); + + if (xx < SizeX && yy < SizeY) + m_heightmap[xx, yy] = val; + } } } } - ClearTaint(); } + catch + { + ClearLand(); + } + ClearTaint(); + } + + + // stores as variable2D + // int32 sizeX + // int32 sizeY + // float[,] array + + public Array ToCompressedTerrainSerializationV2D() + { + Array ret = null; + try + { + using (MemoryStream str = new MemoryStream((2 * sizeof(Int32)) + (SizeX * SizeY * sizeof(float)))) + { + using (BinaryWriter bw = new BinaryWriter(str)) + { + bw.Write((Int32)SizeX); + bw.Write((Int32)SizeY); + for (int yy = 0; yy < SizeY; yy++) + for (int xx = 0; xx < SizeX; xx++) + { + // reduce to 1cm resolution + float val = (float)Math.Round(m_heightmap[xx, yy],2,MidpointRounding.ToEven); + bw.Write(val); + } + } + ret = str.ToArray(); + } + } + catch + { + + } + + m_log.DebugFormat("{0} V2D {1} bytes", + LogHeader, ret.Length); + + return ret; } - - // See the reader below. - public Array ToCompressedTerrainSerialization() + + // as above with Gzip compression + public Array ToCompressedTerrainSerializationV2DGzip() { Array ret = null; - using (MemoryStream str = new MemoryStream((3 * sizeof(Int32)) + (SizeX * SizeY * sizeof(Int16)))) + try { - using (BinaryWriter bw = new BinaryWriter(str)) + using (MemoryStream inp = new MemoryStream((2 * sizeof(Int32)) + (SizeX * SizeY * sizeof(float)))) { - bw.Write((Int32)DBTerrainRevision.Compressed2D); - bw.Write((Int32)SizeX); - bw.Write((Int32)SizeY); - bw.Write((Int32)CompressionFactor); - for (int yy = 0; yy < SizeY; yy++) - for (int xx = 0; xx < SizeX; xx++) + using (BinaryWriter bw = new BinaryWriter(inp)) + { + bw.Write((Int32)SizeX); + bw.Write((Int32)SizeY); + for (int yy = 0; yy < SizeY; yy++) + for (int xx = 0; xx < SizeX; xx++) + { + bw.Write((float)m_heightmap[xx, yy]); + } + + bw.Flush(); + inp.Seek(0, SeekOrigin.Begin); + + using (MemoryStream outputStream = new MemoryStream()) { - bw.Write((Int16)m_heightmap[xx, yy]); + using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress)) + { + inp.CopyStream(compressionStream, int.MaxValue); + compressionStream.Close(); + ret = outputStream.ToArray(); + } } + } } - ret = str.ToArray(); } + catch + { + + } + m_log.DebugFormat("{0} V2DGzip {1} bytes", + LogHeader, ret.Length); return ret; } @@ -426,7 +535,7 @@ namespace OpenSim.Framework // the forth int is the compression factor for the following int16s // This is just sets heightmap info. The actual size of the region was set on this instance's // creation and any heights not initialized by theis blob are set to the default height. - public void FromCompressedTerrainSerialization(byte[] pBlob) + public void FromCompressedTerrainSerialization2D(byte[] pBlob) { Int32 hmFormatCode, hmSizeX, hmSizeY, hmCompressionFactor; @@ -448,7 +557,7 @@ namespace OpenSim.Framework { for (int xx = 0; xx < hmSizeX; xx++) { - Int16 val = br.ReadInt16(); + float val = FromCompressedHeight(br.ReadInt16()); if (xx < SizeX && yy < SizeY) m_heightmap[xx, yy] = val; } @@ -456,9 +565,112 @@ namespace OpenSim.Framework } ClearTaint(); - m_log.InfoFormat("{0} Read compressed 2d heightmap. Heightmap size=<{1},{2}>. Region size=<{3},{4}>. CompFact={5}", + m_log.DebugFormat("{0} Read (compressed2D) heightmap. Heightmap size=<{1},{2}>. Region size=<{3},{4}>. CompFact={5}", LogHeader, hmSizeX, hmSizeY, SizeX, SizeY, hmCompressionFactor); } } + + // Initialize heightmap from blob consisting of: + // int32, int32, int32, float[] + // where the first int32 is format code, next two int32s are the X and y of heightmap data + // This is just sets heightmap info. The actual size of the region was set on this instance's + // creation and any heights not initialized by theis blob are set to the default height. + public void FromCompressedTerrainSerializationV2D(byte[] pBlob) + { + Int32 hmSizeX, hmSizeY; + try + { + using (MemoryStream mstr = new MemoryStream(pBlob)) + { + using (BinaryReader br = new BinaryReader(mstr)) + { + hmSizeX = br.ReadInt32(); + hmSizeY = br.ReadInt32(); + + // In case database info doesn't match real terrain size, initialize the whole terrain. + ClearLand(); + + for (int yy = 0; yy < hmSizeY; yy++) + { + for (int xx = 0; xx < hmSizeX; xx++) + { + float val = br.ReadSingle(); + if (xx < SizeX && yy < SizeY) + m_heightmap[xx, yy] = val; + } + } + } + } + } + catch (Exception e) + { + ClearTaint(); + m_log.ErrorFormat("{0} 2D error: {1} - terrain may be damaged", + LogHeader, e.Message); + return; + } + ClearTaint(); + + m_log.DebugFormat("{0} V2D Heightmap size=<{1},{2}>. Region size=<{3},{4}>", + LogHeader, hmSizeX, hmSizeY, SizeX, SizeY); + + } + + // as above but Gzip compressed + public void FromCompressedTerrainSerializationV2DGZip(byte[] pBlob) + { + m_log.InfoFormat("{0} VD2Gzip {1} bytes input", + LogHeader, pBlob.Length); + + Int32 hmSizeX, hmSizeY; + + try + { + using (MemoryStream outputStream = new MemoryStream()) + { + using (MemoryStream inputStream = new MemoryStream(pBlob)) + { + using (GZipStream decompressionStream = new GZipStream(inputStream, CompressionMode.Decompress)) + { + decompressionStream.Flush(); + decompressionStream.CopyTo(outputStream); + } + } + + outputStream.Seek(0, SeekOrigin.Begin); + + using (BinaryReader br = new BinaryReader(outputStream)) + { + hmSizeX = br.ReadInt32(); + hmSizeY = br.ReadInt32(); + + // In case database info doesn't match real terrain size, initialize the whole terrain. + ClearLand(); + + for (int yy = 0; yy < hmSizeY; yy++) + { + for (int xx = 0; xx < hmSizeX; xx++) + { + float val = br.ReadSingle(); + if (xx < SizeX && yy < SizeY) + m_heightmap[xx, yy] = val; + } + } + } + } + } + catch( Exception e) + { + ClearTaint(); + m_log.ErrorFormat("{0} V2DGzip error: {1} - terrain may be damaged", + LogHeader, e.Message); + return; + } + + ClearTaint(); + m_log.DebugFormat("{0} V2DGzip. Heightmap size=<{1},{2}>. Region size=<{3},{4}>", + LogHeader, hmSizeX, hmSizeY, SizeX, SizeY); + + } } } diff --git a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs index 95e9439..5ad0030 100644 --- a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs +++ b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs @@ -96,7 +96,7 @@ namespace OpenSim.Framework.Tests VisualParams[(int)AvatarAppearance.VPElement.SHAPE_FOOT_SIZE] = 45; - // head + // head VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HEAD_SIZE] = 255; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_SQUASH_STRETCH_HEAD] = 0; // head stretch VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HEAD_SHAPE] = 155; @@ -106,7 +106,7 @@ namespace OpenSim.Framework.Tests VisualParams[(int)AvatarAppearance.VPElement.SHAPE_FACE_SHEAR] = 127; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_FOREHEAD_ANGLE] = 104; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_BIG_BROW] = 94; - VisualParams[(int)AvatarAppearance.VPElement.SHAPE_PUFFY_UPPER_CHEEKS] = 0; // upper cheeks + VisualParams[(int)AvatarAppearance.VPElement.SHAPE_PUFFY_UPPER_CHEEKS] = 0; // upper cheeks VisualParams[(int)AvatarAppearance.VPElement.SHAPE_DOUBLE_CHIN] = 122; // lower cheeks VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HIGH_CHEEK_BONES] = 130; @@ -232,7 +232,7 @@ namespace OpenSim.Framework.Tests /// /// Test to ensure that the serialization format is the same and the underlying types don't change without notice /// oldSerialization is just a json serialization of the OSDMap packed for the AgentCircuitData. - /// The idea is that if the current json serializer cannot parse the old serialization, then the underlying types + /// The idea is that if the current json serializer cannot parse the old serialization, then the underlying types /// have changed and are incompatible. /// [Test] @@ -311,14 +311,15 @@ namespace OpenSim.Framework.Tests Agent1Data.SessionID = SessionId; Agent1Data.startpos = StartPos; + EntityTransferContext ctx = new EntityTransferContext(); OSDMap map2; - OSDMap map = Agent1Data.PackAgentCircuitData(); + OSDMap map = Agent1Data.PackAgentCircuitData(ctx); try { string str = OSDParser.SerializeJsonString(map); //System.Console.WriteLine(str); map2 = (OSDMap) OSDParser.DeserializeJson(str); - } + } catch (System.NullReferenceException) { //spurious litjson errors :P diff --git a/OpenSim/Framework/Tests/AgentCircuitManagerTests.cs b/OpenSim/Framework/Tests/AgentCircuitManagerTests.cs index ae132c8..b572afc 100644 --- a/OpenSim/Framework/Tests/AgentCircuitManagerTests.cs +++ b/OpenSim/Framework/Tests/AgentCircuitManagerTests.cs @@ -183,7 +183,7 @@ namespace OpenSim.Framework.Tests resp = agentCircuitManager.AuthenticateSession(UUID.Random(), AgentId1, circuitcode1); Assert.That(!resp.Authorised); - + resp = agentCircuitManager.AuthenticateSession(SessionId1, AgentId1, circuitcode2); Assert.That(!resp.Authorised); diff --git a/OpenSim/Framework/Tests/AnimationTests.cs b/OpenSim/Framework/Tests/AnimationTests.cs index d8f17d0..daf8611 100644 --- a/OpenSim/Framework/Tests/AnimationTests.cs +++ b/OpenSim/Framework/Tests/AnimationTests.cs @@ -84,7 +84,7 @@ namespace OpenSim.Framework.Tests anim4.AnimID = anim2.AnimID; anim4.ObjectID = anim2.ObjectID; anim4.SequenceNum = anim2.SequenceNum; - + Assert.That(anim4.ObjectID == objUUID2 && anim4.AnimID == animUUID2 && anim4.SequenceNum == 1, "void constructor and manual field population failed to set the properties correctly."); } } diff --git a/OpenSim/Framework/Tests/CacheTests.cs b/OpenSim/Framework/Tests/CacheTests.cs index c709860..a92ff3c 100644 --- a/OpenSim/Framework/Tests/CacheTests.cs +++ b/OpenSim/Framework/Tests/CacheTests.cs @@ -70,7 +70,7 @@ namespace OpenSim.Framework.Tests Assert.That(citem == null, "Item should not be in Cache"); } - + [Test] public void ExpireItemManually() { @@ -96,7 +96,7 @@ namespace OpenSim.Framework.Tests cachedItem.Store(foo); cache.Store(cacheItemUUID.ToString(), cachedItem); cache.Clear(); - + object citem = cache.Get(cacheItemUUID.ToString()); Assert.That(citem == null, "Item should not be in Cache because we manually invalidated it"); } diff --git a/OpenSim/Framework/Tests/LocationTest.cs b/OpenSim/Framework/Tests/LocationTest.cs index 3d5d1d2..5e84026 100644 --- a/OpenSim/Framework/Tests/LocationTest.cs +++ b/OpenSim/Framework/Tests/LocationTest.cs @@ -85,6 +85,6 @@ namespace OpenSim.Framework.Tests Assert.That(TestLocation2.Equals(cln), "Cloned object failed .Equals(obj) Test"); } - + } } diff --git a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs index 3f0a031..bde7056 100644 --- a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs +++ b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs @@ -110,13 +110,14 @@ namespace OpenSim.Framework.Tests && position2.Center == position1.Center && position2.RegionHandle == position1.RegionHandle && position2.Far == position1.Far - + ,"Copy From ChildAgentDataUpdate failed"); position2 = new AgentPosition(); Assert.IsFalse(position2.AgentID == position1.AgentID, "Test Error, position2 should be a blank uninitialized AgentPosition"); - position2.Unpack(position1.Pack(), null); + EntityTransferContext ctx = new EntityTransferContext(); + position2.Unpack(position1.Pack(ctx), null, ctx); Assert.IsTrue(position2.AgentID == position1.AgentID, "Agent ID didn't unpack the same way it packed"); Assert.IsTrue(position2.Position == position1.Position, "Position didn't unpack the same way it packed"); @@ -147,13 +148,13 @@ namespace OpenSim.Framework.Tests // string time = settings.LoadedCreationTime; Assert.That(m_RegionSettingsOnSaveEventFired, "RegionSettings Save Event didn't Fire"); - + } public void RegionSaveFired(RegionSettings settings) { m_RegionSettingsOnSaveEventFired = true; } - + [Test] public void InventoryItemBaseConstructorTest01() { @@ -163,7 +164,7 @@ namespace OpenSim.Framework.Tests UUID ItemID = UUID.Random(); UUID OwnerID = UUID.Random(); - + InventoryItemBase b2 = new InventoryItemBase(ItemID); Assert.That(b2.ID == ItemID, "ID constructor should create an inventory item with ID = ItemID"); Assert.That(b2.Owner == UUID.Zero, "ID constructor should create an inventory item with Owner = UUID.Zero"); @@ -218,12 +219,12 @@ namespace OpenSim.Framework.Tests BannedHostNameMask = string.Empty, BannedUserID = bannedUserId} ); - Assert.IsTrue(es.IsBanned(bannedUserId), "User Should be banned but is not."); - Assert.IsFalse(es.IsBanned(UUID.Zero), "User Should not be banned but is."); + Assert.IsTrue(es.IsBanned(bannedUserId, 32), "User Should be banned but is not."); + Assert.IsFalse(es.IsBanned(UUID.Zero, 32), "User Should not be banned but is."); es.RemoveBan(bannedUserId); - Assert.IsFalse(es.IsBanned(bannedUserId), "User Should not be banned but is."); + Assert.IsFalse(es.IsBanned(bannedUserId, 32), "User Should not be banned but is."); es.AddEstateManager(UUID.Zero); @@ -267,7 +268,7 @@ namespace OpenSim.Framework.Tests Assert.That(fld.ID == uuid1, "ID,Owner constructor failed to save value in ID field."); Assert.That(fld.Owner == uuid2, "ID,Owner constructor failed to save value in ID field."); } - + [Test] public void AsssetBaseConstructorTest01() { @@ -303,6 +304,6 @@ namespace OpenSim.Framework.Tests Culture.SetCurrentCulture(); Assert.That(Thread.CurrentThread.CurrentCulture.Name == ci.Name, "SetCurrentCulture failed to set thread culture to en-US"); - } + } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/Tests/PrimeNumberHelperTests.cs b/OpenSim/Framework/Tests/PrimeNumberHelperTests.cs index 82e13e5..cc30fb9 100644 --- a/OpenSim/Framework/Tests/PrimeNumberHelperTests.cs +++ b/OpenSim/Framework/Tests/PrimeNumberHelperTests.cs @@ -127,9 +127,9 @@ namespace OpenSim.Framework.Tests int[] nonprimes = { 4, 6, 8, 10, 14, 16, 18, 22, 28, 30, 36, 40, 42, 46, 52, 58, 60, 66, 70, 72, 78, 82, 88, - 96, 366, 372, 378, 382, 388, 396, 400, 408, 418, 420, 430, 432, 438, 442, 448, 456, 460, 462, - 466, 478, 486, 490, 498, 502, 508, 856, 858, 862, 876, 880, 882, 886, 906, 910, 918, 928, 936, - 940, 946, 952, 966, 970, 976, 982, 990, 996, 1008, 1740, 1746, 1752, 1758, 4650, 4656, 4662, + 96, 366, 372, 378, 382, 388, 396, 400, 408, 418, 420, 430, 432, 438, 442, 448, 456, 460, 462, + 466, 478, 486, 490, 498, 502, 508, 856, 858, 862, 876, 880, 882, 886, 906, 910, 918, 928, 936, + 940, 946, 952, 966, 970, 976, 982, 990, 996, 1008, 1740, 1746, 1752, 1758, 4650, 4656, 4662, 4672, 4678, 4690, 7740, 7752, 7756, 7758, 7788, 7792, 7816, 7822, 7828, 7840, 7852, 7866, 7872, 7876, 7878, 7882, 7900, 7906, 7918 }; diff --git a/OpenSim/Framework/Tests/UtilTest.cs b/OpenSim/Framework/Tests/UtilTest.cs index cfe3139..b3d79ee 100644 --- a/OpenSim/Framework/Tests/UtilTest.cs +++ b/OpenSim/Framework/Tests/UtilTest.cs @@ -59,12 +59,12 @@ namespace OpenSim.Framework.Tests Assert.That(Util.GetMagnitude(v2), new DoubleToleranceConstraint(expectedMagnitude, lowPrecisionTolerance), "Magnitude of vector was incorrect."); - +/* TestDelegate d = delegate() { Util.GetNormalizedVector(v1); }; bool causesArgumentException = TestHelpers.AssertThisDelegateCausesArgumentException(d); Assert.That(causesArgumentException, Is.True, "Getting magnitude of null vector did not cause argument exception."); - +*/ Vector3 expectedNormalizedVector = new Vector3(.577f, .577f, .577f); double expectedNormalizedMagnitude = 1; Vector3 normalizedVector = Util.GetNormalizedVector(v2); @@ -92,7 +92,7 @@ namespace OpenSim.Framework.Tests Assert.That(Util.GetMagnitude(v2), new DoubleToleranceConstraint(expectedMagnitude, lowPrecisionTolerance), "Magnitude of vector was incorrect."); - +/* TestDelegate d = delegate() { Util.GetNormalizedVector(v1); }; bool causesArgumentException = TestHelpers.AssertThisDelegateCausesArgumentException(d); Assert.That(causesArgumentException, Is.True, @@ -102,6 +102,7 @@ namespace OpenSim.Framework.Tests causesArgumentException = TestHelpers.AssertThisDelegateCausesArgumentException(d); Assert.That(causesArgumentException, Is.True, "Getting magnitude of null vector did not cause argument exception."); +*/ } //Lets test a simple case of <0,0,0> and <-5,-5,-5> @@ -120,12 +121,12 @@ namespace OpenSim.Framework.Tests Assert.That(Util.GetMagnitude(v2), new DoubleToleranceConstraint(expectedMagnitude, lowPrecisionTolerance), "Magnitude of vector was incorrect."); - +/* TestDelegate d = delegate() { Util.GetNormalizedVector(v1); }; bool causesArgumentException = TestHelpers.AssertThisDelegateCausesArgumentException(d); Assert.That(causesArgumentException, Is.True, "Getting magnitude of null vector did not cause argument exception."); - +*/ Vector3 expectedNormalizedVector = new Vector3(-.577f, -.577f, -.577f); double expectedNormalizedMagnitude = 1; Vector3 normalizedVector = Util.GetNormalizedVector(v2); @@ -232,7 +233,7 @@ namespace OpenSim.Framework.Tests "application/vnd.ll.clothing", "application/vnd.ll.gesture" }; - + for (int i=0;iNon-texture assets Asset = 6, + + HighPriority = 128, } [Flags] diff --git a/OpenSim/Framework/UserProfileData.cs b/OpenSim/Framework/UserProfileData.cs index 266ccf0..d8fa629 100644 --- a/OpenSim/Framework/UserProfileData.cs +++ b/OpenSim/Framework/UserProfileData.cs @@ -159,12 +159,12 @@ namespace OpenSim.Framework /// public virtual ulong HomeRegion { - get + get { return Util.RegionWorldLocToHandle(Util.RegionToWorldLoc(m_homeRegionX), Util.RegionToWorldLoc(m_homeRegionY)); - // return Utils.UIntsToLong( m_homeRegionX * (uint)Constants.RegionSize, m_homeRegionY * (uint)Constants.RegionSize); + // return Utils.UIntsToLong( m_homeRegionX * (uint)Constants.RegionSize, m_homeRegionY * (uint)Constants.RegionSize); } - + set { uint regionWorldLocX, regionWorldLocY; @@ -212,7 +212,7 @@ namespace OpenSim.Framework get { return m_surname; } set { m_surname = value; } } - + /// /// The concatentation of the various name components. /// diff --git a/OpenSim/Framework/UserProfiles.cs b/OpenSim/Framework/UserProfiles.cs index 98ab651..7c6a6fe 100644 --- a/OpenSim/Framework/UserProfiles.cs +++ b/OpenSim/Framework/UserProfiles.cs @@ -27,6 +27,8 @@ using System; using OpenMetaverse; +using System.Collections.Generic; + namespace OpenSim.Framework { @@ -48,7 +50,7 @@ namespace OpenSim.Framework public byte Flags = 0; public int Price = 0; } - + public class UserProfileProperties { public UUID UserId = UUID.Zero; @@ -66,7 +68,7 @@ namespace OpenSim.Framework public UUID FirstLifeImageId = UUID.Zero; public string FirstLifeText = string.Empty; } - + public class UserProfilePick { public UUID PickId = UUID.Zero; @@ -84,7 +86,7 @@ namespace OpenSim.Framework public int SortOrder = 0; public bool Enabled = false; } - + public class UserProfileNotes { public UUID UserId; @@ -99,7 +101,7 @@ namespace OpenSim.Framework public bool Visible = false; public string EMail = string.Empty; } - + public class UserAccountProperties { public string EmailAddress = string.Empty; @@ -108,13 +110,13 @@ namespace OpenSim.Framework public string Password = string.Empty; public string UserId = string.Empty; } - + public class UserAccountAuth { public string UserId = UUID.Zero.ToString(); public string Password = string.Empty; } - + public class UserAppData { public string TagId = string.Empty; @@ -122,5 +124,18 @@ namespace OpenSim.Framework public string UserId = UUID.Zero.ToString(); public string DataVal = string.Empty; } + + public class UserProfileCacheEntry + { + public Dictionary picksList; + public Dictionary picks; + public Dictionary classifiedsLists; + public Dictionary classifieds; + public UserProfileProperties props; + public string born; + public byte[] membershipType; + public uint flags; + public HashSet ClientsWaitingProps; + } } diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index b5c3e75..7093010 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -59,17 +59,41 @@ namespace OpenSim.Framework { [Flags] public enum PermissionMask : uint - { + { None = 0, - Transfer = 1 << 13, - Modify = 1 << 14, - Copy = 1 << 15, - Export = 1 << 16, - Move = 1 << 19, - Damage = 1 << 20, + + // folded perms + FoldedTransfer = 1, + FoldedModify = 1 << 1, + FoldedCopy = 1 << 2, + FoldedExport = 1 << 3, + + // DO NOT USE THIS FOR NEW WORK. IT IS DEPRECATED AND + // EXISTS ONLY TO REACT TO EXISTING OBJECTS HAVING IT. + // NEW CODE SHOULD NEVER SET THIS BIT! + // Use InventoryItemFlags.ObjectSlamPerm in the Flags field of + // this legacy slam bit. It comes from prior incomplete + // understanding of the code and the prohibition on + // reading viewer code that used to be in place. + Slam = (1 << 4), + + FoldedMask = 0x0f, + + FoldingShift = 13 , // number of bit shifts from normal perm to folded or back (same as Transfer shift below) + // when doing as a block + + Transfer = 1 << 13, // 0x02000 + Modify = 1 << 14, // 0x04000 + Copy = 1 << 15, // 0x08000 + Export = 1 << 16, // 0x10000 + Move = 1 << 19, // 0x80000 + Damage = 1 << 20, // 0x100000 does not seem to be in use // All does not contain Export, which is special and must be // explicitly given - All = (1 << 13) | (1 << 14) | (1 << 15) | (1 << 19) + All = 0x8e000, + AllAndExport = 0x9e000, + AllEffective = 0x9e000, + UnfoldedMask = 0x1e000 } /// @@ -103,7 +127,7 @@ namespace OpenSim.Framework public STPStartInfo STPStartInfo { get; set; } public WIGStartInfo WIGStartInfo { get; set; } public bool IsIdle { get; set; } - public bool IsShuttingDown { get; set; } + public bool IsShuttingDown { get; set; } public int MaxThreads { get; set; } public int MinThreads { get; set; } public int InUseThreads { get; set; } @@ -131,10 +155,16 @@ namespace OpenSim.Framework public static readonly int MAX_THREADPOOL_LEVEL = 3; + public static double TimeStampClockPeriodMS; + public static double TimeStampClockPeriod; + static Util() { LogThreadPool = 0; LogOverloads = true; + TimeStampClockPeriod = 1.0D/ (double)Stopwatch.Frequency; + TimeStampClockPeriodMS = 1e3 * TimeStampClockPeriod; + m_log.InfoFormat("[UTIL] TimeStamp clock with period of {0}ms", Math.Round(TimeStampClockPeriodMS,6,MidpointRounding.AwayFromZero)); } private static uint nextXferID = 5000; @@ -217,7 +247,7 @@ namespace OpenSim.Framework public static Encoding UTF8NoBomEncoding = new UTF8Encoding(false); /// - /// Well known UUID for the blank texture used in the Linden SL viewer version 1.20 (and hopefully onwards) + /// Well known UUID for the blank texture used in the Linden SL viewer version 1.20 (and hopefully onwards) /// public static UUID BLANK_TEXTURE_UUID = new UUID("5748decc-f629-461c-9a36-a35a221fe21f"); @@ -267,14 +297,12 @@ namespace OpenSim.Framework /// /// A 3d vector /// A new vector which is normalized form of the vector - /// The vector paramater cannot be <0,0,0> + public static Vector3 GetNormalizedVector(Vector3 a) { - if (IsZeroVector(a)) - throw new ArgumentException("Vector paramater cannot be a zero vector."); - - float Mag = (float) GetMagnitude(a); - return new Vector3(a.X / Mag, a.Y / Mag, a.Z / Mag); + Vector3 v = new Vector3(a.X, a.Y, a.Z); + v.Normalize(); + return v; } /// @@ -357,47 +385,185 @@ namespace OpenSim.Framework return Utils.UIntsToLong(X, Y); } - // Regions are identified with a 'handle' made up of its region coordinates packed into a ulong. - // Several places rely on the ability to extract a region's location from its handle. - // Note the location is in 'world coordinates' (see below). - // Region handles are based on the lowest coordinate of the region so trim the passed x,y to be the regions 0,0. + // Regions are identified with a 'handle' made up of its world coordinates packed into a ulong. + // Region handles are based on the coordinate of the region corner with lower X and Y + // var regions need more work than this to get that right corner from a generic world position + // this corner must be on a grid point public static ulong RegionWorldLocToHandle(uint X, uint Y) { - return Utils.UIntsToLong(X, Y); + ulong handle = X & 0xffffff00; // make sure it matchs grid coord points. + handle <<= 32; // to higher half + handle |= (Y & 0xffffff00); + return handle; } - public static ulong RegionLocToHandle(uint X, uint Y) + public static ulong RegionGridLocToHandle(uint X, uint Y) { - return Utils.UIntsToLong(Util.RegionToWorldLoc(X), Util.RegionToWorldLoc(Y)); + ulong handle = X; + handle <<= 40; // shift to higher half and mult by 256) + handle |= (Y << 8); // mult by 256) + return handle; } public static void RegionHandleToWorldLoc(ulong handle, out uint X, out uint Y) { X = (uint)(handle >> 32); - Y = (uint)(handle & (ulong)uint.MaxValue); + Y = (uint)(handle & 0xfffffffful); } public static void RegionHandleToRegionLoc(ulong handle, out uint X, out uint Y) { - uint worldX, worldY; - RegionHandleToWorldLoc(handle, out worldX, out worldY); - X = WorldToRegionLoc(worldX); - Y = WorldToRegionLoc(worldY); + X = (uint)(handle >> 40) & 0x00ffffffu; // bring from higher half, divide by 256 and clean + Y = (uint)(handle >> 8) & 0x00ffffffu; // divide by 256 and clean + // if you trust the uint cast then the clean can be removed. } - // A region location can be 'world coordinates' (meters from zero) or 'region coordinates' - // (number of regions from zero). This measurement of regions relies on the legacy 256 region size. - // These routines exist to make what is being converted explicit so the next person knows what was meant. - // Convert a region's 'world coordinate' to its 'region coordinate'. + // A region location can be 'world coordinates' (meters) or 'region grid coordinates' + // grid coordinates have a fixed step of 256m as defined by viewers public static uint WorldToRegionLoc(uint worldCoord) { - return worldCoord / Constants.RegionSize; + return worldCoord >> 8; } - // Convert a region's 'region coordinate' to its 'world coordinate'. + // Convert a region's 'region grid coordinate' to its 'world coordinate'. public static uint RegionToWorldLoc(uint regionCoord) { - return regionCoord * Constants.RegionSize; + return regionCoord << 8; + } + + + public static bool checkServiceURI(string uristr, out string serviceURI) + { + serviceURI = string.Empty; + try + { + Uri uri = new Uri(uristr); + serviceURI = uri.AbsoluteUri; + if(uri.Port == 80) + serviceURI = serviceURI.Trim(new char[] { '/', ' ' }) +":80/"; + else if(uri.Port == 443) + serviceURI = serviceURI.Trim(new char[] { '/', ' ' }) +":443/"; + return true; + } + catch + { + serviceURI = string.Empty; + } + return false; + } + + public static bool buildHGRegionURI(string inputName, out string serverURI, out string regionName) + { + serverURI = string.Empty; + regionName = string.Empty; + + inputName = inputName.Trim(); + + if (!inputName.StartsWith("http") && !inputName.StartsWith("https")) + { + // Formats: grid.example.com:8002:region name + // grid.example.com:region name + // grid.example.com:8002 + // grid.example.com + + string host; + uint port = 80; + + string[] parts = inputName.Split(new char[] { ':' }); + int indx; + if(parts.Length == 0) + return false; + if (parts.Length == 1) + { + indx = inputName.IndexOf('/'); + if (indx < 0) + serverURI = "http://"+ inputName + "/"; + else + { + serverURI = "http://"+ inputName.Substring(0,indx + 1); + if(indx + 2 < inputName.Length) + regionName = inputName.Substring(indx + 1); + } + } + else + { + host = parts[0]; + + if (parts.Length >= 2) + { + indx = parts[1].IndexOf('/'); + if(indx < 0) + { + // If it's a number then assume it's a port. Otherwise, it's a region name. + if (!UInt32.TryParse(parts[1], out port)) + { + port = 80; + regionName = parts[1]; + } + } + else + { + string portstr = parts[1].Substring(0, indx); + if(indx + 2 < parts[1].Length) + regionName = parts[1].Substring(indx + 1); + if (!UInt32.TryParse(portstr, out port)) + port = 80; + } + } + // always take the last one + if (parts.Length >= 3) + { + regionName = parts[2]; + } + + serverURI = "http://"+ host +":"+ port.ToString() + "/"; + } + } + else + { + // Formats: http://grid.example.com region name + // http://grid.example.com "region name" + // http://grid.example.com + + string[] parts = inputName.Split(new char[] { ' ' }); + + if (parts.Length == 0) + return false; + + serverURI = parts[0]; + + int indx = serverURI.LastIndexOf('/'); + if(indx > 10) + { + if(indx + 2 < inputName.Length) + regionName = inputName.Substring(indx + 1); + serverURI = inputName.Substring(0, indx + 1); + } + else if (parts.Length >= 2) + { + regionName = inputName.Substring(serverURI.Length); + } + } + + // use better code for sanity check + Uri uri; + try + { + uri = new Uri(serverURI); + } + catch + { + return false; + } + + if(!string.IsNullOrEmpty(regionName)) + regionName = regionName.Trim(new char[] { '"', ' ' }); + serverURI = uri.AbsoluteUri; + if(uri.Port == 80) + serverURI = serverURI.Trim(new char[] { '/', ' ' }) +":80/"; + else if(uri.Port == 443) + serverURI = serverURI.Trim(new char[] { '/', ' ' }) +":443/"; + return true; } public static T Clamp(T x, T min, T max) @@ -505,6 +671,7 @@ namespace OpenSim.Framework public static string GetFormattedXml(string rawXml) { XmlDocument xd = new XmlDocument(); + xd.XmlResolver=null; xd.LoadXml(rawXml); StringBuilder sb = new StringBuilder(); @@ -641,19 +808,25 @@ namespace OpenSim.Framework /// /// /// + public static string Md5Hash(string data) { - byte[] dataMd5 = ComputeMD5Hash(data); + return Md5Hash(data, Encoding.Default); + } + + public static string Md5Hash(string data, Encoding encoding) + { + byte[] dataMd5 = ComputeMD5Hash(data, encoding); StringBuilder sb = new StringBuilder(); for (int i = 0; i < dataMd5.Length; i++) sb.AppendFormat("{0:x2}", dataMd5[i]); return sb.ToString(); } - private static byte[] ComputeMD5Hash(string data) + private static byte[] ComputeMD5Hash(string data, Encoding encoding) { MD5 md5 = MD5.Create(); - return md5.ComputeHash(Encoding.Default.GetBytes(data)); + return md5.ComputeHash(encoding.GetBytes(data)); } /// @@ -661,6 +834,12 @@ namespace OpenSim.Framework /// /// /// + + public static string SHA1Hash(string data, Encoding enc) + { + return SHA1Hash(enc.GetBytes(data)); + } + public static string SHA1Hash(string data) { return SHA1Hash(Encoding.Default.GetBytes(data)); @@ -679,8 +858,10 @@ namespace OpenSim.Framework private static byte[] ComputeSHA1Hash(byte[] src) { - SHA1CryptoServiceProvider SHA1 = new SHA1CryptoServiceProvider(); - return SHA1.ComputeHash(src); + byte[] ret; + using(SHA1CryptoServiceProvider SHA1 = new SHA1CryptoServiceProvider()) + ret = SHA1.ComputeHash(src); + return ret; } public static int fast_distance2d(int x, int y) @@ -713,18 +894,27 @@ namespace OpenSim.Framework /// New region x-coord /// Old region y-coord /// New region y-coord - /// - public static bool IsOutsideView(float drawdist, uint oldx, uint newx, uint oldy, uint newy) - { - int dd = (int)((drawdist + Constants.RegionSize - 1) / Constants.RegionSize); - - int startX = (int)oldx - dd; - int startY = (int)oldy - dd; + /// + public static bool IsOutsideView(float drawdist, uint oldx, uint newx, uint oldy, uint newy, + int oldsizex, int oldsizey, int newsizex, int newsizey) + { + // we still need to make sure we see new region 1stNeighbors + drawdist--; + oldx *= Constants.RegionSize; + newx *= Constants.RegionSize; + if (oldx + oldsizex + drawdist < newx) + return true; + if (newx + newsizex + drawdist < oldx) + return true; - int endX = (int)oldx + dd; - int endY = (int)oldy + dd; + oldy *= Constants.RegionSize; + newy *= Constants.RegionSize; + if (oldy + oldsizey + drawdist < newy) + return true; + if (newy + newsizey + drawdist < oldy) + return true; - return (newx < startX || endX < newx || newy < startY || endY < newy); + return false; } public static string FieldToString(byte[] bytes) @@ -804,6 +994,18 @@ namespace OpenSim.Framework return output.ToString(); } + private static ExpiringCache dnscache = new ExpiringCache(); + + /// + /// Converts a URL to a IPAddress + /// + /// URL Standard Format + /// A resolved IP Address + public static IPAddress GetHostFromURL(string url) + { + return GetHostFromDNS(url.Split(new char[] {'/', ':'})[3]); + } + /// /// Returns a IP address from a specified DNS, favouring IPv4 addresses. /// @@ -811,38 +1013,128 @@ namespace OpenSim.Framework /// An IP address, or null public static IPAddress GetHostFromDNS(string dnsAddress) { - // Is it already a valid IP? No need to look it up. - IPAddress ipa; - if (IPAddress.TryParse(dnsAddress, out ipa)) - return ipa; + if(String.IsNullOrWhiteSpace(dnsAddress)) + return null; - IPAddress[] hosts = null; + IPAddress ia = null; + if(dnscache.TryGetValue(dnsAddress, out ia) && ia != null) + { + dnscache.AddOrUpdate(dnsAddress, ia, 300); + return ia; + } - // Not an IP, lookup required + ia = null; + // If it is already an IP, don't let GetHostEntry see it + if (IPAddress.TryParse(dnsAddress, out ia) && ia != null) + { + if (ia.Equals(IPAddress.Any) || ia.Equals(IPAddress.IPv6Any)) + return null; + dnscache.AddOrUpdate(dnsAddress, ia, 300); + return ia; + } + + IPHostEntry IPH; try { - hosts = Dns.GetHostEntry(dnsAddress).AddressList; + IPH = Dns.GetHostEntry(dnsAddress); } - catch (Exception e) + catch // (SocketException e) + { + return null; + } + + if(IPH == null || IPH.AddressList.Length == 0) + return null; + + ia = null; + foreach (IPAddress Adr in IPH.AddressList) { - m_log.WarnFormat("[UTIL]: An error occurred while resolving host name {0}, {1}", dnsAddress, e); + if (ia == null) + ia = Adr; - // Still going to throw the exception on for now, since this was what was happening in the first place - throw e; + if (Adr.AddressFamily == AddressFamily.InterNetwork) + { + ia = Adr; + break; + } } + if(ia != null) + dnscache.AddOrUpdate(dnsAddress, ia, 300); + return ia; + } - foreach (IPAddress host in hosts) + public static IPEndPoint getEndPoint(IPAddress ia, int port) + { + if(ia == null) + return null; + + IPEndPoint newEP = null; + try + { + newEP = new IPEndPoint(ia, port); + } + catch + { + newEP = null; + } + return newEP; + } + + public static IPEndPoint getEndPoint(string hostname, int port) + { + if(String.IsNullOrWhiteSpace(hostname)) + return null; + + IPAddress ia = null; + if(dnscache.TryGetValue(hostname, out ia) && ia != null) + { + dnscache.AddOrUpdate(hostname, ia, 300); + return getEndPoint(ia, port); + } + + ia = null; + + // If it is already an IP, don't let GetHostEntry see it + if (IPAddress.TryParse(hostname, out ia) && ia != null) + { + if (ia.Equals(IPAddress.Any) || ia.Equals(IPAddress.IPv6Any)) + return null; + + dnscache.AddOrUpdate(hostname, ia, 300); + return getEndPoint(ia, port); + } + + + IPHostEntry IPH; + try + { + IPH = Dns.GetHostEntry(hostname); + } + catch // (SocketException e) + { + return null; + } + + if(IPH == null || IPH.AddressList.Length == 0) + return null; + + ia = null; + foreach (IPAddress Adr in IPH.AddressList) { - if (host.AddressFamily == AddressFamily.InterNetwork) + if (ia == null) + ia = Adr; + + if (Adr.AddressFamily == AddressFamily.InterNetwork) { - return host; + ia = Adr; + break; } } - if (hosts.Length > 0) - return hosts[0]; + if(ia != null) + dnscache.AddOrUpdate(hostname, ia, 300); - return null; + return getEndPoint(ia,port); } public static Uri GetURI(string protocol, string hostname, int port, string path) @@ -987,7 +1279,7 @@ namespace OpenSim.Framework public static string configDir() { - return "../config"; + return "."; } public static string dataDir() @@ -999,13 +1291,26 @@ namespace OpenSim.Framework { foreach (IAppender appender in LogManager.GetRepository().GetAppenders()) { - if (appender is FileAppender) + if (appender is FileAppender && appender.Name == "LogFileAppender") { return ((FileAppender)appender).File; } } - return "../logs/OpenSim.log"; + return "./OpenSim.log"; + } + + public static string statsLogFile() + { + foreach (IAppender appender in LogManager.GetRepository().GetAppenders()) + { + if (appender is FileAppender && appender.Name == "StatsLogFileAppender") + { + return ((FileAppender)appender).File; + } + } + + return "./OpenSimStats.log"; } public static string logDir() @@ -1065,9 +1370,28 @@ namespace OpenSim.Framework } } + public static string GetConfigVarWithDefaultSection(IConfigSource config, string varname, string section) + { + // First, check the Startup section, the default section + IConfig cnf = config.Configs["Startup"]; + if (cnf == null) + return string.Empty; + string val = cnf.GetString(varname, string.Empty); + + // Then check for an overwrite of the default in the given section + if (!string.IsNullOrEmpty(section)) + { + cnf = config.Configs[section]; + if (cnf != null) + val = cnf.GetString(varname, val); + } + + return val; + } + /// /// Gets the value of a configuration variable by looking into - /// multiple sections in order. The latter sections overwrite + /// multiple sections in order. The latter sections overwrite /// any values previously found. /// /// Type of the variable @@ -1082,7 +1406,7 @@ namespace OpenSim.Framework /// /// Gets the value of a configuration variable by looking into - /// multiple sections in order. The latter sections overwrite + /// multiple sections in order. The latter sections overwrite /// any values previously found. /// /// @@ -1138,7 +1462,7 @@ namespace OpenSim.Framework ConfigSource.ExpandKeyValues(); } } - + public static T ReadSettingsFromIniFile(IConfig config, T settingsClass) { Type settingsType = settingsClass.GetType(); @@ -1249,7 +1573,7 @@ namespace OpenSim.Framework if (File.Exists(configFile)) { - // Merge + // Merge config.Merge(new IniConfigSource(configFile)); config.ExpandKeyValues(); configFilePath = configFile; @@ -1388,6 +1712,46 @@ namespace OpenSim.Framework return ret; } + public static string Compress(string text) + { + byte[] buffer = Util.UTF8.GetBytes(text); + MemoryStream memory = new MemoryStream(); + using (GZipStream compressor = new GZipStream(memory, CompressionMode.Compress, true)) + { + compressor.Write(buffer, 0, buffer.Length); + } + + memory.Position = 0; + + byte[] compressed = new byte[memory.Length]; + memory.Read(compressed, 0, compressed.Length); + + byte[] compressedBuffer = new byte[compressed.Length + 4]; + Buffer.BlockCopy(compressed, 0, compressedBuffer, 4, compressed.Length); + Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, compressedBuffer, 0, 4); + return Convert.ToBase64String(compressedBuffer); + } + + public static string Decompress(string compressedText) + { + byte[] compressedBuffer = Convert.FromBase64String(compressedText); + using (MemoryStream memory = new MemoryStream()) + { + int msgLength = BitConverter.ToInt32(compressedBuffer, 0); + memory.Write(compressedBuffer, 4, compressedBuffer.Length - 4); + + byte[] buffer = new byte[msgLength]; + + memory.Position = 0; + using (GZipStream decompressor = new GZipStream(memory, CompressionMode.Decompress)) + { + decompressor.Read(buffer, 0, buffer.Length); + } + + return Util.UTF8.GetString(buffer); + } + } + /// /// Copy data from one stream to another, leaving the read position of both streams at the beginning. /// @@ -1405,7 +1769,7 @@ namespace OpenSim.Framework const int readSize = 256; byte[] buffer = new byte[readSize]; MemoryStream ms = new MemoryStream(); - + int count = inputStream.Read(buffer, 0, readSize); while (count > 0) @@ -1485,12 +1849,16 @@ namespace OpenSim.Framework return new UUID(bytes, 0); } - public static void ParseFakeParcelID(UUID parcelID, out ulong regionHandle, out uint x, out uint y) + public static bool ParseFakeParcelID(UUID parcelID, out ulong regionHandle, out uint x, out uint y) { byte[] bytes = parcelID.GetBytes(); regionHandle = Utils.BytesToUInt64(bytes); x = Utils.BytesToUInt(bytes, 8) & 0xffff; y = Utils.BytesToUInt(bytes, 12) & 0xffff; + // validation may fail, just reducing the odds of using a real UUID as encoded parcel + return ( bytes[0] == 0 && bytes[4] == 0 && // handler x,y multiples of 256 + bytes[9] < 64 && bytes[13] < 64 && // positions < 16km + bytes[14] == 0 && bytes[15] == 0); } public static void ParseFakeParcelID(UUID parcelID, out ulong regionHandle, out uint x, out uint y, out uint z) @@ -1513,7 +1881,7 @@ namespace OpenSim.Framework x += rx; y += ry; } - + /// /// Get operating system information if available. Returns only the first 45 characters of information /// @@ -1524,20 +1892,20 @@ namespace OpenSim.Framework { string os = String.Empty; - if (Environment.OSVersion.Platform != PlatformID.Unix) - { - os = Environment.OSVersion.ToString(); - } - else - { - os = ReadEtcIssue(); - } - - if (os.Length > 45) - { - os = os.Substring(0, 45); - } - +// if (Environment.OSVersion.Platform != PlatformID.Unix) +// { +// os = Environment.OSVersion.ToString(); +// } +// else +// { +// os = ReadEtcIssue(); +// } +// +// if (os.Length > 45) +// { +// os = os.Substring(0, 45); +// } + return os; } @@ -1579,6 +1947,8 @@ namespace OpenSim.Framework // hide the password in the connection string passPosition = connectionString.IndexOf("password", StringComparison.OrdinalIgnoreCase); + if (passPosition == -1) + return connectionString; passPosition = connectionString.IndexOf("=", passPosition); if (passPosition < connectionString.Length) passPosition += 1; @@ -1645,7 +2015,7 @@ namespace OpenSim.Framework public static Guid GetHashGuid(string data, string salt) { - byte[] hash = ComputeMD5Hash(data + salt); + byte[] hash = ComputeMD5Hash(data + salt, Encoding.Default); //string s = BitConverter.ToString(hash); @@ -1747,7 +2117,7 @@ namespace OpenSim.Framework vol = vcomps[0]; } } - + string[] comps = path.Split(new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar}, StringSplitOptions.RemoveEmptyEntries); // Glob @@ -1792,6 +2162,32 @@ namespace OpenSim.Framework return found.ToArray(); } + public static string ServerURI(string uri) + { + if (uri == string.Empty) + return string.Empty; + + // Get rid of eventual slashes at the end + uri = uri.TrimEnd('/'); + + IPAddress ipaddr1 = null; + string port1 = ""; + try + { + ipaddr1 = Util.GetHostFromURL(uri); + } + catch { } + + try + { + port1 = uri.Split(new char[] { ':' })[2]; + } + catch { } + + // We tried our best to convert the domain names to IP addresses + return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri; + } + /// /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary. /// @@ -1823,14 +2219,14 @@ namespace OpenSim.Framework if (!str.EndsWith("\0")) str += "\0"; - + // Because this is UTF-8 encoding and not ASCII, it's possible we // might have gotten an oversized array even after the string trim byte[] data = UTF8.GetBytes(str); - if (data.Length > 256) + if (data.Length > 255) //play safe { - int cut = 255; + int cut = 254; if((data[cut] & 0x80 ) != 0 ) { while(cut > 0 && (data[cut] & 0xc0) != 0xc0) @@ -1895,6 +2291,56 @@ namespace OpenSim.Framework } /// + /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to MaxLength bytes if necessary. + /// + /// + /// If null or empty, then an bytes[0] is returned. + /// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0] + /// + /// + /// Arguments to substitute into the string via the {} mechanism. + /// + /// + public static byte[] StringToBytes(string str, int MaxLength, params object[] args) + { + return StringToBytes1024(string.Format(str, args), MaxLength); + } + + /// + /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to MaxLength bytes if necessary. + /// + /// + /// If null or empty, then an bytes[0] is returned. + /// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0] + /// + /// + public static byte[] StringToBytes(string str, int MaxLength) + { + if (String.IsNullOrEmpty(str)) + return Utils.EmptyBytes; + + if (!str.EndsWith("\0")) + str += "\0"; + + // Because this is UTF-8 encoding and not ASCII, it's possible we + // might have gotten an oversized array even after the string trim + byte[] data = UTF8.GetBytes(str); + + if (data.Length > MaxLength) + { + int cut = MaxLength - 1 ; + if((data[cut] & 0x80 ) != 0 ) + { + while(cut > 0 && (data[cut] & 0xc0) != 0xc0) + cut--; + } + Array.Resize(ref data, cut + 1); + data[cut] = 0; + } + + return data; + } + /// /// Pretty format the hashtable contents to a single line. /// /// @@ -2004,7 +2450,7 @@ namespace OpenSim.Framework STPStartInfo startInfo = new STPStartInfo(); startInfo.ThreadPoolName = "Util"; - startInfo.IdleTimeout = 2000; + startInfo.IdleTimeout = 20000; startInfo.MaxWorkerThreads = maxThreads; startInfo.MinWorkerThreads = minThreads; @@ -2032,7 +2478,7 @@ namespace OpenSim.Framework throw new NotImplementedException(); } } - + /// /// Additional information about threads in the main thread pool. Used to time how long the /// thread has been running, and abort it if it has timed-out. @@ -2043,14 +2489,15 @@ namespace OpenSim.Framework public string StackTrace { get; set; } private string context; public bool LogThread { get; set; } - + public IWorkItemResult WorkItem { get; set; } public Thread Thread { get; set; } public bool Running { get; set; } public bool Aborted { get; set; } private int started; + public bool DoTimeout; - public ThreadInfo(long threadFuncNum, string context) + public ThreadInfo(long threadFuncNum, string context, bool dotimeout = true) { ThreadFuncNum = threadFuncNum; this.context = context; @@ -2058,6 +2505,7 @@ namespace OpenSim.Framework Thread = null; Running = false; Aborted = false; + DoTimeout = dotimeout; } public void Started() @@ -2128,7 +2576,7 @@ namespace OpenSim.Framework foreach (KeyValuePair entry in activeThreads) { ThreadInfo t = entry.Value; - if (t.Running && !t.Aborted && (t.Elapsed() >= THREAD_TIMEOUT)) + if (t.DoTimeout && t.Running && !t.Aborted && (t.Elapsed() >= THREAD_TIMEOUT)) { m_log.WarnFormat("Timeout in threadfunc {0} ({1}) {2}", t.ThreadFuncNum, t.Thread.Name, t.GetStackTrace()); t.Abort(); @@ -2138,7 +2586,7 @@ namespace OpenSim.Framework // It's possible that the thread won't abort. To make sure the thread pool isn't // depleted, increase the pool size. - m_ThreadPool.MaxThreads++; +// m_ThreadPool.MaxThreads++; } } } @@ -2148,7 +2596,7 @@ namespace OpenSim.Framework public static Dictionary GetFireAndForgetCallsMade() { return new Dictionary(m_fireAndForgetCallsMade); - } + } private static Dictionary m_fireAndForgetCallsMade = new Dictionary(); @@ -2168,11 +2616,11 @@ namespace OpenSim.Framework { FireAndForget(callback, obj, null); } - - public static void FireAndForget(System.Threading.WaitCallback callback, object obj, string context) + + public static void FireAndForget(System.Threading.WaitCallback callback, object obj, string context, bool dotimeout = true) { Interlocked.Increment(ref numTotalThreadFuncsCalled); - +/* if (context != null) { if (!m_fireAndForgetCallsMade.ContainsKey(context)) @@ -2185,25 +2633,25 @@ namespace OpenSim.Framework else m_fireAndForgetCallsInProgress[context]++; } - +*/ WaitCallback realCallback; bool loggingEnabled = LogThreadPool > 0; - + long threadFuncNum = Interlocked.Increment(ref nextThreadFuncNum); - ThreadInfo threadInfo = new ThreadInfo(threadFuncNum, context); + ThreadInfo threadInfo = new ThreadInfo(threadFuncNum, context, dotimeout); if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest) { // If we're running regression tests, then we want any exceptions to rise up to the test code. - realCallback = - o => - { - Culture.SetCurrentCulture(); - callback(o); - - if (context != null) - m_fireAndForgetCallsInProgress[context]--; + realCallback = + o => + { + Culture.SetCurrentCulture(); + callback(o); + +// if (context != null) +// m_fireAndForgetCallsInProgress[context]--; }; } else @@ -2229,7 +2677,6 @@ namespace OpenSim.Framework } catch (ThreadAbortException e) { - m_log.Error(string.Format("Aborted threadfunc {0} ", threadFuncNum), e); } catch (Exception e) { @@ -2244,8 +2691,8 @@ namespace OpenSim.Framework if ((loggingEnabled || (threadFuncOverloadMode == 1)) && threadInfo.LogThread) m_log.DebugFormat("Exit threadfunc {0} ({1})", threadFuncNum, FormatDuration(threadInfo.Elapsed())); - if (context != null) - m_fireAndForgetCallsInProgress[context]--; +// if (context != null) +// m_fireAndForgetCallsInProgress[context]--; } }; } @@ -2253,6 +2700,7 @@ namespace OpenSim.Framework long numQueued = Interlocked.Increment(ref numQueuedThreadFuncs); try { +/* long numRunning = numRunningThreadFuncs; if (m_ThreadPool != null && LogOverloads) @@ -2285,6 +2733,7 @@ namespace OpenSim.Framework } } else +*/ { // Since we didn't log "Queue threadfunc", don't log "Run threadfunc" or "End threadfunc" either. // Those log lines aren't useful when we don't know which function is running in the thread. @@ -2342,7 +2791,7 @@ namespace OpenSim.Framework if (stackTrace.Contains("BeginFireQueueEmpty")) return false; } - + return true; } @@ -2355,7 +2804,7 @@ namespace OpenSim.Framework { string src = Environment.StackTrace; string[] lines = src.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); - + StringBuilder dest = new StringBuilder(src.Length); bool started = false; @@ -2400,11 +2849,11 @@ namespace OpenSim.Framework /// trace. And pausing another thread can cause a deadlock. This method attempts to /// avoid deadlock by using a short timeout (200ms), after which it gives up and /// returns 'null' instead of the stack trace. - /// + /// /// Take from: http://stackoverflow.com/a/14935378 - /// + /// /// WARNING: this doesn't work in Mono. See https://bugzilla.novell.com/show_bug.cgi?id=571691 - /// + /// /// /// The stack trace, or null if failed to get it private static StackTrace GetStackTrace(Thread targetThread) @@ -2500,12 +2949,22 @@ namespace OpenSim.Framework return stpi; } + public static void StopThreadPool() + { + if (m_ThreadPool == null) + return; + SmartThreadPool pool = m_ThreadPool; + m_ThreadPool = null; + + try { pool.Shutdown(); } catch {} + } + #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. + /// for the callers. /// This trims it to a 12 day interval so don't let your frame time get too long. /// /// @@ -2513,6 +2972,7 @@ namespace OpenSim.Framework { return Environment.TickCount & EnvironmentTickCountMask; } + const Int32 EnvironmentTickCountMask = 0x3fffffff; /// @@ -2557,6 +3017,18 @@ namespace OpenSim.Framework return tcA - tcB; } + // returns a timestamp in ms as double + // using the time resolution avaiable to StopWatch + public static double GetTimeStamp() + { + return (double)Stopwatch.GetTimestamp() * TimeStampClockPeriod; + } + + public static double GetTimeStampMS() + { + return (double)Stopwatch.GetTimestamp() * TimeStampClockPeriodMS; + } + /// /// Formats a duration (given in milliseconds). /// @@ -2855,7 +3327,7 @@ namespace OpenSim.Framework if (parts.Length == 2) return CalcUniversalIdentifier(id, agentsURI, parts[0] + " " + parts[1]); } - + return CalcUniversalIdentifier(id, agentsURI, firstName + " " + lastName); } @@ -2940,6 +3412,7 @@ namespace OpenSim.Framework } +/* don't like this code public class DoubleQueue where T:class { private Queue m_lowQueue = new Queue(); @@ -2954,10 +3427,10 @@ namespace OpenSim.Framework public virtual int Count { - get - { + get + { lock (m_syncRoot) - return m_highQueue.Count + m_lowQueue.Count; + return m_highQueue.Count + m_lowQueue.Count; } } @@ -3051,7 +3524,7 @@ namespace OpenSim.Framework } } } - +*/ public class BetterRandom { private const int BufferSize = 1024; // must be a multiple of 4 diff --git a/OpenSim/Framework/VersionInfo.cs b/OpenSim/Framework/VersionInfo.cs index 1b9ec76..fc0fb1a 100644 --- a/OpenSim/Framework/VersionInfo.cs +++ b/OpenSim/Framework/VersionInfo.cs @@ -29,9 +29,10 @@ namespace OpenSim { public class VersionInfo { - public const string VersionNumber = "0.8.2.1"; - private const string IG_BUILD_NUMBER = "1"; - private const Flavour VERSION_FLAVOUR = Flavour.IG; + public const string VersionNumber = "0.9.0.1"; + public const string AssemblyVersionNumber = "0.9.0.*"; + + public const Flavour VERSION_FLAVOUR = Flavour.Release; public enum Flavour { @@ -42,26 +43,25 @@ namespace OpenSim RC3, Release, Post_Fixes, - Extended, - IG + Extended } public static string Version { - get { return GetVersionString(VersionNumber, IG_BUILD_NUMBER, VERSION_FLAVOUR); } + get { return GetVersionString(VersionNumber, VERSION_FLAVOUR); } } - public static string GetVersionString(string versionNumber, string buildNumber, Flavour flavour) + public static string GetVersionString(string versionNumber, Flavour flavour) { - string versionString = "OpenSim " + versionNumber + " " + flavour + " build " + buildNumber; + string versionString = "OpenSim " + versionNumber + " " + flavour; return versionString.PadRight(VERSIONINFO_VERSION_LENGTH); } - public const int VERSIONINFO_VERSION_LENGTH = 39; + public const int VERSIONINFO_VERSION_LENGTH = 27; /// /// This is the external interface version. It is separate from the OpenSimulator project version. - /// + /// /// /// Commented because it's not used anymore, see below for new /// versioning method. @@ -70,23 +70,23 @@ namespace OpenSim /// /// This rules versioning regarding teleports, and compatibility between simulators in that regard. /// - /// + /// /// /// The protocol version that we will use for outgoing transfers - /// Valid values are - /// "SIMULATION/0.3" + /// Valid values are + /// "SIMULATION/0.3" /// - This is the latest, and it supports teleports to variable-sized regions /// - Older versions can teleport to this one, but only if the destination region /// is 256x256 /// "SIMULATION/0.2" /// - A source simulator which only implements "SIMULATION/0.1" can still teleport here /// - this protocol is more efficient than "SIMULATION/0.1" - /// "SIMULATION/0.1" + /// "SIMULATION/0.1" /// - this is an older teleport protocol used in OpenSimulator 0.7.5 and before. /// public readonly static float SimulationServiceVersionAcceptedMin = 0.3f; - public readonly static float SimulationServiceVersionAcceptedMax = 0.5f; + public readonly static float SimulationServiceVersionAcceptedMax = 0.6f; public readonly static float SimulationServiceVersionSupportedMin = 0.3f; - public readonly static float SimulationServiceVersionSupportedMax = 0.5f; + public readonly static float SimulationServiceVersionSupportedMax = 0.6f; } } diff --git a/OpenSim/Framework/WearableCacheItem.cs b/OpenSim/Framework/WearableCacheItem.cs index 1aecf79..427e149 100644 --- a/OpenSim/Framework/WearableCacheItem.cs +++ b/OpenSim/Framework/WearableCacheItem.cs @@ -43,13 +43,14 @@ namespace OpenSim.Framework public static WearableCacheItem[] GetDefaultCacheItem() { - int itemmax = 21; + int itemmax = AvatarAppearance.TEXTURE_COUNT; WearableCacheItem[] retitems = new WearableCacheItem[itemmax]; for (uint i=0;i ret = new List(); if (pInput.Type == OSDType.Array) @@ -63,7 +64,7 @@ namespace OpenSim.Framework CacheId = item["cacheid"].AsUUID(), TextureID = item["textureid"].AsUUID() }); - + if (dataCache != null && item.ContainsKey("assetdata")) { AssetBase asset = new AssetBase(item["textureid"].AsUUID(),"BakedTexture",(sbyte)AssetType.Texture,UUID.Zero.ToString()); @@ -98,7 +99,8 @@ namespace OpenSim.Framework return ret.ToArray(); } - public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache) + + public static OSD ToOSD(WearableCacheItem[] pcacheItems, IAssetCache dataCache) { OSDArray arr = new OSDArray(); foreach (WearableCacheItem item in pcacheItems) @@ -111,7 +113,8 @@ namespace OpenSim.Framework { if (dataCache.Check(item.TextureID.ToString())) { - AssetBase assetItem = dataCache.Get(item.TextureID.ToString()); + AssetBase assetItem; + dataCache.Get(item.TextureID.ToString(), out assetItem); if (assetItem != null) { itemmap.Add("assetdata", OSD.FromBinary(assetItem.Data)); @@ -124,6 +127,68 @@ namespace OpenSim.Framework } return arr; } + + public static OSDArray BakedToOSD(WearableCacheItem[] pcacheItems) + { + if (pcacheItems.Length < AvatarAppearance.BAKE_INDICES[AvatarAppearance.BAKE_INDICES.Length - 1]) + return null; + + OSDArray arr = new OSDArray(); + + for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) + { + int idx = AvatarAppearance.BAKE_INDICES[i]; + + WearableCacheItem item = pcacheItems[idx]; + + OSDMap itemmap = new OSDMap(); + itemmap.Add("textureindex", OSD.FromUInteger(item.TextureIndex)); + itemmap.Add("cacheid", OSD.FromUUID(item.CacheId)); + itemmap.Add("textureid", OSD.FromUUID(item.TextureID)); +/* + if (item.TextureAsset != null) + { + itemmap.Add("assetdata", OSD.FromBinary(item.TextureAsset.Data)); + itemmap.Add("assetcreator", OSD.FromString(item.TextureAsset.CreatorID)); + itemmap.Add("assetname", OSD.FromString(item.TextureAsset.Name)); + } + */ + arr.Add(itemmap); + } + return arr; + } + + public static WearableCacheItem[] BakedFromOSD(OSD pInput) + { + WearableCacheItem[] pcache = WearableCacheItem.GetDefaultCacheItem(); + + if (pInput.Type == OSDType.Array) + { + OSDArray itemarray = (OSDArray)pInput; + foreach (OSDMap item in itemarray) + { + int idx = (int)item["textureindex"].AsUInteger(); + if (idx < 0 || idx > pcache.Length) + continue; + pcache[idx].CacheId = item["cacheid"].AsUUID(); + pcache[idx].TextureID = item["textureid"].AsUUID(); +/* + if (item.ContainsKey("assetdata")) + { + AssetBase asset = new AssetBase(item["textureid"].AsUUID(), "BakedTexture", (sbyte)AssetType.Texture, UUID.Zero.ToString()); + asset.Temporary = true; + asset.Local = true; + asset.Data = item["assetdata"].AsBinary(); + pcache[idx].TextureAsset = asset; + } + else + */ + pcache[idx].TextureAsset = null; + } + } + return pcache; + } + public static WearableCacheItem SearchTextureIndex(uint pTextureIndex,WearableCacheItem[] pcacheItems) { for (int i = 0; i < pcacheItems.Length; i++) diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index b180c8a..20d30b5 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -72,11 +72,6 @@ namespace OpenSim.Framework public static int RequestNumber { get; set; } /// - /// Control where OSD requests should be serialized per endpoint. - /// - public static bool SerializeOSDRequestsPerEndpoint { get; set; } - - /// /// this is the header field used to communicate the local request id /// used for performance and debugging /// @@ -98,31 +93,6 @@ namespace OpenSim.Framework /// public const int MaxRequestDiagLength = 200; - /// - /// Dictionary of end points - /// - private static Dictionary m_endpointSerializer = new Dictionary(); - - private static object EndPointLock(string url) - { - System.Uri uri = new System.Uri(url); - string endpoint = string.Format("{0}:{1}",uri.Host,uri.Port); - - lock (m_endpointSerializer) - { - object eplock = null; - - if (! m_endpointSerializer.TryGetValue(endpoint,out eplock)) - { - eplock = new object(); - m_endpointSerializer.Add(endpoint,eplock); - // m_log.WarnFormat("[WEB UTIL] add a new host to end point serializer {0}",endpoint); - } - - return eplock; - } - } - #region JSONRequest /// @@ -154,21 +124,6 @@ namespace OpenSim.Framework return ServiceOSDRequest(url, null, "GET", timeout, false, false); } - public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc) - { - if (SerializeOSDRequestsPerEndpoint) - { - lock (EndPointLock(url)) - { - return ServiceOSDRequestWorker(url, data, method, timeout, compressed, rpc); - } - } - else - { - return ServiceOSDRequestWorker(url, data, method, timeout, compressed, rpc); - } - } - public static void LogOutgoingDetail(Stream outputStream) { LogOutgoingDetail("", outputStream); @@ -222,7 +177,7 @@ namespace OpenSim.Framework LogOutgoingDetail(string.Format("RESPONSE {0}: ", reqnum), input); } - private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc) + public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc) { int reqnum = RequestNumber++; @@ -233,6 +188,9 @@ namespace OpenSim.Framework string errorMessage = "unknown error"; int tickstart = Util.EnvironmentTickCount(); int tickdata = 0; + int tickcompressdata = 0; + int tickJsondata = 0; + int compsize = 0; string strBuffer = null; try @@ -242,21 +200,23 @@ namespace OpenSim.Framework request.Timeout = timeout; request.KeepAlive = false; request.MaximumAutomaticRedirections = 10; - request.ReadWriteTimeout = timeout / 4; + request.ReadWriteTimeout = timeout / 2; request.Headers[OSHeaderRequestID] = reqnum.ToString(); - + // If there is some input, write it into the request if (data != null) { strBuffer = OSDParser.SerializeJsonString(data); + tickJsondata = Util.EnvironmentTickCountSubtract(tickstart); + if (DebugLevel >= 5) LogOutgoingDetail("SEND", reqnum, strBuffer); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); request.ContentType = rpc ? "application/json-rpc" : "application/json"; - + if (compressed) { request.Headers["X-Content-Encoding"] = "gzip"; // can't set "Content-Encoding" because old OpenSims fail if they get an unrecognized Content-Encoding @@ -271,19 +231,25 @@ namespace OpenSim.Framework // gets written on the stream upon Dispose() } byte[] buf = ms.ToArray(); + + tickcompressdata = Util.EnvironmentTickCountSubtract(tickstart); + request.ContentLength = buf.Length; //Count bytes to send + compsize = buf.Length; using (Stream requestStream = request.GetRequestStream()) requestStream.Write(buf, 0, (int)buf.Length); } } else { + compsize = buffer.Length; + request.ContentLength = buffer.Length; //Count bytes to send using (Stream requestStream = request.GetRequestStream()) requestStream.Write(buffer, 0, buffer.Length); //Send it } } - + // capture how much time was spent writing, this may seem silly // but with the number concurrent requests, this often blocks tickdata = Util.EnvironmentTickCountSubtract(tickstart); @@ -314,6 +280,7 @@ namespace OpenSim.Framework catch (Exception ex) { errorMessage = ex.Message; + m_log.Debug("[WEB UTIL]: Exception making request: " + ex.ToString()); } finally { @@ -321,8 +288,17 @@ namespace OpenSim.Framework if (tickdiff > LongCallTime) { m_log.InfoFormat( - "[LOGHTTP]: Slow JSON-RPC request {0} {1} to {2} took {3}ms, {4}ms writing, {5}", - reqnum, method, url, tickdiff, tickdata, + "[WEB UTIL]: Slow ServiceOSD request {0} {1} {2} took {3}ms, {4}ms writing({5} at Json; {6} at comp), {7} bytes ({8} uncomp): {9}", + reqnum, + method, + url, + tickdiff, + tickdata, + tickJsondata, + tickcompressdata, + compsize, + strBuffer != null ? strBuffer.Length : 0, + strBuffer != null ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer) : ""); @@ -333,7 +309,7 @@ namespace OpenSim.Framework reqnum, tickdiff, tickdata); } } - + m_log.DebugFormat( "[LOGHTTP]: JSON-RPC request {0} {1} to {2} FAILED: {3}", reqnum, method, url, errorMessage); @@ -357,7 +333,7 @@ namespace OpenSim.Framework result["success"] = OSD.FromBoolean(true); result["_RawResult"] = OSD.FromString(response); result["_Result"] = new OSDMap(); - + if (response.Equals("true",System.StringComparison.OrdinalIgnoreCase)) return result; @@ -368,7 +344,7 @@ namespace OpenSim.Framework return result; } - try + try { OSD responseOSD = OSDParser.Deserialize(response); if (responseOSD.Type == OSDType.Map) @@ -382,10 +358,10 @@ namespace OpenSim.Framework // don't need to treat this as an error... we're just guessing anyway // m_log.DebugFormat("[WEB UTIL] couldn't decode <{0}>: {1}",response,e.Message); } - + return result; } - + #endregion JSONRequest #region FormRequest @@ -396,18 +372,10 @@ namespace OpenSim.Framework /// public static OSDMap PostToService(string url, NameValueCollection data) { - return ServiceFormRequest(url,data,10000); - } - - public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout) - { - lock (EndPointLock(url)) - { - return ServiceFormRequestWorker(url,data,timeout); - } + return ServiceFormRequest(url,data, 30000); } - private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout) + public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout) { int reqnum = RequestNumber++; string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; @@ -415,7 +383,7 @@ namespace OpenSim.Framework if (DebugLevel >= 3) m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} ServiceForm '{1}' to {2}", reqnum, method, url); - + string errorMessage = "unknown error"; int tickstart = Util.EnvironmentTickCount(); int tickdata = 0; @@ -428,9 +396,9 @@ namespace OpenSim.Framework request.Timeout = timeout; request.KeepAlive = false; request.MaximumAutomaticRedirections = 10; - request.ReadWriteTimeout = timeout / 4; + request.ReadWriteTimeout = timeout / 2; request.Headers[OSHeaderRequestID] = reqnum.ToString(); - + if (data != null) { queryString = BuildQueryString(data); @@ -439,7 +407,7 @@ namespace OpenSim.Framework LogOutgoingDetail("SEND", reqnum, queryString); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString); - + request.ContentLength = buffer.Length; request.ContentType = "application/x-www-form-urlencoded"; using (Stream requestStream = request.GetRequestStream()) @@ -517,7 +485,7 @@ namespace OpenSim.Framework } #endregion FormRequest - + #region Uri /// @@ -570,7 +538,7 @@ namespace OpenSim.Framework } /// - /// Appends a query string to a Uri that may or may not have existing + /// Appends a query string to a Uri that may or may not have existing /// query parameters /// /// Uri to append the query to @@ -622,7 +590,7 @@ namespace OpenSim.Framework } /// - /// + /// /// /// /// @@ -641,12 +609,12 @@ namespace OpenSim.Framework #region Stream /// - /// Copies the contents of one stream to another, starting at the + /// Copies the contents of one stream to another, starting at the /// current position of each stream /// - /// The stream to copy from, at the position + /// The stream to copy from, at the position /// where copying should begin - /// The stream to copy to, at the position where + /// The stream to copy to, at the position where /// bytes should be written /// The maximum bytes to copy /// The total number of bytes copied @@ -779,6 +747,20 @@ namespace OpenSim.Framework MakeRequest(verb, requestUrl, obj, action, maxConnections, null); } + /// + /// Perform a synchronous REST request. + /// + /// + /// + /// + /// + /// Request timeout in seconds. Timeout.Infinite indicates no timeout. If 0 is passed then the default HttpWebRequest timeout is used (100 seconds) + /// + /// + /// + /// The response. If there was an internal exception or the request timed out, + /// then the default(TResponse) is returned. + /// public static void MakeRequest(string verb, string requestUrl, TRequest obj, Action action, int maxConnections, IServiceAuth auth) @@ -791,6 +773,7 @@ namespace OpenSim.Framework int tickstart = Util.EnvironmentTickCount(); int tickdata = 0; + int tickdiff = 0; Type type = typeof(TRequest); @@ -873,7 +856,7 @@ namespace OpenSim.Framework // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't // documented in MSDN using (WebResponse response = request.EndGetResponse(res2)) - { + { try { using (Stream respStream = response.GetResponseStream()) @@ -894,7 +877,7 @@ namespace OpenSim.Framework if (e.Response is HttpWebResponse) { using (HttpWebResponse httpResponse = (HttpWebResponse)e.Response) - { + { if (httpResponse.StatusCode != HttpStatusCode.NotFound) { // We don't appear to be handling any other status codes, so log these feailures to that @@ -919,7 +902,7 @@ namespace OpenSim.Framework "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}", verb, requestUrl, e.Message, e.StackTrace); } - + // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); try @@ -932,11 +915,11 @@ namespace OpenSim.Framework "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}", verb, requestUrl, e.Message, e.StackTrace); } - + }, null); } - int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); + tickdiff = Util.EnvironmentTickCountSubtract(tickstart); if (tickdiff > WebUtil.LongCallTime) { string originalRequest = null; @@ -948,8 +931,7 @@ namespace OpenSim.Framework if (originalRequest.Length > WebUtil.MaxRequestDiagLength) originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength); } - - m_log.InfoFormat( + m_log.InfoFormat( "[LOGHTTP]: Slow AsynchronousRequestObject request {0} {1} to {2} took {3}ms, {4}ms writing, {5}", reqnum, verb, requestUrl, tickdiff, tickdata, originalRequest); @@ -957,11 +939,12 @@ namespace OpenSim.Framework else if (WebUtil.DebugLevel >= 4) { m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing", + reqnum, tickdiff, tickdata); } } finally - { + { if (buffer != null) buffer.Dispose(); } @@ -983,7 +966,8 @@ namespace OpenSim.Framework /// /// Thrown if we encounter a network issue while posting /// the request. You'll want to make sure you deal with this as they're not uncommon - public static string MakeRequest(string verb, string requestUrl, string obj, int timeoutsecs, IServiceAuth auth) + public static string MakeRequest(string verb, string requestUrl, string obj, int timeoutsecs = -1, + IServiceAuth auth = null, bool keepalive = true) { int reqnum = WebUtil.RequestNumber++; @@ -998,12 +982,16 @@ namespace OpenSim.Framework request.Method = verb; if (timeoutsecs > 0) request.Timeout = timeoutsecs * 1000; + if(!keepalive && request is HttpWebRequest) + ((HttpWebRequest)request).KeepAlive = false; if (auth != null) auth.AddAuthorization(request.Headers); string respstring = String.Empty; + int tickset = Util.EnvironmentTickCountSubtract(tickstart); + using (MemoryStream buffer = new MemoryStream()) { if ((verb == "POST") || (verb == "PUT")) @@ -1024,11 +1012,10 @@ namespace OpenSim.Framework if (WebUtil.DebugLevel >= 5) WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data)); - Stream requestStream = null; try { - requestStream = request.GetRequestStream(); - requestStream.Write(data, 0, length); + using(Stream requestStream = request.GetRequestStream()) + requestStream.Write(data,0,length); } catch (Exception e) { @@ -1038,9 +1025,6 @@ namespace OpenSim.Framework } finally { - if (requestStream != null) - requestStream.Dispose(); - // capture how much time was spent writing tickdata = Util.EnvironmentTickCountSubtract(tickstart); } @@ -1070,8 +1054,13 @@ namespace OpenSim.Framework if (tickdiff > WebUtil.LongCallTime) { m_log.InfoFormat( - "[LOGHTTP]: Slow SynchronousRestForms request {0} {1} to {2} took {3}ms, {4}ms writing, {5}", - reqnum, verb, requestUrl, tickdiff, tickdata, + "[FORMS]: Slow request {0} {1} {2} took {3}ms, {4}ms writing, {5}", + reqnum, + verb, + requestUrl, + tickdiff, + tickset, + tickdata, obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj); } else if (WebUtil.DebugLevel >= 4) @@ -1086,16 +1075,6 @@ namespace OpenSim.Framework return respstring; } - public static string MakeRequest(string verb, string requestUrl, string obj, int timeoutsecs) - { - return MakeRequest(verb, requestUrl, obj, timeoutsecs, null); - } - - public static string MakeRequest(string verb, string requestUrl, string obj) - { - return MakeRequest(verb, requestUrl, obj, -1); - } - public static string MakeRequest(string verb, string requestUrl, string obj, IServiceAuth auth) { return MakeRequest(verb, requestUrl, obj, -1, auth); @@ -1136,7 +1115,7 @@ namespace OpenSim.Framework /// Request timeout in milliseconds. Timeout.Infinite indicates no timeout. If 0 is passed then the default HttpWebRequest timeout is used (100 seconds) /// /// - /// The response. If there was an internal exception or the request timed out, + /// The response. If there was an internal exception or the request timed out, /// then the default(TResponse) is returned. /// public static TResponse MakeRequest(string verb, string requestUrl, TRequest obj, int pTimeout) @@ -1159,7 +1138,7 @@ namespace OpenSim.Framework /// /// /// - /// The response. If there was an internal exception or the request timed out, + /// The response. If there was an internal exception or the request timed out, /// then the default(TResponse) is returned. /// public static TResponse MakeRequest(string verb, string requestUrl, TRequest obj, int pTimeout, int maxConnections) @@ -1178,7 +1157,7 @@ namespace OpenSim.Framework /// /// /// - /// The response. If there was an internal exception or the request timed out, + /// The response. If there was an internal exception or the request timed out, /// then the default(TResponse) is returned. /// public static TResponse MakeRequest(string verb, string requestUrl, TRequest obj, int pTimeout, int maxConnections, IServiceAuth auth) @@ -1202,7 +1181,7 @@ namespace OpenSim.Framework auth.AddAuthorization(ht.Headers); if (pTimeout != 0) - ht.Timeout = pTimeout; + request.Timeout = pTimeout; if (maxConnections > 0 && ht.ServicePoint.ConnectionLimit < maxConnections) ht.ServicePoint.ConnectionLimit = maxConnections; @@ -1283,18 +1262,24 @@ namespace OpenSim.Framework { if (hwr.StatusCode == HttpStatusCode.NotFound) return deserial; + if (hwr.StatusCode == HttpStatusCode.Unauthorized) { - m_log.Error(string.Format( - "[SynchronousRestObjectRequester]: Web request {0} requires authentication ", - requestUrl)); - return deserial; + m_log.ErrorFormat("[SynchronousRestObjectRequester]: Web request {0} requires authentication", + requestUrl); + } + else + { + m_log.WarnFormat("[SynchronousRestObjectRequester]: Web request {0} returned error: {1}", + requestUrl, hwr.StatusCode); } } else - m_log.Error(string.Format( - "[SynchronousRestObjectRequester]: WebException for {0} {1} {2} ", - verb, requestUrl, typeof(TResponse).ToString()), e); + m_log.ErrorFormat( + "[SynchronousRestObjectRequester]: WebException for {0} {1} {2} {3}", + verb, requestUrl, typeof(TResponse).ToString(), e.Message); + + return deserial; } } catch (System.InvalidOperationException) @@ -1344,7 +1329,6 @@ namespace OpenSim.Framework return deserial; } - public static class XMLResponseHelper { public static TResponse LogAndDeserialize(int reqnum, Stream respStream, long contentLength) @@ -1369,7 +1353,7 @@ namespace OpenSim.Framework } } - + public static class XMLRPCRequester { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -1413,7 +1397,7 @@ namespace OpenSim.Framework { m_log.Error("Error parsing XML-RPC response", e); } - + if (Resp.IsFault) { m_log.DebugFormat( diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index bf34419..66ce8e5 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs @@ -74,7 +74,16 @@ namespace OpenSim AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); - ServicePointManager.DefaultConnectionLimit = 12; + if(Util.IsWindows()) + ServicePointManager.DefaultConnectionLimit = 32; + else + { + ServicePointManager.DefaultConnectionLimit = 12; + } + + try { ServicePointManager.DnsRefreshTimeout = 300000; } catch { } + ServicePointManager.Expect100Continue = false; + ServicePointManager.UseNagleAlgorithm = false; // Add the arguments supplied when running the application to the configuration ArgvConfigSource configSource = new ArgvConfigSource(args); @@ -85,9 +94,9 @@ namespace OpenSim if (logConfigFile != String.Empty) { XmlConfigurator.Configure(new System.IO.FileInfo(logConfigFile)); - m_log.InfoFormat("[OPENSIM MAIN]: configured log4net using \"{0}\" as configuration file", + m_log.InfoFormat("[OPENSIM MAIN]: configured log4net using \"{0}\" as configuration file", logConfigFile); - } + } else { XmlConfigurator.Configure(); @@ -103,22 +112,22 @@ namespace OpenSim "[OPENSIM MAIN]: Environment variable MONO_THREADS_PER_CPU is {0}", monoThreadsPerCpu ?? "unset"); // Verify the Threadpool allocates or uses enough worker and IO completion threads - // .NET 2.0, workerthreads default to 50 * numcores - // .NET 3.0, workerthreads defaults to 250 * numcores - // .NET 4.0, workerthreads are dynamic based on bitness and OS resources + // .NET 2.0, workerthreads default to 50 * numcores + // .NET 3.0, workerthreads defaults to 250 * numcores + // .NET 4.0, workerthreads are dynamic based on bitness and OS resources // Max IO Completion threads are 1000 on all 3 CLRs // // Mono 2.10.9 to at least Mono 3.1, workerthreads default to 100 * numcores, iocp threads to 4 * numcores - int workerThreadsMin = 500; - int workerThreadsMax = 1000; // may need further adjustment to match other CLR - int iocpThreadsMin = 1000; - int iocpThreadsMax = 2000; // may need further adjustment to match other CLR + int workerThreadsMin = 500; + int workerThreadsMax = 1000; // may need further adjustment to match other CLR + int iocpThreadsMin = 1000; + int iocpThreadsMax = 2000; // may need further adjustment to match other CLR { int currentMinWorkerThreads, currentMinIocpThreads; System.Threading.ThreadPool.GetMinThreads(out currentMinWorkerThreads, out currentMinIocpThreads); m_log.InfoFormat( - "[OPENSIM MAIN]: Runtime gave us {0} min worker threads and {1} min IOCP threads", + "[OPENSIM MAIN]: Runtime gave us {0} min worker threads and {1} min IOCP threads", currentMinWorkerThreads, currentMinIocpThreads); } @@ -137,30 +146,30 @@ namespace OpenSim m_log.InfoFormat("[OPENSIM MAIN]: Limiting max worker threads to {0}",workerThreads); } - // Increase the number of IOCP threads available. - // Mono defaults to a tragically low number (24 on 6-core / 8GB Fedora 17) - if (iocpThreads < iocpThreadsMin) + // Increase the number of IOCP threads available. + // Mono defaults to a tragically low number (24 on 6-core / 8GB Fedora 17) + if (iocpThreads < iocpThreadsMin) { iocpThreads = iocpThreadsMin; m_log.InfoFormat("[OPENSIM MAIN]: Bumping up max IOCP threads to {0}",iocpThreads); } - // Make sure we don't overallocate IOCP threads and thrash system resources + // Make sure we don't overallocate IOCP threads and thrash system resources if ( iocpThreads > iocpThreadsMax ) { iocpThreads = iocpThreadsMax; m_log.InfoFormat("[OPENSIM MAIN]: Limiting max IOCP completion threads to {0}",iocpThreads); } - // set the resulting worker and IO completion thread counts back to ThreadPool + // set the resulting worker and IO completion thread counts back to ThreadPool if ( System.Threading.ThreadPool.SetMaxThreads(workerThreads, iocpThreads) ) - { - m_log.InfoFormat( + { + m_log.InfoFormat( "[OPENSIM MAIN]: Threadpool set to {0} max worker threads and {1} max IOCP threads", workerThreads, iocpThreads); - } - else - { - m_log.Warn("[OPENSIM MAIN]: Threadpool reconfiguration failed, runtime defaults still in effect."); - } + } + else + { + m_log.Warn("[OPENSIM MAIN]: Threadpool reconfiguration failed, runtime defaults still in effect."); + } // Check if the system is compatible with OpenSimulator. // Ensures that the minimum system requirements are met @@ -178,7 +187,7 @@ namespace OpenSim Culture.SetCurrentCulture(); // Validate that the user has the most basic configuration done - // If not, offer to do the most basic configuration for them warning them along the way of the importance of + // If not, offer to do the most basic configuration for them warning them along the way of the importance of // reading these files. /* m_log.Info("Checking for reguired configuration...\n"); @@ -187,13 +196,13 @@ namespace OpenSim || (File.Exists(Path.Combine(Util.configDir(), "opensim.ini"))) || (File.Exists(Path.Combine(Util.configDir(), "openSim.ini"))) || (File.Exists(Path.Combine(Util.configDir(), "Opensim.ini"))); - + bool StanaloneCommon_ProperCased = File.Exists(Path.Combine(Path.Combine(Util.configDir(), "config-include"), "StandaloneCommon.ini")); bool StanaloneCommon_lowercased = File.Exists(Path.Combine(Path.Combine(Util.configDir(), "config-include"), "standalonecommon.ini")); bool GridCommon_ProperCased = File.Exists(Path.Combine(Path.Combine(Util.configDir(), "config-include"), "GridCommon.ini")); bool GridCommon_lowerCased = File.Exists(Path.Combine(Path.Combine(Util.configDir(), "config-include"), "gridcommon.ini")); - if ((OpenSim_Ini) + if ((OpenSim_Ini) && ( (StanaloneCommon_ProperCased || StanaloneCommon_lowercased @@ -211,7 +220,7 @@ namespace OpenSim "yes"); if (resp == "yes") { - + if (!(OpenSim_Ini)) { try @@ -311,7 +320,7 @@ namespace OpenSim m_saveCrashDumps = configSource.Configs["Startup"].GetBoolean("save_crashes", false); // load Crash directory config - m_crashDir = configSource.Configs["Startup"].GetString("crash_dir", m_crashDir); + m_crashDir = configSource.Configs["Startup"].GetString("crash_dir", m_crashDir); if (background) { @@ -319,9 +328,9 @@ namespace OpenSim m_sim.Startup(); } else - { + { m_sim = new OpenSim(configSource); - + m_sim.Startup(); while (true) diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs index cf7db97..62bd4f4 100644 --- a/OpenSim/Region/Application/ConfigurationLoader.cs +++ b/OpenSim/Region/Application/ConfigurationLoader.cs @@ -43,10 +43,10 @@ namespace OpenSim public class ConfigurationLoader { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + /// /// Various Config settings the region needs to start - /// Physics Engine, Mesh Engine, GridMode, PhysicsPrim allowed, Neighbor, + /// Physics Engine, Mesh Engine, GridMode, PhysicsPrim allowed, Neighbor, /// StorageDLL, Storage Connection String, Estate connection String, Client Stack /// Standalone settings. /// @@ -154,14 +154,15 @@ namespace OpenSim } // Override distro settings with contents of inidirectory - string iniDirPath = Path.GetFullPath(Path.Combine(Util.configDir(), startupConfig.GetString("inidirectory", "config"))); + string iniDirName = startupConfig.GetString("inidirectory", "config"); + string iniDirPath = Path.Combine(Util.configDir(), iniDirName); if (Directory.Exists(iniDirPath)) { m_log.InfoFormat("[CONFIG]: Searching folder {0} for config ini files", iniDirPath); List overrideSources = new List(); - string[] fileEntries = Directory.GetFiles(iniDirPath); + string[] fileEntries = Directory.GetFiles(iniDirName); foreach (string filePath in fileEntries) { if (Path.GetExtension(filePath).ToLower() == ".ini") @@ -187,7 +188,7 @@ namespace OpenSim { iniFileExists = true; AddIncludes(overrideConfig, overrideSources); - } + } } m_config.Source.Merge(overrideConfig.Source); } @@ -197,7 +198,7 @@ namespace OpenSim { m_log.FatalFormat("[CONFIG]: Could not load any configuration"); Environment.Exit(1); - } + } else if (!iniFileExists) { m_log.FatalFormat("[CONFIG]: Could not load any configuration"); @@ -256,14 +257,14 @@ namespace OpenSim string path = Path.Combine(basepath, chunkWithoutWildcards); path = Path.GetFullPath(path) + chunkWithWildcards; string[] paths = Util.Glob(path); - + // If the include path contains no wildcards, then warn the user that it wasn't found. if (wildcardIndex == -1 && paths.Length == 0) { m_log.WarnFormat("[CONFIG]: Could not find include file {0}", path); } else - { + { foreach (string p in paths) { if (!sources.Contains(p)) @@ -347,13 +348,10 @@ namespace OpenSim config.Set("meshing", "Meshmerizer"); config.Set("physical_prim", true); config.Set("serverside_object_permissions", true); - config.Set("storage_prim_inventories", true); config.Set("startup_console_commands_file", String.Empty); config.Set("shutdown_console_commands_file", String.Empty); config.Set("DefaultScriptEngine", "XEngine"); config.Set("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll"); - // life doesn't really work without this - config.Set("EventQueue", true); } { @@ -379,11 +377,11 @@ namespace OpenSim m_configSettings.PhysicsEngine = startupConfig.GetString("physics"); m_configSettings.MeshEngineName = startupConfig.GetString("meshing"); - m_configSettings.ClientstackDll + m_configSettings.ClientstackDll = startupConfig.GetString("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll"); } m_networkServersInfo.loadFromConfiguration(m_config.Source); } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/Application/IApplicationPlugin.cs b/OpenSim/Region/Application/IApplicationPlugin.cs index a3fa66c..ff3f5d7 100644 --- a/OpenSim/Region/Application/IApplicationPlugin.cs +++ b/OpenSim/Region/Application/IApplicationPlugin.cs @@ -43,7 +43,7 @@ namespace OpenSim void Initialise(OpenSimBase openSim); /// - /// Called when the application loading is completed + /// Called when the application loading is completed /// void PostInitialise(); } diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 5af8194..fcc8717 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -26,12 +26,14 @@ */ using System; +using System.Threading; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; +using System.Runtime; using System.Text; using System.Text.RegularExpressions; using System.Timers; @@ -74,7 +76,7 @@ namespace OpenSim private string m_timedScript = "disabled"; private int m_timeInterval = 1200; - private Timer m_scriptTimer; + private System.Timers.Timer m_scriptTimer; public OpenSim(IConfigSource configSource) : base(configSource) { @@ -114,8 +116,8 @@ namespace OpenSim if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse(asyncCallMethodStr, out asyncCallMethod)) Util.FireAndForgetMethod = asyncCallMethod; - stpMinThreads = startupConfig.GetInt("MinPoolThreads", 15); - stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 300); + stpMinThreads = startupConfig.GetInt("MinPoolThreads", 2 ); + stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 25); m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) "); } @@ -123,8 +125,27 @@ namespace OpenSim Util.InitThreadPool(stpMinThreads, stpMaxThreads); m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod); + + m_log.InfoFormat("[OPENSIM MAIN] Running GC in {0} mode", GCSettings.IsServerGC ? "server":"workstation"); } +#if (_MONO) + private static Mono.Unix.UnixSignal[] signals; + + + private Thread signal_thread = new Thread (delegate () + { + while (true) + { + // Wait for a signal to be delivered + int index = Mono.Unix.UnixSignal.WaitAny (signals, -1); + + //Mono.Unix.Native.Signum signal = signals [index].Signum; + MainConsole.Instance.RunCommand("shutdown"); + } + }); +#endif + /// /// Performs initialisation of the scene, such as loading configuration from disk. /// @@ -134,6 +155,27 @@ namespace OpenSim m_log.Info("========================= STARTING OPENSIM ========================="); m_log.Info("===================================================================="); +#if (_MONO) + if(!Util.IsWindows()) + { + try + { + // linux mac os specifics + signals = new Mono.Unix.UnixSignal[] + { + new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGTERM) + }; + signal_thread.IsBackground = true; + signal_thread.Start(); + } + catch (Exception e) + { + m_log.Info("Could not set up UNIX signal handlers. SIGTERM will not"); + m_log.InfoFormat("shut down gracefully: {0}", e.Message); + m_log.Debug("Exception was: ", e); + } + } +#endif //m_log.InfoFormat("[OPENSIM MAIN]: GC Is Server GC: {0}", GCSettings.IsServerGC.ToString()); // http://msdn.microsoft.com/en-us/library/bb384202.aspx //GCSettings.LatencyMode = GCLatencyMode.Batch; @@ -172,10 +214,12 @@ namespace OpenSim MainServer.Instance.AddStreamHandler(new OpenSim.XSimStatusHandler(this)); if (userStatsURI != String.Empty) MainServer.Instance.AddStreamHandler(new OpenSim.UXSimStatusHandler(this)); + MainServer.Instance.AddStreamHandler(new OpenSim.SimRobotsHandler()); if (managedStatsURI != String.Empty) { string urlBase = String.Format("/{0}/", managedStatsURI); + StatsManager.StatsPassword = managedStatsPassword; MainServer.Instance.AddHTTPHandler(urlBase, StatsManager.HandleStatsRequest); m_log.InfoFormat("[OPENSIM] Enabling remote managed stats fetch. URL = {0}", urlBase); } @@ -217,7 +261,7 @@ namespace OpenSim // Start timer script (run a script every xx seconds) if (m_timedScript != "disabled") { - m_scriptTimer = new Timer(); + m_scriptTimer = new System.Timers.Timer(); m_scriptTimer.Enabled = true; m_scriptTimer.Interval = m_timeInterval*1000; m_scriptTimer.Elapsed += RunAutoTimerScript; @@ -238,55 +282,65 @@ namespace OpenSim m_console.Commands.AddCommand("General", false, "change region", "change region ", - "Change current console region", + "Change current console region", ChangeSelectedRegion); m_console.Commands.AddCommand("Archiving", false, "save xml", - "save xml", - "Save a region's data in XML format", + "save xml []", + "Save a region's data in XML format", SaveXml); m_console.Commands.AddCommand("Archiving", false, "save xml2", - "save xml2", - "Save a region's data in XML2 format", + "save xml2 []", + "Save a region's data in XML2 format", SaveXml2); m_console.Commands.AddCommand("Archiving", false, "load xml", - "load xml [-newIDs [ ]]", + "load xml [ [-newUID [ ]]]", "Load a region's data from XML format", LoadXml); m_console.Commands.AddCommand("Archiving", false, "load xml2", - "load xml2", - "Load a region's data from XML2 format", + "load xml2 []", + "Load a region's data from XML2 format", LoadXml2); m_console.Commands.AddCommand("Archiving", false, "save prims xml2", "save prims xml2 [ ]", - "Save named prim to XML2", + "Save named prim to XML2", SavePrimsXml2); m_console.Commands.AddCommand("Archiving", false, "load oar", - "load oar [--merge] [--skip-assets]" + "load oar [-m|--merge] [-s|--skip-assets]" + " [--default-user \"User Name\"]" + " [--force-terrain] [--force-parcels]" + " [--no-objects]" - + " [--rotation degrees] [--rotation-center \"\"]" - + " [--displacement \"\"]" + + " [--rotation degrees]" + + " [--bounding-origin \"\"]" + + " [--bounding-size \"\"]" + + " [--displacement \"\"]" + + " [-d|--debug]" + " []", "Load a region's data from an OAR archive.", "--merge will merge the OAR with the existing scene (suppresses terrain and parcel info loading).\n" + + "--skip-assets will load the OAR but ignore the assets it contains.\n" + "--default-user will use this user for any objects with an owner whose UUID is not found in the grid.\n" - + "--displacement will add this value to the position of every object loaded.\n" + "--force-terrain forces the loading of terrain from the oar (undoes suppression done by --merge).\n" + "--force-parcels forces the loading of parcels from the oar (undoes suppression done by --merge).\n" + "--no-objects suppresses the addition of any objects (good for loading only the terrain).\n" + "--rotation specified rotation to be applied to the oar. Specified in degrees.\n" - + "--rotation-center Location (relative to original OAR) to apply rotation. Default is <128,128,0>.\n" - + "--skip-assets will load the OAR but ignore the assets it contains.\n\n" + + "--bounding-origin will only place objects that after displacement and rotation fall within the bounding cube who's position starts at . Defaults to <0,0,0>.\n" + + "--bounding-size specifies the size of the bounding cube. The default is the size of the destination region and cannot be larger than this.\n" + + "--displacement will add this value to the position of every object loaded.\n" + + "--debug forces the archiver to display messages about where each object is being placed.\n\n" + "The path can be either a filesystem location or a URI.\n" - + " If this is not given then the command looks for an OAR named region.oar in the current directory.", - LoadOar); + + " If this is not given then the command looks for an OAR named region.oar in the current directory." + + " [--rotation-center \"\"] used to be an option, now it does nothing and will be removed soon." + + "When an OAR is being loaded, operations are applied in this order:\n" + + "1: Rotation (around the incoming OARs region center)\n" + + "2: Cropping (a bounding cube with origin and size)\n" + + "3: Displacement (setting offset coordinates within the destination region)", + LoadOar); ; m_console.Commands.AddCommand("Archiving", false, "save oar", //"save oar [-v|--version=] [-p|--profile=] []", @@ -307,12 +361,12 @@ namespace OpenSim m_console.Commands.AddCommand("Objects", false, "edit scale", "edit scale ", - "Change the scale of a named prim", + "Change the scale of a named prim", HandleEditScale); m_console.Commands.AddCommand("Objects", false, "rotate scene", "rotate scene [centerX, centerY]", - "Rotates all scene objects around centerX, centerY (defailt 128, 128) (please back up your region before using)", + "Rotates all scene objects around centerX, centerY (default 128, 128) (please back up your region before using)", HandleRotateScene); m_console.Commands.AddCommand("Objects", false, "scale scene", @@ -334,44 +388,44 @@ namespace OpenSim m_console.Commands.AddCommand("Users", false, "show users", "show users [full]", - "Show user data for users currently on the region", + "Show user data for users currently on the region", "Without the 'full' option, only users actually on the region are shown." + " With the 'full' option child agents of users in neighbouring regions are also shown.", HandleShow); m_console.Commands.AddCommand("Comms", false, "show connections", "show connections", - "Show connection data", + "Show connection data", HandleShow); m_console.Commands.AddCommand("Comms", false, "show circuits", "show circuits", - "Show agent circuit data", + "Show agent circuit data", HandleShow); m_console.Commands.AddCommand("Comms", false, "show pending-objects", "show pending-objects", - "Show # of objects on the pending queues of all scene viewers", + "Show # of objects on the pending queues of all scene viewers", HandleShow); m_console.Commands.AddCommand("General", false, "show modules", "show modules", - "Show module data", + "Show module data", HandleShow); m_console.Commands.AddCommand("Regions", false, "show regions", "show regions", - "Show region data", + "Show region data", HandleShow); - + m_console.Commands.AddCommand("Regions", false, "show ratings", "show ratings", - "Show rating data", + "Show rating data", HandleShow); m_console.Commands.AddCommand("Objects", false, "backup", "backup", - "Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", + "Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand); m_console.Commands.AddCommand("Regions", false, "create region", @@ -385,22 +439,22 @@ namespace OpenSim m_console.Commands.AddCommand("Regions", false, "restart", "restart", - "Restart the currently selected region(s) in this instance", + "Restart the currently selected region(s) in this instance", RunCommand); m_console.Commands.AddCommand("General", false, "command-script", "command-script