Compare commits

...

482 Commits

Author SHA1 Message Date
Robert Adams 0aa0dad478 Send multiple terrain patches per terrain update packet if terrain
draw distance optimization is enabled. Makes terrain editting a lot
snappier.
2014-06-01 19:23:49 -07:00
Diva Canto 3aa99b9a7f Fixes a permissions bug where a user with group powers to always rez was not being given permission to rez on group land. 2014-06-01 16:45:37 -07:00
Diva Canto 14a31c3e9b Correct minor bug regarding packing of estate bans 2014-06-01 12:01:49 -07:00
Diva Canto 94d0ae0d91 This may fix mantis #7200, but I am unable to test because I don't have any old viewers around anymore. 2014-06-01 10:18:53 -07:00
Diva Canto 0eaca7aafb Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-06-01 10:06:59 -07:00
Diva Canto 2ff9ea3f80 Fixed a few things pertaining to interfacing with the estate service. Specifically, StoreEstateSettings was not being used anywhere; instead EstatSetting.Save was being called, but that method is a trigger to the DB-layer code directly, which, besides being wrong, was making it impossible to replace the service with a remote connector.
Also added more packing/unpacking code.
2014-06-01 10:06:26 -07:00
Robert Adams a2ea844494 Move the generation of the multi-resolution map tiles off the main
region creation thread. For varregions or simulators with many regions,
this will speed up simulator startup and elimiate some thread timeout
warnings.
2014-05-31 14:21:39 -07:00
Robert Adams 0300ec45eb Modifications to debugging printouts. No functional changes. 2014-05-31 12:19:51 -07:00
Robert Adams 22dade6463 varregion: More tweeking to only sending patches within avatar draw distance.
Still has problems with child avatars.
2014-05-31 12:19:50 -07:00
Robert Adams db5a42ffac varregion: send terrain patches from where the avatar outward if the parameter
[Terrain]SendTerrainUpdatesByViewDistance=true.
This tracks which patches have been sent to each client and outputs the
patches as the avatar moves.
2014-05-31 12:19:49 -07:00
Diva Canto eaf595c008 Fix a bug where estate not found would result in a dummy estate record with erroneous information.
Also, added conversion of EstateSettings from/to key-value pairs in preparation for robust net work connectors.
2014-05-31 11:40:54 -07:00
Diva Canto d6f9f690e5 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-05-31 08:22:56 -07:00
Diva Canto 02a53665c9 Added missing reference 2014-05-31 08:22:36 -07:00
Justin Clark-Casey (justincc) bf5320eb26 minor: rename velocidyDiff -> velocityDiff 2014-05-30 22:21:13 +01:00
Justin Clark-Casey (justincc) 3c992b028c minor: Add some commented out logging to ScenePresence.SendTerseUpdateToAllClients() which is extremely helpful when investigating presence update triggers. 2014-05-30 22:18:07 +01:00
Justin Clark-Casey (justincc) a755c57b44 Fix issue with BulletSim avatar level flight jitter by commenting out RawVelocity update threshold for now in BSCharacter.UpdateProperties().
For some reason as yet unidentified (feedback?) a threshold above 0.4 here causes the RawVelocity to move between a lower and upper bound rather than remaining constant.
The RawVelocity increased until it triggered the threshold update, at which point it started to decrease until it again triggered the threshhold update.
This delta-v was enough to exceed the checks in ScenePresence.SendTerseUpdateToAllClients() and produce jittery avatar flight because of the fluctuating velocity.
With a threshold of 0.4 (or 0, as with ODE), the RawVelocity remains constant in BulletSim and so avatar flight becomes mostly smooth - remaining occasional glitches appear to be a result of errors in distance extraploation.
There are no obvious problems with commenting out the threshold.
Misterblue, if this is wrong or I've missed some subtlety here, please feel free to revert and/or correct.
The same considerations may or may not apply to object velocity updates.
2014-05-30 22:12:23 +01:00
dahlia 9ced61fbc2 Add a 0 parameter overload for RestClient.Request() for use when no auth is required. This preserves API compatibility for external modules using this function. 2014-05-30 13:47:19 -07:00
Diva Canto 0eede1467f Moved these two estate-related interfaces to the projects where they belong. 2014-05-30 13:11:46 -07:00
Justin Clark-Casey (justincc) 35c7fb2038 minor: Comment out log line in Groups V2 GroupsServicePostHandler for now which logs every request it receives. 2014-05-30 19:45:05 +01:00
Justin Clark-Casey (justincc) 8656b5e948 Fix bug where setting a parcel in a varregion for sale would make sale bitmap generation in WorldMapModule throw an exception on next startup.
This commit replaces the hardcoded region sizes in WorldMapModule.GenerateOverlay() with numbers pulled from m_scene.RegionInfo
2014-05-30 19:40:10 +01:00
BlueWall 1efaf0c85c Add some info about xbuild command line switches to clean and select between producing Debug or Release binaries 2014-05-30 11:56:05 -04:00
Justin Clark-Casey (justincc) 27597463da Change Assembly verson of OpenSim.Data.PGSQL.dll to 0.8.0.* to match all other assembly versions 2014-05-27 23:40:29 +01:00
Justin Clark-Casey (justincc) c32ccfb520 minor: Comment out 2 error level debugging message in authentication code 2014-05-27 23:18:33 +01:00
Justin Clark-Casey (justincc) 9ca86664bb Make RegionReady login disabled during initialization message a console messages instead of a warning message.
Same justification as earlier commit 996a6c2.  These are not warnings but should still be visible to the user at any log level.
2014-05-27 23:15:50 +01:00
Justin Clark-Casey (justincc) 464d31b70b Stop appending redundant newline to console messages in Robust and pCampbot configs
This is to fix an issue since recent commit fbcb763 where these are no longer removed automatically.
OpenSim.*.config was already not appending these newlines
2014-05-27 20:44:00 +01:00
Justin Clark-Casey (justincc) 5622cf68aa In compiler tests, remove the ResolveEventHandlers after test exit 2014-05-27 18:47:42 +01:00
Justin Clark-Casey (justincc) 394ec508f6 Make CompilerTest add same AssemblyResolver as XEngine to see if this solves the issue with different AppDomain BaseDirectory in local and Jenkins test runs 2014-05-27 18:37:16 +01:00
Justin Clark-Casey (justincc) bcaacb4e41 Temporarily print regression TestCastAndConcatString() script compile errors out to console to get a handle on what's going wrong.
Does not fail for me locally and I failed to notice this test was failing on Jenkins.
2014-05-27 18:19:08 +01:00
Justin Clark-Casey (justincc) d131c57978 Update regression TestInventoryDescendentsFetch() to account for recent commit 1fa3a6f
This was hidden in continuous integration because of another regression test issue.
2014-05-27 18:14:36 +01:00
Diva Canto 987c56984d Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-05-27 10:13:43 -07:00
Diva Canto e19c830a6c Fixes a bug where map search results pertaining to varregions would only send the SW-most corner of the varregions; the other areas, when clicked, would result a blue circle, meaning that the viewer didn't know about those areas. This is still not quite right, as all the areas appear to be in the same coordinates, but it's good enough for now. 2014-05-27 10:13:24 -07:00
Robert Adams fab0389cb1 BulletSim: add locking of PhysObjects while processing simulation
step updates and collisions. This is an attempt to fix a crash reported
by Justin when doing high velocity teleports.
2014-05-26 20:29:45 -07:00
Diva Canto d2877b9cd4 Don't report NPC presences. 2014-05-26 10:28:31 -07:00
Diva Canto b778bd9423 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-05-26 08:14:34 -07:00
Diva Canto 449548d7a4 Adds an optional redirect URL to the asset server handler for when assets are not found locally. 2014-05-26 08:13:49 -07:00
Oren Hurvitz 33cc847c4a When saving an OAR in "Publish" mode, also discard Group information 2014-05-26 15:33:13 +01:00
Oren Hurvitz 5aeaa7fcdd Prevent login to a region if the Telehub or Landing Point are in a banned parcel 2014-05-25 15:37:28 +01:00
Oren Hurvitz e68867c9b6 When taking an object into inventory, set the inventory item's "Next Owner" permissions according to the permissions of the items in the object 2014-05-25 15:35:00 +01:00
Oren Hurvitz 1fa3a6f1bd When creating a new user, create the folders "Current Outfit", "Favorites", and the standard subfolders of "Calling Cards".
(If we don't create them now then they'll be created later by the viewer, but why wait.)
2014-05-25 15:34:49 +01:00
Diva Canto ff9da24465 Added HTTP Authentication also to Groups and offline IM. 2014-05-23 17:31:39 -07:00
Diva Canto 227685bea4 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-05-23 16:20:04 -07:00
Diva Canto 20f20895cf Adds optional HTTP Basic Authentication to Robust service connectors. 2014-05-23 16:19:43 -07:00
Justin Clark-Casey (justincc) 9bae636ff0 Fix issues where reported LSL compiler error line numbers do not match the script.
This is probably due to changes in the layout of the generated script preamble (using statements etc, ) in c8afc852 (Jan 17 2013).
Re-enabled existing regression test that exercises at least one case of this.
2014-05-24 00:12:23 +01:00
Justin Clark-Casey (justincc) cf95b65c10 Get regression test TestUseUndeclaredVariable() functional again, though not yet enabled.
This reveals the position map problems and will make the fix (and subsequent continual checking) easier.
2014-05-23 22:29:47 +01:00
Justin Clark-Casey (justincc) 250ea09328 Reactivate regression test TestCastAndConcatString() in CompilerTests. 2014-05-23 22:12:49 +01:00
Justin Clark-Casey (justincc) b3a496d6f2 Add mikemig to contributors 2014-05-23 21:13:37 +01:00
Justin Clark-Casey (justincc) f55e153636 Compile the regex that extract categories for colourization just once rather than on every single log.
Compiling every time is unnecessary since Regex is thread-safe.
2014-05-23 21:09:48 +01:00
Justin Clark-Casey (justincc) fbcb76383d Allow console output to be multiline by making colourization regex RegexOptions.SingleLine 2014-05-23 20:57:50 +01:00
Justin Clark-Casey (justincc) 72c67c5091 Fix possible infinite recursion in MessageTransferModule.SendGridInstantMessageViaXMLRPCAsync() whilst preserving retry lookup behaviour.
This is based on heavily mikemig's original patch in http://opensimulator.org/mantis/view.php?id=7149
but instead of exiting after the first IM delivery failure to presence information retrieved from the presence service
it will retry the lookup until the result matches the previous lookup.
This is to deal with the case where the agent is sent an IM whilst they are teleporting.
2014-05-23 20:14:49 +01:00
Justin Clark-Casey (justincc) 5015b0b485 If one is sitting on a child with an unset camera-eye and so using one set in a root prim, the focus should remain on the root prim.
Matches behaviour just tested on the Linden grid.
2014-05-23 01:55:05 +01:00
Justin Clark-Casey (justincc) c78a8271c4 Add any camera at compensation for sat upon child prims to any existing camera-at value, rather than replace. 2014-05-23 01:38:05 +01:00
Justin Clark-Casey (justincc) fbed245596 Compensate camera-at and camera-eye for child prim rotation when sitting on child prim with camera-eye set 2014-05-23 01:34:02 +01:00
Justin Clark-Casey (justincc) 174df94172 If a script calls llSetCameraAtOffset() or llSetCameraEyeOffset() on a child prim and the root prim has no corresponding value set, then also set the root prim.
This matches behaviour just tested on the Linden Lab grid.
2014-05-22 23:58:28 +01:00
Justin Clark-Casey (justincc) 3fbaef9275 If the root prim has a camera-at or camera-eye setting and a sat upon child prim does not, use the root prim offsets.
This matches behaviour just tested on the Linden Lab grid.
2014-05-22 23:52:28 +01:00
Justin Clark-Casey (justincc) 16bf38e1ab Fix issue where llSetCameraAtOffset() and llSetCameraEyeOffset() in non-root prims moved camera/focus to wrong position.
For non-root prim, eye offsets now need to be made relative to root prim if either camera-at or camera-eye are set.
Probably a regression since November 2013 when all sits were made relative to root prim to match viewer expections (and fix other bugs).
Addresses http://opensimulator.org/mantis/view.php?id=7176
2014-05-22 23:39:22 +01:00
Justin Clark-Casey (justincc) f8b8241239 Add regression test for north-south chat across neighbour regions. 2014-05-22 20:28:26 +01:00
Justin Clark-Casey (justincc) bffc9ad184 Extend regression TestInterRegionChatDistanceEastWest() to test out of range chat 2014-05-22 20:04:32 +01:00
Justin Clark-Casey (justincc) 15b50ae737 Extend regression TestInterRegionChatDistanceEastWest() to test in range chat both ways. 2014-05-22 19:55:34 +01:00
Justin Clark-Casey (justincc) 65a135f4d3 Simplify regression TestInterRegionChatDistanceEastWest() by making the child presence connection directly rather than routing through TestClient.
This code isn't relevant to this test and is already exercised by other tests.
2014-05-22 19:47:33 +01:00
Justin Clark-Casey (justincc) 1b156b7fe8 Add regression test for in-range chat between neighbouring regions from east to west. 2014-05-22 19:18:24 +01:00
Diva Canto b7c7293c7a Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-05-22 10:16:19 -07:00
Diva Canto f7b2aa0f49 Fixed a problem with detaching attachments in situations where the user's asset server is not the same as the simulator's asset server. Unfortunately this still continues to be wasteful -- new assets are created every time an attachment is detached, but the process of storing the new asset goes through the InventoryAccess module, which does all sorts of checks regarding the users' inventory. 2014-05-22 10:16:01 -07:00
AliciaRaven 04aa13a086 Fix mantis 6973. Prevent BOM being prefixed to message XML which was causing an exception when the service tried to read the data later on.
Signed-off-by: Oren Hurvitz <orenh@kitely.com>
2014-05-22 13:16:14 +01:00
Oren Hurvitz 251b93d97e Store the Teleport Flags in the Circuit. This doesn't seem to be necessary, because everything has worked so far, but it's the right thing to do. 2014-05-22 13:16:06 +01:00
Oren Hurvitz a1b291c889 Allow map searches for regions that contain the characters "!+|"
These characters are used as placeholders for other characters: ": /". But we should search first for the exact string the user entered, and only if that fails then replace the characters and search again.
2014-05-21 07:39:23 +01:00
Justin Clark-Casey (justincc) 5b433e101d minor: Comment out currently unused log setup in TerrainCompressor 2014-05-20 23:59:08 +01:00
Justin Clark-Casey (justincc) d93275745b minor: Remove some unused fields in ScenePresence 2014-05-20 23:57:03 +01:00
Justin Clark-Casey (justincc) 32070fa5f4 minor: remove compiler warning in SceneObjectPartInventory 2014-05-20 23:54:49 +01:00
Justin Clark-Casey (justincc) 9479f64778 Fix issue where avatar and script chat could sometimes be heard from anywhere in neighbouring regions.
This was due to a silent uint overflow in ScenePresence.UpdateChildAgent() corrupting child agent positions
when the child agent was in a region with a greater x or y map co-ord than the root agent region
Probably introduced in beeec1c.
This still will not function properly with very high region map co-ords (in the millions) but other parts of the code don't handle this properly anyway.
Looks to address http://opensimulator.org/mantis/view.php?id=7163
2014-05-20 23:52:07 +01:00
Justin Clark-Casey (justincc) 5ec3429843 On verbose groups messaging logging, count all operations in reported time when sending group messages, not just those after get group members and get presence status, as applicable 2014-05-19 23:01:48 +01:00
Justin Clark-Casey (justincc) 77a331fce3 Add DebugMessagingEnabled = false to OpenSim.ini.example for consistency. Slightly simplify config comments. 2014-05-19 23:00:04 +01:00
Justin Clark-Casey (justincc) b46be88db6 Split verbose groups messaging logging into its own setting separate from that of the groups module.
This is to allow us to get useful information on messaging without being overwhelmed by the rest of groups debug.
Enabled with [Groups] DebugMessagingEnabled = true in config (default false)
Or "debug groups messaging verbose true|false on the console" (similar to existing groups setting).
Done for both xmlrpc and V2 groups.
2014-05-19 22:45:17 +01:00
Justin Clark-Casey (justincc) 3a6f312484 Fix recent regression from 77e7bbc where an attachment on a received group notice with XmlRpcGroups messaging did not appear in the user's inventory.
This was because the "session ID" when the message template was copied was always replaced with the group ID, whereas a notice requires this to be the notice ID.
Instead just copy the "session ID" as is - other callers already have this set properly so replacing with group ID was redundant anyway.
Relates to http://opensimulator.org/mantis/view.php?id=7037
2014-05-19 22:06:41 +01:00
Oren Hurvitz 47b84875fd Tell QueryAccess explicitly whether the user is coming in via Teleport or Cross, because the permission checks are different.
Previously we used a heuristic of checking if the entry position is 0 to differentiate between Teleport and Cross, but that doesn't work anymore since we've started providing the precise entry position for cross, too. That's required in order to ensure that the user is allowed to enter the parcel that he's walking into.
2014-05-19 11:19:11 +01:00
Oren Hurvitz 78733b979f Log the user when an inventory operation is blocked because the item/folder isn't in the Suitcase 2014-05-19 11:12:53 +01:00
Oren Hurvitz dd30a29ba0 Return more specific error messages if an attempt to enter a region fails due to permissions (in QueryAccess and IsAuthorizedForRegion) 2014-05-19 11:11:30 +01:00
Oren Hurvitz 882af7195c Better error-handling and logging in case User Profile requests fail 2014-05-19 11:11:06 +01:00
Oren Hurvitz 96e5836b50 When can't rez, show only one error message; not two. And show more specific error messages. 2014-05-19 10:54:27 +01:00
Diva Canto ab1472e5b7 Don't trigger ItemUploaded when no item has been uploaded. 2014-05-18 23:01:55 -07:00
Diva Canto 922f76a3a7 Don't fetch assets from the server when doing simple inventory operations like copy-paste items in inventory. 2014-05-18 07:49:01 -07:00
Robert Adams 0be9e3b079 BulletSim: adjust avatar step up parameters to better walk up small
staircases. This change is required because of the change in the
avatar default shape from the capsule to the rectangle.
2014-05-17 20:11:22 -07:00
Justin Clark-Casey (justincc) 4a74c4533c minor: eliminate now unnecessary string.Format in postgresql RetrieveGroups method 2014-05-15 22:51:47 +01:00
Justin Clark-Casey (justincc) d2c738fc09 Don't warn on not seeing [Groups] Robust section for core groups as this does not contain any mandatory parameters and won't be present on older installations. 2014-05-15 22:48:05 +01:00
Justin Clark-Casey (justincc) 6dc1b113d0 Escape find string in PgSQL core groups plugin 2014-05-15 22:45:01 +01:00
Justin Clark-Casey (justincc) d32d25634d Escape find string in MySQL core groups plugin 2014-05-15 22:09:37 +01:00
Justin Clark-Casey (justincc) 7c12dfe185 On ScenePresence.MakeChildAgent(), reset the m_originRegionID as this is currently being used as a flag to orchestrate destination simulator threads on teleport.
If not reset, it's possible that teleports back and forth between simulators may not restart scripts in attachments.
2014-05-14 22:08:06 +01:00
Justin Clark-Casey (justincc) 2f7539a25b Remove a race where the client's SP.CompleteMovement() thread could attempt to restart attachment scripts before the source simulator's SP.UpdateAgent() thread had added them.
This commit changes the order of code so that attachments are re-added before the CompleteMovement() thread is released.
Relates to http://opensimulator.org/mantis/view.php?id=7148
2014-05-14 21:49:29 +01:00
Justin Clark-Casey (justincc) 0c0ee95bd8 minor: Clean up and make consistent some log file messages in EstateManagementModule relating to RAW file uploading. 2014-05-14 19:22:55 +01:00
Justin Clark-Casey (justincc) c23d37a509 Fix recent asset request timeout issue by commenting out (for now) the m_maxAssetRequestConcurrency mistakenly passed in as a timeout to SynchronousRestObjectRequester.MakeRequest()
For a long time, possibly forever, the m_maxAssetRequestConcurrency was mistakenly passed in as a 30 ms timeout rather than as a concurrent connection limiter.
This didn't come to light until the timeout was actually used in recent commit faf9ba53
Since this hasn't been operational for a long time and in release candidate phase, commenting it out for now though will need to revisit this.
Relates to http://opensimulator.org/mantis/view.php?id=7165
2014-05-14 00:11:07 +01:00
Justin Clark-Casey (justincc) 4569c595bf Fix behaviour change in recent commit bbc1dc6 so that SynchronousRestObjectRequester.MakeRequest() calls with no timeout specified use the default HttpWebRequest timeout as previously.
I mistakenly thought that that default request timeout was inifite rather than 100 seconds, restoring previously behaviour.
As per http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.timeout%28v=vs.100%29.aspx
Relates to http://opensimulator.org/mantis/view.php?id=7165
2014-05-13 22:21:20 +01:00
Justin Clark-Casey (justincc) 484aa72ff8 minor: Add some method doc to IMessageTransferModule 2014-05-12 23:49:37 +01:00
Justin Clark-Casey (justincc) 8ad29fc5c8 Make offline IM delivery to URL (pre recent Addons code) have a 10 second rather than infinite timeout.
This both signals a problem with the URL and eventually frees the thread, rather than hanging indefinitely with no information.
2014-05-12 23:42:47 +01:00
Justin Clark-Casey (justincc) 87e2668529 For XmlRpcGroups (Flotsam) module, when MessageOnlineUsersOnly = true, handle notices to offline users directly as known undeliverable messages rather than discarding or attempting delivery.
Offline notices can still be controlled with the [Messaging] ForwardOfflineGroupMessages setting.
Looks to address more of http://opensimulator.org/mantis/view.php?id=7037
Only for Flotsam now for testing, but if approach works should be possible with core offline notices as well.
2014-05-12 23:38:48 +01:00
Justin Clark-Casey (justincc) 515d373a8e Add send group notice regression test for when MessageOnlineUsersOnly=true 2014-05-12 22:54:54 +01:00
Justin Clark-Casey (justincc) bbc1dc6bce Replace existing 0 timeout in internal overloaded SynchronousRestObjectRequester.MakeRequest() methods with proper Timeout.Infinite (-1) instead.
Triggered by recent faf9ba53 though this was wrong in the code before, it's just that we didn't actually try to set the timeout given.
2014-05-12 22:37:07 +01:00
Justin Clark-Casey (justincc) 8457044b2f Eliminate subsequently unused scene finding in UndeliveredMessage() method of xmlrpc and core offline IM modules 2014-05-12 22:23:24 +01:00
Justin Clark-Casey (justincc) 19d8f05584 minor: eliminate unused UUID in xmlrpc GroupsMessagingModule.ProcessMessageFromGroupSession() 2014-05-12 22:15:01 +01:00
Justin Clark-Casey (justincc) 7db4336f1c minor: Add method doc to SynchronousRestObjectRequester.MakeRequest() methods 2014-05-12 22:05:02 +01:00
Justin Clark-Casey (justincc) faf9ba53fc In SynchronousRestObjectRequester.MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout, int maxConnections) actually set timeout on WebRequest if given.
Previously, we were doing nothing with this parameter.
No effect on current code since none of the 6 callers attempt to use the timeout.
2014-05-12 19:20:00 +01:00
Oren Hurvitz bf8f64e40e Fixed error if a user didn't have a "Current Outfit" folder in their suitcase.
This fixes http://opensimulator.org/mantis/view.php?id=7161
2014-05-12 08:54:31 +03:00
Diva Canto 73891c7fd3 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-05-09 11:06:33 -07:00
Diva Canto 667a272cce This little sucker had evaded my attention forever. As a consequence some assets associated with foreign users were being missed. 2014-05-09 11:06:03 -07:00
Justin Clark-Casey (justincc) f41809e07d minor: Capitalize Hypergrid help category like others 2014-05-08 22:39:52 +01:00
Diva Canto afb938e579 Fix test breakage 2014-05-08 11:30:45 -07:00
Diva Canto a31393ba0b Make the URL for texture redirects match the path of the resource that we use in OpenSim. 2014-05-08 11:18:17 -07:00
Diva Canto a845c1a893 Finished implementing redirects in GetTexture. 2014-05-07 19:38:33 -07:00
Diva Canto 093705efd1 Delete extraneous console message in the Configger. 2014-05-07 17:19:57 -07:00
Diva Canto f4cba27105 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-05-07 17:00:12 -07:00
Diva Canto 3db9b847bf Allow Tools.Configger to take -inifile as argument 2014-05-07 16:59:11 -07:00
Justin Clark-Casey (justincc) 2b33677402 Add GridUserService service config to [UserAccountService] in Robust[.HG].ini.example so that home can be set for new users rather than always warning that it can't be set.
Code already exists to do this but forgot to put entry into config files a long time ago.
Thanks to AliciaRaven for the spot.
Relates to http://opensimulator.org/mantis/view.php?id=7155
2014-05-07 23:32:02 +01:00
Justin Clark-Casey (justincc) 812f5e124d Remove duplicate HypergridLinker entry from [GridService] in Robust.HG.ini.example 2014-05-07 18:39:56 +01:00
Justin Clark-Casey (justincc) 2fbafc7465 Add Matt Lehmann to contributors 2014-05-06 22:37:26 +01:00
Justin Clark-Casey (justincc) e44450cce1 Revert "fix infinite recursion loop in SendGridInstantMessageViaXMLRPCAsync()"
There is a problem here with infinite recursion, but this patch loses the 'hunting' behaviour where the code will attempt multiple lookups if the avatar is teleporting rapidly around different simulators.
This patch only does a single lookup before giving up.

This reverts commit cecb446e0e.
2014-05-06 19:53:35 +01:00
Dev Random 78015bbbdc Console commands for Estate Mgmt 2014-05-06 18:55:42 +01:00
Matt Lehmann 9e83b43009 new version of patch to add default-user switch new version :qw :wq updated version of default user switch for load oar :q :q 2014-05-06 18:48:59 +01:00
Matt Lehmann 8b3c2f7d0c updated version of default user switch for load oar :q :q 2014-05-06 18:48:42 +01:00
Kunta Kinte cecb446e0e fix infinite recursion loop in SendGridInstantMessageViaXMLRPCAsync() 2014-05-06 17:52:32 +01:00
Vegaslon 0faba7dc33 Fix avatars going to corner of region when they are sitting on a child prim and the prim is deleted. 2014-05-06 17:41:13 +01:00
Vegaslon e245638f24 Change llUnSit to be able to unsit any avatar that is currently sat on the object, not just avatars sitting on the sittarget in the object containing the script. or when the object is owned by the parcel, land group or estate owner. 2014-05-06 17:35:34 +01:00
Talun c9742c826d Mantis 7146 The lsl function llGetMassMKS is not implemented
This patch implements llGetMassMKS as it is described in the wiki
http://wiki.secondlife.com/wiki/LlGetMassMKS
2014-05-06 17:31:21 +01:00
Justin Clark-Casey (justincc) 539165e6bd minor: Change configuration text in config files to reflect the existing situation of BulletSim as the default physics engine. 2014-05-06 17:28:21 +01:00
Justin Clark-Casey (justincc) 95eeb4dde8 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-05-06 17:22:47 +01:00
Oren Hurvitz ef262799ca Better error handling in AssetServerPostHandler. Invalid XML causes an InvalidOperationException, not an XmlException 2014-05-06 09:43:07 +03:00
Oren Hurvitz 614b9e14c4 When moving an item from a prim to a user's inventory, don't delete the item from the prim until it was successfully copied to the user 2014-05-06 07:28:46 +01:00
Oren Hurvitz eb79c882ea Show more meaningful error messages when failed to move an item from a prim to a user's inventory.
Also, actually show the error to the user in more cases. (Previously, sometimes the operation failed without telling the user anything.)
2014-05-06 07:28:45 +01:00
Oren Hurvitz 1e5cff32fc Show more meaningful error messages when failed to give an item to another user 2014-05-06 07:28:44 +01:00
Oren Hurvitz df49196e17 Log whenever an inventory operation is blocked because the item/folder isn't in the Suitcase 2014-05-06 07:28:43 +01:00
Oren Hurvitz 0fe08c8799 - When sending the "My Suitcase" folder to the client, always claim it has Folder Type 8. (Previously we had used Folder Type -1 in one place, and LLClientView didn't even bother changing Folder Type 100 to anything else.) 2014-05-06 07:16:37 +01:00
Oren Hurvitz 7862d1e20d Added range-checking for the parameters to PRIM_POINT_LIGHT (used in llSetLinkPrimitiveParamsFast() ) 2014-05-06 07:14:58 +01:00
Diva Canto 13b2ac1425 Makes it possible to support grids in which all the simulators share all central services of a Robust server EXCEPT assets. In other words, grids where the simulators' assets are kept in one DB and the users' inventory assets
are kept on another. When users rez items from inventory or take objects from world, an HG-like asset copy takes place between the 2 servers, the world asset server and the user's asset server. This makes the simulators independent of the central asset server.

Note that this an advanced configuration and requires some security strengthening coming up.
2014-05-04 20:54:42 -07:00
Diva Canto 7f570636f8 Please note: older simulators (0.7.6) still send the info about gzip in ContentType 2014-05-04 11:41:52 -07:00
Diva Canto 5a10da3ee8 Added a optional key between the group remote connectors, sim and service. This allows for more secure group services, to be used by collections of mutually-trusting grids. 2014-05-03 17:13:53 -07:00
Justin Clark-Casey (justincc) 53b72ab4b8 minor: Comment out Cacheitems debug log lines for now 2014-05-02 13:31:58 +01:00
Talun 3a2c099169 Mantis 7144 missing ATTACH_AVATAR_CENTER constant
This patch adds ATTACH_AVATAR_CENTER and ATTACH_NECK
2014-05-01 23:20:31 +01:00
Justin Clark-Casey (justincc) c31d93cb6f Fix issue where only one of multiple attachments on the same attachpoint for NPCs would be seen by other viewers.
It appears that at least Singularity 1.8.5 (but probably others) rely on attachment FromItemIDs being different to display more than one.
This commit resolves this by generating random IDs instead of always using UUID.Zero for NPCs.
Resolves http://opensimulator.org/mantis/view.php?id=7110
2014-05-01 22:24:21 +01:00
Justin Clark-Casey (justincc) f0411dc128 minor: Use Vector2.Zero constant and only set in condition branch where it was missing in TryParseConsole2DVector(). xbuild still compiles. 2014-04-30 21:50:18 +01:00
Melanie 7c121a2acc Change XEngine to call StateChange rather than RemoveScript on state changes 2014-04-30 20:56:49 +01:00
Melanie f0eeb47262 Add the "StateChange" function to the async comand manager to differentiate
between state changes and script exit/reset.
2014-04-30 20:54:34 +01:00
BlueWall 44f533d95a Assign value to 'vector' to fix building under xbuild and Monodevelop 2014-04-30 15:45:00 -04:00
Justin Clark-Casey (justincc) 7bb673a854 minor: Correct mistake in terrain flip error message from previous commit 5d01a1f 2014-04-30 19:41:11 +01:00
Justin Clark-Casey (justincc) 5d01a1ff4d minor: Print output in response to terrain console commands on the console rather than in the log. 2014-04-30 19:24:17 +01:00
Justin Clark-Casey (justincc) 253110293a Add "terrain show" console command which outputs terrain height for a given region co-ordinate.
For debug purposes.
2014-04-30 18:04:47 +01:00
Justin Clark-Casey (justincc) 5fc61942e0 minor: convert back some tabs to spaces that got into ScenePresence via recent patch bc969a6b 2014-04-29 20:15:29 +01:00
Justin Clark-Casey (justincc) d4eee213a9 Restore terrain height and flying adjustments that were eliminated from non-megaregion paths in ScenePresence.MoveToTarget() by recent patch bc969a6b 2014-04-29 20:05:08 +01:00
Justin Clark-Casey (justincc) 2dbc18054e Add regression test for NPC movement on a variable region.
Extends basic physics to allow av movement on a varregion (basic physics is only really useful for regression test purposes).
2014-04-29 19:29:16 +01:00
Oren Hurvitz 88f7a833dc Improved HTTP logging 2014-04-29 07:59:17 +01:00
Oren Hurvitz 06e4fcd260 Fixed the UpdateAgentInformation CAP: the viewer expects the simulator to echo back the maturity that it sent
Without this change, attempts to change the maturity rating in the viewer's Preferences don't work.
2014-04-29 07:59:10 +01:00
Robert Adams df89e15290 BulletSim: non-functional changes to debugging statements and formatting. 2014-04-28 18:36:50 -07:00
Robert Adams 63aea3a5f2 BUlletSim: move safeynet ground plane to lower altitude. Define new BulletSim
parameter 'TerrainGroundPlane' which defaults to -500.

BulletSim had assumed altitudes never went negative but that is not true. The
ground plane is just a safety net so things wouldn't fall to infinity.
2014-04-28 11:08:47 -07:00
Oren Hurvitz cb8c3ba023 Removed dependency on Linq in OpenProfileClient 2014-04-28 16:41:02 +01:00
Justin Clark-Casey (justincc) 2e216aa056 Add missing [Test] decorator to actually get the basic scene creation test from 2227f51b to run 2014-04-25 23:35:20 +01:00
Justin Clark-Casey (justincc) 9664273df6 Add basic regression test for creating a var region 2014-04-25 23:34:30 +01:00
Justin Clark-Casey (justincc) 2227f51b29 Add basic sanity regression test for creating a scene. 2014-04-25 23:16:07 +01:00
Justin Clark-Casey (justincc) 38acda9f29 Add regression test for terrain fill at two digit height and max ll height. 2014-04-25 23:01:24 +01:00
Justin Clark-Casey (justincc) 904baa6da6 Fix issue where terrain height values > 327 caused chaotic spiked terrain.
Per http://wiki.secondlife.com/wiki/Tips_for_Creating_Heightfields_and_Details_on_Terrain_RAW_Files#Notes_for_Creating_Height_Field_Maps_for_Second_Life
terrain heights up to 508 are possible on the LL grid (and were available on previous releases of OpenSimulator).
The obvious way to allow both this and equivalent -z values, is to rewiden the internal terrain height storage from short to int.
The memory tradeoff is most noticeable on the maximum 8192x8192 var region (equiv to 1024 normal regions), where it adds 128mb to resident use (128k on a normal region)
This is still better than the double used in previous releases.
This does not affect physics or data storage since they already use float and double respectively.
This may not be the final solution if we actually want to sacrifice -z, >327 or something else.
Relates to http://opensimulator.org/mantis/view.php?id=7076
2014-04-25 22:56:25 +01:00
Melanie a108fcac95 Restore overload mode accidentally disabled in a prior commit. Add a new
config option, LogOverloads, to log when a thread pool overload occurs.
This option defaults to "True" because the logging data is useful for
diagnosing threading issues.
2014-04-25 21:34:29 +01:00
Melanie 2572ed9ed9 Adjust permissions to work hand in hand with what the viewer believes they are.
This fixes the issue of "Show in Search" seeming resetting at random.
2014-04-25 00:35:53 +01:00
Diva Canto cf54df3ecf Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-04-24 14:12:04 -07:00
Diva Canto 1d9a9e6004 Fixes a long-standing bug related to god-mode change ownership of objects permissive, where the permissions of the children prims' inventory items were not changed. As a consequence, we couldn't control some of the objects imported via HG and OARs even in god mode. 2014-04-24 14:11:42 -07:00
Oren Hurvitz 0d898d8d8a Revert "When linking a Hypergrid region, set the region's flags on the in-memory GridRegion immediately."
This reverts commit 463d0b2f8f.
2014-04-24 19:08:50 +03:00
Oren Hurvitz 463d0b2f8f When linking a Hypergrid region, set the region's flags on the in-memory GridRegion immediately.
(When using llTeleportAgent() this *specific* object is used for the teleport, so it should have the correct flags.)
2014-04-24 16:58:16 +01:00
Oren Hurvitz bc06db3df4 - Created a standard function to send XML-RPC requests, which logs them like we do for other types of HTTP activity.
- Changed OpenProfileClient to use the new XML-RPC sending function
- Improved logging in WebUtil
2014-04-24 15:58:43 +01:00
Oren Hurvitz e8a2eff2e8 Changed how UserProfile performs a fallback call using the OpenProfile API, because now JsonRpcRequest() returns an error result instead of throwing an exception 2014-04-24 15:58:43 +01:00
Oren Hurvitz d62f0bc35d Refactored: moved OpenProfileClient to a location where it can be used by both the Simulators and Robust 2014-04-24 15:58:42 +01:00
Oren Hurvitz d15a3b10a3 When sending JSON-RPC calls (for UserProfile), use WebUtil instead of constructing the HTTP requests manually. This allows the calls to be logged when using "debug http all 6". 2014-04-24 15:58:41 +01:00
Oren Hurvitz 6efc203ce8 Fixed: hypergrid-linking stopped accepting the following format: "http://grid.example.com" (without a region name)
Fixes http://opensimulator.org/mantis/view.php?id=7128
2014-04-24 06:19:57 +01:00
Oren Hurvitz d1865c526d Removed unused CsharpSqlite DLLs 2014-04-24 06:19:49 +01:00
Melanie 98c1940820 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2014-04-24 01:48:05 +01:00
Melanie 5dc0298f83 Apply logging flag to a spammy message that may have been overlooked.
No one needs to see every thread launch.....
2014-04-24 01:44:11 +01:00
Dev Random 7180690a14 Show Group name when land is group-owned 2014-04-23 23:29:17 +01:00
Michael Cerquoni 0b743045ef Add Dev Random to CONTRIBUTORS.txt, thanks for the patches! 2014-04-23 17:51:26 -04:00
Justin Clark-Casey (justincc) 5092cbd77e minor: Remove unused System.Linq reference and use ParcelFlags.None instead of 0 from previous commit cb1f28 2014-04-23 19:55:51 +01:00
Dev Random cb1f2886cd Prevent sending Land Properties for unprivileged users 2014-04-23 19:50:59 +01:00
Justin Clark-Casey (justincc) 7a5699224e Fix regression test break on previous commit 328bc3b 2014-04-23 19:46:58 +01:00
Justin Clark-Casey (justincc) 328bc3b76e Adjust avatar sit positioning on a target to pretty much exactly match that of the LL grid.
This uses an offset of 0.05 on the up vector of the sit orientation, after extensive analysis on
http://opensimulator.org/mantis/view.php?id=7096 and https://wiki.secondlife.com/wiki/Talk:LlSitTarget
This supersedes the previous adjustment in 5b73b9c4 which had been wrongly applied.
The maximum change is about 0.1 with a maximum height avatar.
This patch is all Aleric's work - I am applying manually in order to add these additional notes
2014-04-23 19:19:09 +01:00
Oren Hurvitz b01e73cf27 Dynamic textures shouldn't be saved in the assets service (only in the simulator cache) 2014-04-23 14:42:40 +01:00
Oren Hurvitz 7eb12f96ec Hypergrid: don't send Local assets to other grids
This commit also contains other changes, but they're all just for clarity. The only actual behavior change is to avoid Posting local assets.
2014-04-23 16:42:23 +03:00
Oren Hurvitz 2506b3d89e Removed references to Community.CsharpSqlite*.dll. This eliminates some warnings, and SQLite still works. 2014-04-23 14:38:41 +01:00
Oren Hurvitz 018832522c Removed GetUserInventory(). It wasn't being used, and was creating warnings because it's Obsolete. 2014-04-23 14:38:33 +01:00
Oren Hurvitz ca78c8326e Eliminated 'Obsolete' warning: don't call do-nothing function SetPreviousAppearance() 2014-04-23 14:38:04 +01:00
Oren Hurvitz 998d7009a6 Eliminated many warnings 2014-04-23 16:37:36 +03:00
Oren Hurvitz 617bc4710a Workaround for SRAS: if Store Asset returns 'null' then assume the asset already exists, and this isn't an error 2014-04-23 14:19:24 +01:00
Oren Hurvitz 2c9859314f Changed table 'im_offline' to use UTF8 characters. This fixes a problem with Offline IM V2 (only relevant to MySQL).
This fixes http://opensimulator.org/mantis/view.php?id=7123

Users that use MySQL should change their MySQL configuration to support UTF8. In the config file /etc/my.cnf (Linux) or my.ini (Windows), add these settings:

   [mysqld]
   character-set-server=utf8

   [client]
   default-character-set=utf8

And then restart MySQL (on Linux: "sudo service mysqld restart").
2014-04-23 16:18:28 +03:00
Melanie eb5bfd14fa Reverting test change to cause another email 2014-04-23 12:49:28 +01:00
Melanie 85f4357ce6 Test commit to trigger a mailing list update 2014-04-23 12:44:43 +01:00
Oren Hurvitz a893fd90cd Fixed KeyframeMotion to work with very slow movement.
Previously, if the movement speed was below 0.05/sec then it didn't work correctly.

Fixes http://opensimulator.org/mantis/view.php?id=7117
2014-04-22 10:19:11 +01:00
Oren Hurvitz 93a9ed2a6d Changed the maximum asset name and description lengths to constants. Also, pre-truncate the description of dynamic textures. 2014-04-22 12:18:54 +03:00
Oren Hurvitz 4cac87d9f4 Fixed: when a user logged-in, sometimes he didn't get notified of the Online status of friends, so they continued to appear Offline.
This happened because these notifications (the UDP packets) can only be sent to Root Agents. But the notifications were done in OnClientLogin(), at which point the client is still a Child Agent. Since a FireAndForget is used, it became a race condition as to whether the packets would be sent before or after the client became a Root Agent.

To fix this, we now only send the notifications once the client becomes a Root Agent for the first time.
2014-04-21 16:56:49 +01:00
Oren Hurvitz 538ff31b28 Better error handling when retrieving offline IMs 2014-04-21 16:56:26 +01:00
Oren Hurvitz 06db136fbc Removed an attempt to set a user's presence to "Region 0" when they HG teleport to another grid.
a) This shouldn't have been done because at that point the user is still logged-in to the current grid. b) It's not necessary because the user will soon be logged-out completely. c) And it didn't even work because the MySQL database layer prevents setting the region to 0.
2014-04-21 16:56:14 +01:00
Oren Hurvitz acc2c42a79 Better logging in PresenceService, to help diagnose presence problems. 2014-04-21 18:55:53 +03:00
Robert Adams b065c02661 Add 'lillith_xue' to list of CONTRIBUTORS.TXT
Removed references to 'Intel' as the contributors are no independent.
2014-04-21 06:00:55 -07:00
lillith_xue bc969a6b46 Possible solution for #7120 and #7051
Signed-off-by: Robert Adams <misterblue@misterblue.com>
2014-04-21 05:58:29 -07:00
Oren Hurvitz 3f76f72137 Better error-handling when storing assets: recognize that 'null' is an error value 2014-04-20 06:23:38 +01:00
Oren Hurvitz 52f8669169 Stopped setting the Service URL "GatekeeperURI" on users' accounts. It isn't actually used. 2014-04-20 06:23:37 +01:00
Oren Hurvitz 853c0fccc8 Fixed: when any avatar changed his Active Group, it was set as the active group for *all* the avatars in the scene (not permanently) 2014-04-20 06:23:37 +01:00
Oren Hurvitz 090f9bcece Fixed: once a user has rezzed an object, they could then duplicate it as much as they wanted even if the parcel's permissions had since been changed to disallow rezzing 2014-04-20 06:23:36 +01:00
Oren Hurvitz 3185db7f94 Fixed: if a user belonged to the parcel's group then he was allowed to rez object in the parcel even if the flag "Create Objects by Group" was disabled 2014-04-20 06:23:36 +01:00
Oren Hurvitz a780e01a54 Fixed: the parcel flag "Allow Scripts from Group" should only check if the parcel has a Group set; it doesn't have to be *deeded* to the group
Also some cleanup of the use of Group ID's (with no change to functionality).
2014-04-20 06:23:35 +01:00
BlueWall 63fd027494 Catch empty url error 2014-04-19 22:25:21 -04:00
Oren Hurvitz b3ebec184f In teleports, when sending the Source region, set its ServerURI to the Gatekeeper URI (which is used with Regions); not the Home URI (which is used with Users) 2014-04-13 12:58:37 +03:00
Oren Hurvitz e1dd228f18 Better error checking when creating hyperlinks: a) Reject invalid strings; b) Default port is 80, not 0
The change of default port may fix http://opensimulator.org/mantis/view.php?id=7108 , where a user was able to create a Hyperlink to OSGrid from inside OSGrid.
2014-04-13 09:54:56 +01:00
Robert Adams c8914d22eb BulletSim: reduce the terrain collison margin to be the same as other
objects in the world.

This was originally changed in an attempt to make vehicles work better
but the effect was not that large and it causes avatars to float
above the terrain.
2014-04-12 17:37:57 -07:00
Melanie 574a11558d Refactor: Rename GetOtherSetting to GetSetting and make SetOtherSetting private 2014-04-12 17:32:16 +01:00
Melanie 5d964a6424 Remove the old XML format parsing. Now additional region params can just be
added as they are already exposed through an API when using Nini. That will
remove the need to always edit RegioInfo just to add a region based setting.
2014-04-12 16:58:07 +01:00
Dev Random 18b91fdbe9 Tweak to PrimLimits and add missing Regions.ini example
Signed-off-by: Melanie <melanie@t-data.com>
2014-04-12 14:40:34 +01:00
Dev Random f0998a9222 Add per-user checking to PrimLimitsModule
Signed-off-by: Melanie <melanie@t-data.com>
2014-04-12 09:28:29 +01:00
Justin Clark-Casey (justincc) 7c148d9b2f minor: use constants instead of magic numbers in llRequestAgentData() where possible 2014-04-11 00:52:28 +01:00
Justin Clark-Casey (justincc) de0ab04d00 Actually add the llRequestAgentData() test class for commit 530c86 2014-04-11 00:36:50 +01:00
Justin Clark-Casey (justincc) 530c86335d Fix the presence info caching used in llRequestAgentData(), which was completely inoperative.
This means the presence info may be out of date by up to 20 seconds, but this avoids scripts potentially triggering constants requests to user accout and presence info services.
Relates to http://opensimulator.org/mantis/view.php?id=7088 though I fixed in a different way.
Adds regression test for this case.
2014-04-11 00:29:06 +01:00
Robert Adams 562a3cb338 BulletSim: small tweek to avatar height reduce feet embedded into prims.
This adjustment makes a default, shoeless avatar stand properly on a prim
for the various heights (0% to 100% in the appearance adjustment).
2014-04-10 06:53:36 -07:00
Snoopy Pfeffer 32ad66c274 Allows to sell objects on a parcel of land together with that parcel of land. The objects that are sold together with the parcel of land need to fulfill the following preconditions: owned by the current parcel owner, not set to a group, transferrable. This feature does not work for group owned parcels or land bought by a group. 2014-04-10 11:47:46 +02:00
Oren Hurvitz c725ad1577 Fixed: when teleporting between grids, the avatar name wasn't always updated.
When an avatar is in their home grid, their name appears as "First Last". In other grids the name appears as "First.Last @grid.example.com". However, viewers have a bug and they don't always show the new name. We use a trick (changing the Group Title briefly) in order to make the viewers show the new name. This is only done after a Hypergrid teleport.
2014-04-09 15:00:54 +01:00
Oren Hurvitz 06e0528d0b In teleports, pass the source region to the destination (similar to an HTTP referrer) 2014-04-09 09:22:20 +01:00
Oren Hurvitz cf1686335f Log when the presence service logs-out all the users in a region 2014-04-09 06:06:52 +01:00
Oren Hurvitz af406748a2 Improved error messages when a teleport fails. The viewer's dialog already says "Teleport failed", so adding "Teleport refused" is redundant. 2014-04-08 08:11:30 +01:00
Oren Hurvitz e00f1a0410 Allow invalidating the users cache 2014-04-08 08:11:29 +01:00
Diva Canto 86105a1533 Better (amend to previous commit) 2014-04-07 19:51:26 -07:00
Diva Canto c0fd09b445 Avoid calling HELO service on malformed URLs. This is in response to an exception reported by danbanner. 2014-04-07 19:41:25 -07:00
Oren Hurvitz 85d51e57a9 When sending QueryAccess to a region, also send the user's Home URI 2014-04-07 07:32:36 +01:00
Oren Hurvitz 55cc8044cb Refactored: use Scene.GetAgentHomeURI() to get the Home URI of a user 2014-04-07 07:26:44 +01:00
Oren Hurvitz f3508649f5 Fixed: during a teleport we always sent the error "The teleport destination could not be found" to the client. This happened on both success and failure.
On successful teleports this error wasn't actually shown to the user. But on failed teleports this error could hide the true cause of the failure. For example, attempting to use a Landmark that's more than 4095 regions away would result in two warnings appearing in the viewer: "Region too far" and "Destination could not be found". The second message hid the first one, so it wasn't obvious to the user what is actually the problem.
2014-04-06 15:42:33 +01:00
Oren Hurvitz abe0f4a088 When preparing a Hypergrid teleport, tell the receiving grid which user is entering the grid.
This can affect which region to use. E.g., returning users may be allowed to enter any region, whereas users from other grids will have to enter a gateway region. Previously per-user decisions were only made later, but by then it's too late to change which region the user enters.
2014-04-06 15:40:45 +01:00
Oren Hurvitz d4acaf25af Pass the correct position to QueryAccess() instead of UUID.Zero (it was wrong in one place) 2014-04-06 15:40:45 +01:00
Justin Clark-Casey (justincc) cacbb5c165 Don't re-retrieve sit part in SP.HandleAgentSit() when we already have it (this time with the right code change) 2014-04-05 02:16:14 +01:00
Justin Clark-Casey (justincc) 86a2cd915c Revert "Don't re-retrieve sit part in SP.HandleAgentSit() when we already have it."
This reverts commit 2c00b73cd2.

Wrong code change
2014-04-05 02:11:36 +01:00
Justin Clark-Casey (justincc) 2c00b73cd2 Don't re-retrieve sit part in SP.HandleAgentSit() when we already have it. 2014-04-05 02:09:44 +01:00
tglion 8b8e1b88ec fixed object-collision issue after uncheck phantom-flag
Signed-off-by: Michael Cerquoni <nebadon2025@gmail.com>
2014-04-04 12:29:44 -04:00
Justin Clark-Casey (justincc) aec723b955 Fix sp.AbsolutePosition when agent is sitting on a child prim, which in turns fixes llDetectedPos(), llGetLinkPrimitiveParams() and similar functions.
Add regression test for this case.
In relation to http://opensimulator.org/mantis/view.php?id=7043
2014-04-03 23:22:57 +01:00
Michael Cerquoni 6b1d09813e remove some whitespace that snuck in with last patch 2014-04-03 13:25:32 -04:00
Dev Random 50eec6df52 Add Varregion support to Terragen Handler
Signed-off-by: Michael Cerquoni <nebadon2025@gmail.com>
2014-04-03 13:14:13 -04:00
Vegaslon 3c5b7d7b79 BulletSim: Minor Fix to vehicle hovering, add more ways to disable it.
Signed-off-by: Michael Cerquoni <nebadon2025@gmail.com>
2014-04-03 13:07:48 -04:00
Dev Random 4aa483777b Move new Estate commands to OpenSim.cs
Signed-off-by: Michael Cerquoni <nebadon2025@gmail.com>
2014-04-03 12:45:43 -04:00
Oren Hurvitz 672bd9fc98 Reduced log levels for REST 404 errors to DEBUG 2014-04-03 15:04:26 +01:00
Oren Hurvitz 01daa74adf Better error messages in RestClient 2014-04-03 14:13:22 +01:00
Oren Hurvitz 6d2893be67 When teleporting using Hypergrid, show more informative error messages in case of error 2014-04-03 14:13:03 +01:00
Robert Adams 65c4cb48ac BulletSim: make avatar physical shape to be a rectangle rather than
a capsule. Set the default to be the rectangle shape and adjust the
parameters in OpenSimDefaults.ini for the new shape.

The rectangle shape will perform better and avatar height can be
computed more accurately.
2014-04-02 21:53:58 -07:00
Robert Adams 9406db3047 Fix problem with floating avatar by passing avatar size information
to the physics engine.

This operation was accidentally removed while in the middle of improving
the computation of the avatar height. This is a temp fix until the real
solution is added.
2014-04-02 21:52:24 -07:00
Justin Clark-Casey (justincc) e756457703 Remove redundant part.SitTargetAvatar setting from SP.MakeRootAgent as part.AddSittingAvatar already does this. 2014-04-03 01:21:50 +01:00
Justin Clark-Casey (justincc) 6ac9c9c972 refactor: Use m_sittingAvatars to maintain the list of sitting avatars instead of two independent structures that do exactly the same thing
m_sittingAvatars code also already properly handles locking to avoid races.
2014-04-03 01:14:39 +01:00
Justin Clark-Casey (justincc) 91b7679db9 minor: Fix warning in AvatarFactoryModule 2014-04-03 00:35:42 +01:00
Justin Clark-Casey (justincc) 17929abd28 Wrap contents of ETM.CrossAgentToNewRegionAsync() in try/catch to avoid a failure terminating simulators running on Windows
In relation to http://opensimulator.org/mantis/view.php?id=7050
2014-04-03 00:34:20 +01:00
Justin Clark-Casey (justincc) 5cb4044539 Don't clear avsToCross in SOG.AbsolutePosition.set(), this is unnecessary since the structure is local and never reused after the clear 2014-04-03 00:26:55 +01:00
Justin Clark-Casey (justincc) e6d0dcd4e8 Fix bug where crossing to a neighbouring region and back again would trigger an exception, and a second recross would stop the user moving until relog
Also fixes an issue where sitting avatar counts became inaccurate after any cross.
Part of the problem was due to cloning code using MemberwiseClone() but not resetting certain collection structures.
Adds regression test for this case.
In relation to http://opensimulator.org/mantis/view.php?id=7050
2014-04-03 00:19:53 +01:00
Oren Hurvitz 2051535ce1 String matching in REST handlers: must allow '-' as a separator, because the "/map" handler uses it 2014-04-02 15:11:54 +01:00
Oren Hurvitz 0301c81b01 Made GetScenePresence() case-insensitive when searching by user name. This makes it easier to use console commands such as "show appearance". 2014-04-02 13:08:31 +01:00
Oren Hurvitz 9211361b19 Fixed AssetsExist in SQLite 2014-04-02 10:00:09 +03:00
Oren Hurvitz 6b65895736 Made the SQLite unit tests work on Windows (sqlite3.dll wasn't being loaded) 2014-04-02 09:49:57 +03:00
Oren Hurvitz 559c66afe6 Added System.Core reference to MSSQL 2014-04-02 09:20:28 +03:00
Oren Hurvitz aa217cf90f Better string matching when searching for REST handlers: must match an entire path component (ending with '/' or a similar character).
For example, these should match: "/assets" and "/assets/12345", but these shouldn't match: "/assets" and "/assets_exist".
2014-04-02 08:52:44 +03:00
Oren Hurvitz bbfda8e19e Fixed last-resort sending of error response (HTTP 500) when an error occurs while handling a request.
The previous code didn't actually send the response, so the caller was stuck until the timeout (100 seconds).
2014-04-02 06:32:41 +01:00
Oren Hurvitz fad0fd7f75 Fixed the "Update Asset" handler: it was looking for the Asset ID in the wrong parameter.
This doesn't actually matter because the "Update Asset" operation isn't implemented in AssetsServer. But still, the handler should do the right thing...
2014-04-02 06:32:40 +01:00
Oren Hurvitz d1c3f8eef5 Added assets service method AssetsExist(), which returns whether the given list of assets exist.
This method is used to optimize sending assets with embedded assets: e.g., when a Hypergrid visitor takes an item into the inventory.
2014-04-02 06:30:57 +01:00
Mic Bowman ac16a667e1 fix orphaned code in sun module per mantis 7068 2014-04-01 19:48:03 -07:00
Justin Clark-Casey (justincc) 7bafee28fa Removing warning from SceneObjectLinkingTests.TestLinkDelink2SceneObjects() by actually checking whether delinked grp3 is not null 2014-04-02 01:26:58 +01:00
Justin Clark-Casey (justincc) 46095c058e minor: comment out currently unused RegionCombinerModule.LogHeader 2014-04-02 01:24:40 +01:00
Justin Clark-Casey (justincc) e5a5b69b08 remove EstateManagmentCommands.m_commander that has been unused for some time 2014-04-02 01:23:40 +01:00
Dev Random 43eab5e163 Console command to rename Estate 2014-04-02 01:17:41 +01:00
Justin Clark-Casey (justincc) 444737c830 minor: Only calculate fetched usedPrims and simulatorCapacity info in PrimLimitsModule.CanObjectEnter() when we know for sure that we need them. 2014-04-02 01:05:37 +01:00
Justin Clark-Casey (justincc) 7cb1690589 minor: disable logging in recently added scene object crossing tests and remove some unnecessary test config 2014-04-02 01:01:53 +01:00
Justin Clark-Casey (justincc) 0af8886400 Fix problem where moving an object to another region on the same simulator was failing, with the object returning to its original position.
Root cause was that PrimLimitsModule was not properly handling the case where the parcel it was asked to check was outside the current region's bounds.
If this is the case, we can abort the check since the receiving region will perform it.
Added a regression test for this case.
2014-04-02 00:58:33 +01:00
BlueWall 4cbd45f3d5 Merge branch 'master' of /home/opensim/src/opensim 2014-03-31 15:50:27 -04:00
BlueWall 59d0e3c3c8 Add check to prevent the return of a wrong value when key is NULL_KEY 2014-03-31 15:49:53 -04:00
Dev Random 635f3f77ab Console command to change Estate owner
Signed-off-by: Michael Cerquoni <nebadon2025@gmail.com>
2014-03-29 00:59:15 -04:00
Oren Hurvitz 6557eba235 Removed default timeout when starting scripts after Load OAR 2014-03-28 13:04:19 +03:00
Oren Hurvitz 1fe504fee5 Better skipping of "SculptData" when parsing XML 2014-03-28 12:52:06 +03:00
Oren Hurvitz f360b687d6 Removed "SculptData" from the serialized XML format of prims 2014-03-28 07:51:21 +01:00
BlueWall ba5a236922 Profiles local StorageProvider fix, round 3 2014-03-27 13:41:20 -04:00
BlueWall 20640357ab Fix to local StorageProvider override 2014-03-27 13:27:46 -04:00
BlueWall 45ada5ca2d Merge branch 'master' of /home/opensim/var/repo/opensim 2014-03-27 12:56:12 -04:00
BlueWall 9c7b28341c Add support for specifying non-default StorageProvider 2014-03-27 12:36:30 -04:00
BlueWall a15282f023 Merge branch 'master' into m_test 2014-03-27 12:21:38 -04:00
Oren Hurvitz 161c827a44 Fixed a case where logging an HTTP response failed because the stream was non-seekable 2014-03-27 17:46:37 +02:00
Oren Hurvitz 76add0fdb0 Log errors in MakeRequest() as INFO, not ERROR. Some communications problems are benign (e.g., can't send Friend status update to a region that is down), so don't log them as ERROR so soon. We rethrow the exception, so the caller can still decide to log the error as an ERROR.
Resolves http://opensimulator.org/mantis/view.php?id=7077
2014-03-27 15:00:42 +01:00
Justin Clark-Casey (justincc) af54e6f370 minor: Change incorrect "Maximum" in the PhysicalPrimMin OpenSim.ini.example description to "Minimum"
Thanks to aiaustin for the spot.
2014-03-26 23:45:02 +00:00
Justin Clark-Casey (justincc) e7fa8a4699 minor: change misspelling of overriden to overridden in comments within config files
Thanks to aiaustin for the spot.
2014-03-26 23:43:49 +00:00
Justin Clark-Casey (justincc) 262892336b Add LuciusSirnah to contributors list 2014-03-26 21:03:21 +00:00
Justin Clark-Casey (justincc) 1247174db4 Fix MSSQLInventoryHandler.IncreementFolderVersion where sql accidentally used a MySQL style ?folderID insted of @folderID
Thanks to LuciusSirnah in http://opensimulator.org/mantis/view.php?id=7075 for this fix
2014-03-26 21:02:26 +00:00
Justin Clark-Casey (justincc) de941d2ec7 minor: remove compiler warning from NullEstateData 2014-03-26 21:00:57 +00:00
Justin Clark-Casey (justincc) b0bae62c30 refactor: Actually use MaptileStaticFile in RegionInfo rather than having both a public field and a get property 2014-03-26 20:58:58 +00:00
Justin Clark-Casey (justincc) 7a4c5b067d Add MSSQL EstateStore.migrations VERSION 10 transaction to add AllowLandMark, AllowParcelChanges and AllowSetHome columns to estate_settings table.
Taken from http://opensimulator.org/mantis/view.php?id=7074 by LuciusSirnah.  Thanks!
2014-03-26 20:42:53 +00:00
Justin Clark-Casey (justincc) 6c447f892e Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-03-26 20:36:33 +00:00
Justin Clark-Casey (justincc) 5e8dfb4f7e Fix extra physics params MSSQL migration (version 39).
This was failing because it used MySQL syntax
This is taken from Lucius Sirnah's entry in http://opensimulator.org/mantis/view.php?id=6593
But with the column existence checking removed, as this should not be necessary in a migration and is inconsistent with all other migrations, though I can see a case for doing it.
2014-03-26 20:34:04 +00:00
Oren Hurvitz 7a47c15edb - Increased the threadpool timeout to 10 minutes
- Changed a few places that launch long-lasting threads to skip the timeout altogether
2014-03-26 20:34:55 +01:00
Oren Hurvitz 14a7ddb885 Revert "Use log-rolling on the log files (once per day)"
This reverts commit 8ecab21b37.
2014-03-26 08:56:56 +02:00
Justin Clark-Casey (justincc) 2fbb906ff6 Reinsert code to extract size_x and size_y parameters from GetHomeRegion response in UserAgentServiceConnector.
This is actually code from commits afb2e07 and cf61cdf
For as yet unexplained reasons, the section of these commits which changed UserAgentServiceConnector.cs disappeared from its history between approx Feb 5 2014 and Feb 13 2014.
This ought to be impossible.  More details to follow in opensim-dev mailing list
2014-03-26 02:34:22 +00:00
Justin Clark-Casey (justincc) 62a03a5cac Also take YP/commented out JS references from script engine CodeTools.
Fixes build break from d3387d591a
2014-03-26 01:20:49 +00:00
Justin Clark-Casey (justincc) d3387d591a Remove unmaintained and unused YieldProlog scripting language
This hasn't been mainntained since 2008 and has not been kept up with the rest of the language infrastructure.
Hence, it almost certainly doesn't work and has never been used, afaik
If this is wrong, please say on the opensim-users/dev mailing list.
Removing to reduce maintenance burden (since it still needs to be made to compile).
2014-03-26 00:59:57 +00:00
Justin Clark-Casey (justincc) cffea984f1 minor: Remove "js" (Javascript) from list of allowed languages in script config since it hasn't been present in OpenSimulator for a very long time (0.6 days)
One reason support was removed is that the external DLL that implemented Javascript stopped development.
Not sure how well this ever worked in OpenSimulator.
Not removing vb for now as this is directly supported by Mono (via vbnc compiler) though I strongly suspect it is also inoperable.
2014-03-26 00:50:33 +00:00
Justin Clark-Casey (justincc) 99308d64c6 minor: Add some doc to Scene.Backup() detailing its direct invocation if the indepedent backup thread is not running (e.g. in a regression test) 2014-03-26 00:43:17 +00:00
Oren Hurvitz 6d1d58b654 Use the "X-Content-Encoding" header to indicate gzipped data, because old OpenSims fail if they get an unknown "Content-Encoding" 2014-03-25 18:09:23 +01:00
BlueWall 14836e60ff Fix issue with user picks creation. The snapshot id is UUID.Zero in new parcels. 2014-03-25 11:10:48 -04:00
BlueWall 9aec36156e Sync code that has moved in development branch with changes in master 2014-03-25 11:09:27 -04:00
BlueWall fce3fca7f9 Add the UserProfiles local service module to non-HG Standalone configuration. 2014-03-25 11:08:58 -04:00
BlueWall 542bef20e8 Move JsonRpc request code out for general availability 2014-03-25 11:08:27 -04:00
BlueWall dba33fee39 Move from UserProfileModule for general availability 2014-03-25 11:08:11 -04:00
Oren Hurvitz b1d8aa0b64 Use the "Content-Encoding" header to indicate gzipped streams 2014-03-25 15:36:59 +01:00
Oren Hurvitz 8ecab21b37 Use log-rolling on the log files (once per day)
Resolves http://opensimulator.org/mantis/view.php?id=6950
2014-03-25 09:53:02 +01:00
Oren Hurvitz 368b29a680 In Core Profiles: as a fallback, try to get profiles from foreign grids using the OpenProfile protocol
Resolves http://opensimulator.org/mantis/view.php?id=6954
2014-03-25 09:37:18 +01:00
Oren Hurvitz f90aee696a Always throw an exception if MakeRequest (used for HTTP POST) fails. (Previously many exceptions were ignored)
Resolves http://opensimulator.org/mantis/view.php?id=6949
2014-03-25 09:37:10 +01:00
Oren Hurvitz f901a38204 Improved logging of HTTP requests
- MemoryBuffer isn't seekable, so we can't log it. Log the string instead.
- Handle compressed streams
- Don't attempt to dump binary data. Either don't log it at all (if we know it's binary), or at least convert non-ASCII characters to ASCII.
- Log responses to HTTP requests
- Use the same log prefix for all of these log messages ("[LOGHTTP]"), to make them easy to see at a glance
- Increased the snippet length to 200 (80 doesn't show enough), and add "..." only if the message was actually truncated

Resolves http://opensimulator.org/mantis/view.php?id=6949
2014-03-25 09:36:53 +01:00
Oren Hurvitz 4289b71141 Fixed unit tests due to changes in the threadpool 2014-03-25 10:04:52 +02:00
Oren Hurvitz e131e73652 Run slow operations in a separate thread, instead of using FireAndForget (which has a 1-minute timeout)
Resolves http://opensimulator.org/mantis/view.php?id=6945
2014-03-25 08:01:55 +01:00
Oren Hurvitz 84d7227dfd Changed LogThreadPool to have 4 logging levels. Added console command "debug threadpool level" to set the logging level.
Resolves http://opensimulator.org/mantis/view.php?id=6945
2014-03-25 08:01:50 +01:00
Oren Hurvitz b13214af27 Added a watchdog to abort slow threads in the main thread pool
If a task in the thread pool hangs then it will permanently take up
one of the threads. If this happens repeatedly then the thread pool will
become exhausted and OpenSim will fail. This watchdog terminates threads in the
thread pool that have been executing for over a minute (which probably
means they're hung).

Resolves http://opensimulator.org/mantis/view.php?id=6945
2014-03-25 08:01:45 +01:00
Oren Hurvitz e735f76553 LogThreadPool: when the thread is for ProcessPacketMethod, also log the packet type
Resolves http://opensimulator.org/mantis/view.php?id=6945
2014-03-25 08:01:41 +01:00
Oren Hurvitz 4031933475 Refactored DebugFlagsEnum
Resolves http://opensimulator.org/mantis/view.php?id=6945
2014-03-25 08:01:37 +01:00
Oren Hurvitz 8555e54e22 Automatically start logging FireAndForget activity if the threadpool is full
Resolves http://opensimulator.org/mantis/view.php?id=6945
2014-03-25 08:01:32 +01:00
Oren Hurvitz 7c0ebcb984 Added debug flag: LogThreadPool. It makes us log every use of the main threadpool.
Resolves http://opensimulator.org/mantis/view.php?id=6945
2014-03-25 08:01:13 +01:00
Justin Clark-Casey (justincc) 091f3a8000 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-03-25 00:20:38 +00:00
Justin Clark-Casey (justincc) e12c044eab Don't fail to enable permissions modules correctly if there is any leading or trailing whitespace between comma separate module combinations. 2014-03-25 00:19:24 +00:00
Oren Hurvitz 8276a9e5f7 Fixed Debug command for Groups. (Use of wrong capitalization caused *two* "debug" options to appear in "help")
This is a (small) part of http://opensimulator.org/mantis/view.php?id=6949
2014-03-24 18:27:18 +01:00
Oren Hurvitz 6a477e044d If prim region crossing fails then don't delete the prim from the original region
Resolves http://opensimulator.org/mantis/view.php?id=6946
2014-03-24 18:24:50 +01:00
Oren Hurvitz 1769e93c42 Fixed parsing of coalesced objects if the XML starts with an XML Declaration ("<xml ...>")
Resolves http://opensimulator.org/mantis/view.php?id=6944
2014-03-24 18:18:29 +01:00
Oren Hurvitz 1a32b35279 In Load OAR, correctly restore group-owned objects
Resolves http://opensimulator.org/mantis/view.php?id=6943
2014-03-24 18:18:23 +01:00
Oren Hurvitz 305f5110c6 In Load OAR: Zero isn't a valid Group ID
Resolves http://opensimulator.org/mantis/view.php?id=6943
2014-03-24 18:18:08 +01:00
Oren Hurvitz 35078e03e5 During Load OAR, fix the User and Group ID's in objects that are embedded in assets (previously only rezzed objects were fixed)
Resolves http://opensimulator.org/mantis/view.php?id=6942
2014-03-24 18:17:59 +01:00
Oren Hurvitz 5fd9411143 Refactored Load IAR: created a generic mechanism to modify the SOG's as they are being loaded
Resolves http://opensimulator.org/mantis/view.php?id=6942
2014-03-24 18:17:35 +01:00
Oren Hurvitz 0ff61341e4 HGAssetService searches for the "HomeURI" setting in several sections: Startup, Hypergrid, HGAssetService
Resolves http://opensimulator.org/mantis/view.php?id=6940
2014-03-24 18:02:22 +01:00
Oren Hurvitz 8cec0b3fa1 If updating a user's profile notes fails then return an error
Resolves http://opensimulator.org/mantis/view.php?id=6938
2014-03-24 18:02:17 +01:00
Oren Hurvitz 1b30ae81b5 Fixed updating usersettings in the database
Resolves http://opensimulator.org/mantis/view.php?id=6938
2014-03-24 18:02:05 +01:00
Oren Hurvitz b9e0d0fdb2 Don't show hidden groups in search results
Resolves http://opensimulator.org/mantis/view.php?id=6937
2014-03-24 18:01:56 +01:00
Oren Hurvitz 1d4551e52f Check settings for groups module
Resolves http://opensimulator.org/mantis/view.php?id=6937
2014-03-24 18:01:47 +01:00
Oren Hurvitz c8583e566d When searching for users, don't add users from the local cache if they have an invalid UUID
Resolves http://opensimulator.org/mantis/view.php?id=6935
2014-03-24 18:01:37 +01:00
Oren Hurvitz a2dd8f31de Trim search queries (for users, groups, etc.). I have found that sometimes the viewer adds a space at the end, which causes searches to fail.
Resolves http://opensimulator.org/mantis/view.php?id=6935
2014-03-24 18:01:28 +01:00
Oren Hurvitz 6edc446780 Fixed: OnRegionInfoChange was never triggered
Resolves http://opensimulator.org/mantis/view.php?id=6934
2014-03-24 18:01:22 +01:00
Oren Hurvitz bf68dbabd7 Save to database these parcel updates: Force Owner, Abandon Request, Reclaim. (Previously these updates only changed the parcel in memory)
Resolves http://opensimulator.org/mantis/view.php?id=6934
2014-03-24 18:01:08 +01:00
Oren Hurvitz 89945f8829 Refactored: ExternalRepresentationUtils should be the only place where the "CreatorData" field is calculated, to ensure uniformity
Resolves http://opensimulator.org/mantis/view.php?id=6933
2014-03-24 18:00:59 +01:00
Oren Hurvitz edc04d4184 When updating the CreatorId of an inventory item, automatically update the CreatorIdAsUuid field as well
Resolves http://opensimulator.org/mantis/view.php?id=6933
2014-03-24 18:00:39 +01:00
Oren Hurvitz 5b2af7f99e Moved the linkage between LoginService and HGInventoryService to the config file 2014-03-24 18:33:18 +02:00
Oren Hurvitz df9845a283 When a user logs-in, automatically create the Suitcase folder
This is only done if the Suitcase Inventory Service is used.
Previously the Suitcase was created at a later time, which meant that it wasn't shown in the viewer until the viewer was restarted.
2014-03-24 17:02:13 +01:00
Oren Hurvitz 7496d0b0f7 Fixed unit tests for delinking objects 2014-03-24 15:05:39 +02:00
Oren Hurvitz 4bccfed80c When logging in UserAgentServiceConnector, always log the original server URL (the hostname), not the IP
This resolves http://opensimulator.org/mantis/view.php?id=6955 (that patch was modified a bit)
2014-03-24 14:20:19 +02:00
Oren Hurvitz eaf99bf928 Changed to Unix line-endings in VS2010Target.cs
Resolves http://opensimulator.org/mantis/view.php?id=6951
2014-03-24 12:27:07 +01:00
Oren Hurvitz f5ae36d7e2 Updated Prebuild to support .NET 4.5
Resolves http://opensimulator.org/mantis/view.php?id=6951
2014-03-24 12:26:54 +01:00
Oren Hurvitz 425d76bb98 Enable runprebuild.bat to run in Cygwin
This resolves http://opensimulator.org/mantis/view.php?id=6951
2014-03-24 12:26:53 +01:00
Oren Hurvitz 921f0052f4 Get the full viewer name even if it's (incorrectly) sent in the 'Channel' field
Recent versions of Firestorm and Singularity have started sending the viewer name in the 'Channel' field, leaving only their version number in the 'Viewer' field. So we need to search both of these fields for the viewer name.

This resolves http://opensimulator.org/mantis/view.php?id=6952
2014-03-24 12:26:52 +01:00
Oren Hurvitz 6734b94761 Better error messages
This resolves http://opensimulator.org/mantis/view.php?id=6936
2014-03-24 12:22:32 +01:00
Oren Hurvitz 773ffcafc3 Removed "hacktastic" code that is no longer needed.
We no longer set the object's AbsolutePosition in this place, so the IsAttachment hack doesn't do anything anymore.

This resolves http://opensimulator.org/mantis/view.php?id=6936
2014-03-24 12:05:25 +01:00
Oren Hurvitz 62b3bdf0fc When linking two groups, and then deleting the combined group: delete *all* of the combined group's prims, including those that came from the second subgroup
This fixes http://opensimulator.org/mantis/view.php?id=6175
2014-03-24 11:44:48 +01:00
Robert Adams b0cb0ec02f BulletSim: fix problem where axis constraints were also constraining
linear motion.

The code was limiting linear motion to be only in the positive direction
for any axis that was constrained.
2014-03-23 13:08:31 -07:00
Oren Hurvitz 81c9952e99 Added missing quotes in Robust.HG.ini.example 2014-03-23 16:40:09 +02:00
Dev Random db83208794 Fix negative stat for Active Scripts
Signed-off-by: Michael Cerquoni <nebadon2025@gmail.com>
2014-03-22 23:02:10 -04:00
Kevin Cozens ff5c38534d Reverting "Set default name for mute list" that was pushed by mistake.
This reverts commit 58def34dbe.
2014-03-22 16:38:48 -04:00
Kevin Cozens 58d7e3b8ed Reverting "Pass method to offline.php" commit that was pushed by mistake.
This reverts commit fe16a72a9a.
2014-03-22 16:31:36 -04:00
Kevin Cozens 949139eb0b Moved Kevin Cozens to the core developers list. 2014-03-22 15:57:32 -04:00
Kevin Cozens fe16a72a9a Pass method to offline.php using ?blah instead of /blah/. Avoids issue with Apache web servers running PHP via CGI. 2014-03-22 15:13:03 -04:00
Kevin Cozens 58def34dbe Set default name for mute list module as shown in OpenSim.ini.example 2014-03-22 15:13:03 -04:00
Vegaslon d4dad75a3c BulletSim: Fix jumping while running. Was unintentional taking way all upward target motion for avatar when running.
Signed-off-by: Michael Cerquoni <nebadon2025@gmail.com>
2014-03-22 15:00:48 -04:00
Melanie ebe7726cd7 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2014-03-22 01:49:28 +00:00
Melanie a4d322dcd1 Allow the setting from the environment to take effect if no explicit setting is given.
This is done by calling the constructor only with a directory if one is actually given.
2014-03-22 01:47:48 +00:00
Justin Clark-Casey (justincc) ccf18fd2ef Rename SOG.InSceneBackup to CanBeBackedUp to reflect its actual functionality.
It does not indicate that a SOG has been set to be backed up or not.  It indicates that a SOG can be backed up in principle.
In practice, this was added by lbsa71 in 2007 and is set to always true, albeit as a virtual property.
2014-03-22 01:36:21 +00:00
Dev Random 3d0778bcd6 Allow Mono Plugin Registry setting for Regions
Signed-off-by: Melanie <melanie@t-data.com>
2014-03-22 01:29:51 +00:00
Justin Clark-Casey (justincc) a5800f479e If an object has it's temporary flag unset after being set, put it back in the persistence list.
Effectively uses the patch in http://opensimulator.org/mantis/view.php?id=7060
But also adds a regression test and exposes the necessary property to allow this to work.
2014-03-22 00:29:13 +00:00
Justin Clark-Casey (justincc) 178a5a5585 rename prefix of scene-inventory.<scene-name>.ProcessedFetchInventoryRequests and QueuedFetchInventoryRequests to inventory.httpfetch.*
Actual inventory processing is done with a single set of static structures rather than per scene.
2014-03-21 23:29:31 +00:00
Justin Clark-Casey (justincc) 6664079f84 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-03-21 23:18:13 +00:00
Talun fb312279c9 Mantis 6922: No particles are generated if their size exceeds the maximum allowed size.
This patch ensures that no particle scal value can exceed 4.0
2014-03-21 23:13:34 +00:00
Oren Hurvitz f8caf41bd8 Moved Oren Hurvitz to core developers list 2014-03-21 17:33:19 +02:00
Justin Clark-Casey (justincc) 47e7febebc Add monitored thread last update times as stats in "show stats all"
These have the format server.thread.<thread-name>
2014-03-21 02:06:10 +00:00
Justin Clark-Casey (justincc) 33ae733006 Add H-H-H to contributors 2014-03-20 22:43:00 +00:00
H-H-H da25903300 Adding a way to disable/enable the in built Dwell Module 2014-03-20 22:35:50 +00:00
Justin Clark-Casey (justincc) 7f027552ec If we find an existing suitcase folder in HGSuitcaseInventoryService.GetRootFolder(), then return that as a response rather than null.
Fixes a regression from commit 346644016c (Fri Nov 15 23:10:59 2013)
This is actually the reverse of zadark's patch in http://opensimulator.org/mantis/view.php?id=6969
But I'm assuming that was a mistake since clearly we should be returning this data - this was original behaviour
2014-03-20 20:36:47 +00:00
Justin Clark-Casey (justincc) d04bb3ca9b Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-03-20 20:15:57 +00:00
Talun bd6f734d3a Mantis 6974 PERMISSION_TRACK_CAMERA should be implicit on attach.
http://wiki.secondlife.com/wiki/Run_time_permissions
This change makes PERMISSION_TRACK_CAMERA implicit on attach
2014-03-20 20:11:26 +00:00
Michael Cerquoni b5f94c72b9 Allow MaptileStaticFile path to be set to anywhere and not force it to bin/maptiles 2014-03-19 11:16:52 -04:00
Robert Adams 220ea9f687 Add Jak Daniels to CONTRIBUTORS.TXT 2014-03-18 22:20:00 -07:00
Jak Daniels 61353dde80 Allow Region specific static maptiles to be loaded from file. 2014-03-18 22:18:50 -07:00
Justin Clark-Casey (justincc) cf97535d9e Revert "Simplify DoubleQueue to eliminate redundant sempahore work."
This reverts commit 52b7b40034.

Got the semantics wrong - the sempahore is required so that the blocking thread waits for a signal.
2014-03-19 01:40:56 +00:00
Justin Clark-Casey (justincc) 52b7b40034 Simplify DoubleQueue to eliminate redundant sempahore work.
Exclusion is already guaranteed by the lock on m_syncRoot.
Semaphore could not allow more than one thread in these sections anyway since the underlying SDK structures are not thread-safe.
2014-03-19 00:48:13 +00:00
Justin Clark-Casey (justincc) 1497b75361 minor: Put ProcessedFetchInventoryRequests and QueuedFetchInventoryRequests in stats category "scene-inventory" instead of "scene"
To distinguish from general scene stats
2014-03-19 00:37:06 +00:00
Justin Clark-Casey (justincc) 9858766516 minor: Make "stats show" an alias for "show stats" command. 2014-03-19 00:35:49 +00:00
Justin Clark-Casey (justincc) e6080a38c5 Rename "debug stats record" command to "stats record" for consistency. Move from debug to general command category 2014-03-19 00:29:36 +00:00
Justin Clark-Casey (justincc) 1d0a9e521c Allow a snapshot of stats to be dumped to a file with a "stats save" command 2014-03-19 00:28:57 +00:00
Justin Clark-Casey (justincc) fad1d70180 Add httpserver.<port>.QueuedPollResponses and httpserver.<port>.ProcessedPollResponses statistics 2014-03-18 23:47:33 +00:00
Justin Clark-Casey (justincc) 9e0d419239 minor: Correction to description of QueuedPollResponses since this covers long poll and other 'poll' types 2014-03-18 23:24:22 +00:00
Justin Clark-Casey (justincc) eed343ed8a Add httpserver.<port-number>,QueuedPollResponses stat
This shows the number pf poll responses queued for processing.
2014-03-18 23:21:07 +00:00
Justin Clark-Casey (justincc) 7df325c275 Extend locking in BlockingQueue to cover operations that are not guaranteed to be thread-safe 2014-03-18 23:05:49 +00:00
Justin Clark-Casey (justincc) fdcd392582 Set executable bit on Npgsql.dll for cygwin 2014-03-18 21:04:37 +00:00
Justin Clark-Casey (justincc) f27766d47b Set executable flag on BulletXNA.dll for cygwin 2014-03-18 21:02:51 +00:00
Justin Clark-Casey (justincc) a660c0a750 Add scene.<scene-name>.ProcessedFetchInventoryRequests
This shows the number of requests that have been processed.
These have not necessarily been sent back to the request since this is done separately by the PollServiceRequestManager
2014-03-18 20:59:11 +00:00
Justin Clark-Casey (justincc) 8ce3fa646b Allow "show stats" console command to take a full stat name and display only that stat.
For example, scene.test.RootAgents will show only the RootAgents stat in the scene named "test"
2014-03-18 20:21:47 +00:00
Justin Clark-Casey (justincc) e82d394ddf Add scene.<scene-name>.QueuedFetchInventoryRequests stat
This is to aid in detecting whether there are fetch inventory requests remaining to be processed.
2014-03-18 20:10:41 +00:00
Justin Clark-Casey (justincc) d5f5649750 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-03-18 20:09:15 +00:00
Justin Clark-Casey (justincc) c605c7a7b7 Lock m_syncRoot on DoubleQueue.Count. This is not documented as a thread-safe operation 2014-03-18 19:54:07 +00:00
Melanie Thielker a53272c5fb Add delete maptile ability to MapImageService - yet untested 2014-03-18 00:50:00 +00:00
Justin Clark-Casey (justincc) ae56b946cf Fix a bug in previous commit 01520bb where I accidentally saved OtherCleanTime instead of Dwell 2014-03-18 00:34:40 +00:00
Justin Clark-Casey (justincc) 01520bbb3e Save and load dwell parcel stat in MySQL DB adaptor. Field in table already exists!
The SQLite database adaptor was loading and saving dwell whilst MySQL was not, even though the field already exists in the db table.
2014-03-18 00:02:55 +00:00
Justin Clark-Casey (justincc) f3e177814a Add regression test for http inventory fetch.
Involved some restructuring to allow regression tests to dequeue inventory requests and perform poll responses synchronously rather than async
2014-03-17 20:51:35 +00:00
Justin Clark-Casey (justincc) 873eee5431 Implement osForceBreakAllLinks().
Identical to llBreakAllLinks() except that it doesn't require the script to have link permissions.
2014-03-13 00:04:20 +00:00
Justin Clark-Casey (justincc) 6a279feb2f Only allow llBreakAllLinks() to work if script has received PERMISSION_CHANGE_LINKS
As per http://wiki.secondlife.com/wiki/LlBreakAllLinks
Same as existing llCreateLink() and llBreakLink()
2014-03-12 23:54:20 +00:00
Justin Clark-Casey (justincc) 296d63e20b Implement osForceCreateLink() and osForceBreakLink()
These are identical to llCreateLink() and llBreakLink() except that they don't require script permissions.
However, osForceCreateLink() still requires that linked and linkee still have the same owner.
There's also an AutomaticLinkPermission setting in [XEngine] that could be set to true to prevent the LSL function checks.
But this doesn't allow the finer control over which users/scripts, etc. can do this that the OSSL functions provide.
2014-03-12 23:05:16 +00:00
Justin Clark-Casey (justincc) beba20846f When sending group notices through group messaging, allow the agent ID to use for fetching group data to be different from im.fromAgentID
This is because xmlrpcgroups currently always checks visibility for the requesting agent ID (unlike Groups v2, which can accept UUID.Zero)
But group notice IMs have a from agent which is the group rather than the sending agent.
Further addresses http://opensimulator.org/mantis/view.php?id=7037
2014-03-12 19:31:04 +00:00
Dev Random 7112ee0015 Enable MapImageServiceModule with no refresh 2014-03-11 23:52:11 +00:00
Justin Clark-Casey (justincc) 86630a1b70 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-03-11 23:39:07 +00:00
Justin Clark-Casey (justincc) d975b42f6a Instead of auto-creating a parcel on request if one doesn't cover a given location, fill in gaps or extend existing parcel right after initial data load.
This is in line with simpler and still existing behaviour where a default parcel is created if no parcels are in storage at all.
Making this change as another step to address current problems with spurious parcels occasionally being created.
Also adds regression tests for different load behaviours depending on existing stored parcel data.
Relates to http://opensimulator.org/mantis/view.php?id=7035
2014-03-11 23:38:22 +00:00
Robert Adams 8edf4225f3 varregion: remove serialization of region terrain to floats when sending patches.
This should eliminate much memory thrashing and CPU usage while sending initial
terrain.

The old way of passing terrain was to convert it to an array of floats. This is
really bad for large terrain (think 4096x4096 floats). This change passes a dummy
float array since the real region info is used anyway and the floats are ignored.
(The ignoring the terrain floats is a kludge so as to not change IClientAPI.)
2014-03-11 07:12:47 -07:00
Robert Adams 6b17c9bd98 Add Lani Global to CONTRIBUTORS.txt 2014-03-10 22:12:56 -07:00
Lani Global 71c808cd32 PhysicalPrimMax 64m for OpenSim_ini_example standard size prim
Signed-off-by: Robert Adams <misterblue@misterblue.com>
2014-03-10 22:11:24 -07:00
Lani Global 3e8f593bf2 PhysicalPrimMax to 64m for ini Default files to enable standard size prims and mesh to be used with vehicles.
Signed-off-by: Robert Adams <misterblue@misterblue.com>
2014-03-10 22:11:09 -07:00
Robert Adams 742f505440 Change terrain update sending to be triggered by frame tick rather
than everytime terrain is changed.

The TerrainModule now hooks the frame event and, if terrain has changed,
sends terrain updates to the clients. This polling pattern replaces
the previous push on change pattern and will make it easier to do per
client throttling and per scene presence terrain update ordering.
2014-03-10 22:05:18 -07:00
Oren Hurvitz 0237d9113d Don't start KeyframeMotion timers until all the regions are ready. This prevents problems in megaregions (prims that think they've crossed over to other regions). 2014-03-11 00:55:58 +00:00
Oren Hurvitz 120f872d2b After an object with KeyframeMotion is copied into inventory, resume the motion (previously it remained stopped) 2014-03-11 00:43:22 +00:00
Justin Clark-Casey (justincc) 932c9e757b Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-03-11 00:16:31 +00:00
Justin Clark-Casey (justincc) 77e7bbcbf7 Send group notices through the same messaging module mechanism used to send group chat to avoid timeout issues when sending messages to large groups.
Only implementing for XmlRpcGroups initially to test.
May require MessageOnlineUsersOnly = true in [Groups] to be effective.
In relation to http://opensimulator.org/mantis/view.php?id=7037
2014-03-11 00:11:18 +00:00
Michael Cerquoni 4f67286044 fix missing quote for xBakes connector in Robust example ini files 2014-03-09 19:09:10 -04:00
Michael Cerquoni cfd3e8f0ea minor spelling mistake fix. 2014-03-09 11:46:25 -04:00
Michael Cerquoni abcb2cdb36 add XBakes connector to Robust.HG.ini.example 2014-03-08 21:50:41 -05:00
Michael Cerquoni a96601478c add [BakedTextureService] section to Robust.HG.ini.example file same as Robust.ini.example. 2014-03-08 21:48:33 -05:00
Michael Cerquoni e3c4936dea remove RefreshTime = 0 from [MapImageService] in Standalone.ini, StandaloneHypergrid.ini, Grid.ini, GridHypergrid.ini they were redundant and would not allow variables in OpenSim.ini to be set to anything. 2014-03-08 16:28:45 -05:00
Michael Cerquoni da990d01f2 set RefreshTime = 0 in [MapImageService] in Standalone.ini and StandaloneHypergrid.ini to eliminate memory leaking for Warp3D map tiler, these variables should be erased needs more discussion! 2014-03-08 15:57:19 -05:00
Michael Cerquoni 12f2648a57 set RefreshTime = 0 in [MapImageService] in Grid.ini and GridHypergrid.ini to eliminate memory leaking for Warp3D map tiler, these variables should be erased needs more discussion! 2014-03-08 15:41:26 -05:00
Dev Random 9de3fe9410 Add Varregion support to osGetRegionSize OSSL function
Signed-off-by: Michael Cerquoni <nebadon2025@gmail.com>
2014-03-07 17:48:07 -05:00
Justin Clark-Casey (justincc) 8225e3f40c Remove try/catch in LandManagmentModule.GetLandObject() - this is very old code and the caught exceptions can no longer occur. 2014-03-07 01:41:31 +00:00
Justin Clark-Casey (justincc) 3c05d67094 Lock m_landlist whilst loading parcels from storage to prevent a race against any parcel auto-creation in GetLandObject() 2014-03-07 01:36:06 +00:00
Justin Clark-Casey (justincc) 6b7625a56b Only auto-create a land parcel when there is none in a specified tile if there is more than 1 existing land parcel.
This is because there are still issues with bad parcels being generated in http://opensimulator.org/mantis/view.php?id=7035
Theorizing now that it's possible that something is calling GetParcel() before any parcel data has been loaded from persistence.
2014-03-07 01:23:19 +00:00
Justin Clark-Casey (justincc) 71918eeab4 Add regression test for sending group notices via xmlrpc groups connector. 2014-03-07 01:04:54 +00:00
Justin Clark-Casey (justincc) ddd38a3dea Add scene name to bad parcel add logging 2014-03-06 19:12:16 +00:00
Justin Clark-Casey (justincc) 58c0ed78d4 refactor: Simplify land object by using c# get/set auto-properties where applicable. 2014-03-06 02:12:58 +00:00
Justin Clark-Casey (justincc) 470d053443 minor: slightly simplify code in LandObject.ContainsPoint() 2014-03-06 00:51:39 +00:00
Justin Clark-Casey (justincc) ed14e97bb4 Remove array initialize calls in LMM - these are unnecessary as the VM already does this. 2014-03-06 00:46:16 +00:00
Justin Clark-Casey (justincc) aa2fb1ec25 minor: Increase size of parcel name field in "land show" console command output. Construct table using CDT rather than string formats 2014-03-06 00:40:24 +00:00
Justin Clark-Casey (justincc) 14569992e1 Prevent adding a land object if it overlaps any existing objects that have not had their bitmaps adjusted.
This is to prevent an immediate problem in http://opensimulator.org/mantis/view.php?id=7035 where a development code bug occasionally overlays all the existing parcels with a blank parcel owned by the estate manager and to gather more data.
My guess is that this parcel is being created by the new code in LandManagementModule.GetLandObject(), probably some race between threads since this only happens occasionally.
Adds regression tests for this case and for parcel subdivide.
2014-03-06 00:11:13 +00:00
Justin Clark-Casey (justincc) 4e6f7435d0 Add UUID and ready status (whether region has finished starting up) to "show regions" console output. 2014-03-05 01:23:48 +00:00
Justin Clark-Casey (justincc) 39ed382ddf Don't request a terse update after local teleport - this will be done by the main frame loop anyway and has the potential to race that thread. 2014-03-05 00:59:27 +00:00
Justin Clark-Casey (justincc) c9415fd763 If an avatar is sitting, send out position updates to clients for any change, not just those outside the usual tolerances.
This is to allow small adjustments of less than 0.05m in functions such as llSetPrimitiveLinkParams() to work
This is another fix for http://opensimulator.org/mantis/view.php?id=7044
Extends regression test for this case.
2014-03-05 00:38:38 +00:00
Justin Clark-Casey (justincc) 31de7b845f When positioning agent with PRIM_ROTATION in llSetLinkPrimitiveParams(), set the global rotation rather than the local rotation
Functionally the same as the patch in http://opensimulator.org/mantis/view.php?id=7044, thanks Aleric.
This commit also extends the regression test
2014-03-03 23:35:21 +00:00
Justin Clark-Casey (justincc) 5038a59ef3 Maybe slightly reduce warp3d memory leakage by disposing of decoded bitmap in Warp3DImageModule.GetTexture()
However, this still appears to be leaking massively, at least for me.  Possible cause is warp3D using GDI objects internally and not disposing of them.
2014-02-28 00:16:06 +00:00
Justin Clark-Casey (justincc) 88b1fc1382 Set up a StreamReader and call ReadToEnd() instead of using the GetStreamString() extension method
This eliminates some stream seeking that was never necessary and makes disposable of the StreamReader consistent with other code
2014-02-27 23:13:26 +00:00
Justin Clark-Casey (justincc) 94ad69faf2 Remove long unused UntrustedWebRequest class
This purports to check web requests but doesn't appear to actually do that.
2014-02-27 22:58:44 +00:00
Justin Clark-Casey (justincc) 5fafea6631 refactor: More consistently use using construct within WebUtil to match other existing code there. 2014-02-27 22:52:43 +00:00
Justin Clark-Casey (justincc) 1f4f09ad69 Add more details to InvalidOperationException logging in SychronousRestFormsRequest.MakeRequest(). 2014-02-27 20:35:56 +00:00
Justin Clark-Casey (justincc) 91333b9267 Stop LSL_Api.GetLinkEntities() from creating an unused list on every parameter except LINK_THIS. Simplify code. 2014-02-27 00:23:24 +00:00
Justin Clark-Casey (justincc) ed760f2586 minor: remove unused variable from recent commit 0e23374 2014-02-27 00:14:16 +00:00
Justin Clark-Casey (justincc) d7c9725ec0 refactor: Make osGetPrimtiveParams() and soSetPrimitiveParams() use common get/set params code in LSL_Api rather than an old copy&pasted section. 2014-02-27 00:11:50 +00:00
Dev Random 6955190c7d Add Util method to load OpSys env vars 2014-02-26 23:39:45 +00:00
Justin Clark-Casey (justincc) ce5d308d23 Add some regression tests for previous commit 0e23374 2014-02-26 23:13:56 +00:00
Justin Clark-Casey (justincc) 0e23374aa2 Implement PRIM_ROTATION, PRIM_ROT_LOCAL, PRIM_POSITION and PRIM_POS_LOCAL when manipulating avatars via llSetLinkPrimitiveParams()
Combination of core parts of Freaky's patch at https://github.com/ft-/opensim-patches/blob/master/opensim-llsetlinkprimitive-agent-fix.patch plus further adjustments from myself.
Resolves Mantises 6121, 6421, 6573, 6657
2014-02-26 23:07:13 +00:00
Justin Clark-Casey (justincc) 26fe59c35e Improve regression test TestSetAppearance() 2014-02-24 19:43:06 +00:00
Justin Clark-Casey (justincc) bc9952f901 Re-enable regression TestSaveBakedTextures() 2014-02-24 19:30:33 +00:00
Justin Clark-Casey (justincc) fd1b2a1c57 Stop mesh avatars that specify the alpha texture in their bake slots from causing the simulator to continually request that they rebake
This is because the alpha texture is not in the cache, we must continue to have the fallback of looking for these and other persisted bakes in the asset service.
Relates to http://opensimulator.org/mantis/view.php?id=6927
2014-02-24 19:20:50 +00:00
Robert Adams 0f03c64a0c Make Scene.DefaultDrawDistance to be the max of the region size and the
user setting. Seems this parameter has many side effects.
2014-02-23 21:56:37 -08:00
dahlia d6837f5dc7 update libomv to 59280cfe3e96714151158f4ec7b167af57f60e93 (current head) to hopefully resolve zlib incompatibilities when rendering maptiles with mesh 2014-02-22 18:52:59 -08:00
Robert Adams 0b213af675 Fix problem of hurricane speed winds. Thanks Vegaslon. 2014-02-22 15:04:28 -08:00
Diva Canto cddf1ec0dc Added 2 new behaviors to pCampBot 2014-02-21 10:06:08 -08:00
Diva Canto 97c74afca8 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-02-21 10:05:06 -08:00
Diva Canto d27e188fe2 Added 2 new behavirors to pCampBot. These are part of a systematic study I'm doing for understanding the load that AgentUpdate packets incur on the server. 2014-02-21 10:04:12 -08:00
Justin Clark-Casey (justincc) 11b4f534c2 If texture decode fails in Warp3D map maker, log uuid of asset that failed to decode along with exception 2014-02-20 23:36:50 +00:00
Justin Clark-Casey (justincc) d50d169441 If GetFolderContent called by WebFetchInvDescHandler.Fetch() fails for some reason and returns null, log and return empty contents rather than throwing an exception that ends up terminating the simulator. 2014-02-20 22:35:41 +00:00
Justin Clark-Casey (justincc) 28419251bf minor: Add some method doc to AFM,SetAppearanceAssets() 2014-02-20 19:30:47 +00:00
Justin Clark-Casey (justincc) d1bb73d068 In core.groups GroupsServiceRemoveConnector, if GetGroupRecord() or UpdateGroup() do not have a RESULT parameter in the result message, return null rather than fail with NullReferenceException
This check was already done by other methods.
Looks to resolve http://opensimulator.org/mantis/view.php?id=7012
2014-02-20 19:17:21 +00:00
Justin Clark-Casey (justincc) 4d1426e77d For now, do not replacing missing wearables with default wearables if itme details cannot be found.
This is causing many issues on OSGrid, possibly due to teleporting timing differences with simulators hosted in different places or HG teleports
Added a bit more logging for debug purposes.
See http://opensimulator.org/mantis/view.php?id=6939
2014-02-20 18:40:21 +00:00
dahlia a2866b85f3 add newRegion parameter to CrossAgentToNewRegion event and trigger the event after crossing thread is invoked 2014-02-20 00:18:28 -08:00
dahlia 269a6410a0 add EventManager event OnCrossAgentToNewRegion 2014-02-19 17:52:38 -08:00
Robert Adams c26f01ff8c varregion: make scene default draw distance to be the maximum size of the
region. This is a temp fix for the use of draw distance to compute child
regions. Eventually must use the draw distance from the viewer for the
computation.
2014-02-19 09:51:49 -08:00
Robert Adams fc9930e420 Repair check for if in region position (I mean || is kinda like &&). 2014-02-15 18:49:40 -08:00
Robert Adams 79200ed270 Fix displacement and location operations on legacy trees and grass in
the 'load oar' and 'scene' commands. Before they  were ignored but the
code now relies on the SOG.IsAttachment function for attachmentness.
2014-02-15 17:10:20 -08:00
Robert Adams 7fc289c039 Properly restore position on crossing failure for mega-regions.
Fix odd "cannot cross into banned parcel" viewer error message when crossing
into non-existant region. Proper permission failure messages are now returned.
2014-02-15 17:02:53 -08:00
Robert Adams 877bdcdce1 Rewrite of mega-region code to use new form of border checking.
This commit eliminates all of the 'border' class and list code and replaces
it with testing if in the current region.
Impacts: can make a mega-region out of varregions of the same size; and
mega-region combinations must be rectangular (not square but rectangular)
2014-02-15 16:01:43 -08:00
Robert Adams bdbbeaa494 Non-functional changes of numbers into symbolic references and a few
comments on what variables really mean.
2014-02-15 16:01:01 -08:00
Justin Clark-Casey (justincc) f6913e911e Merge branch 'justincc-master' 2014-02-15 01:18:10 +00:00
Justin Clark-Casey (justincc) f74aafaf63 In GridUserService, if a UUID is given consistently use the longest matched entry (as already done by GetGridUserInfo()) in order to avoid problems with multiple entries.
This is to avoid issues where LoggedIn, SetHome, etc were always using the exact UUID match but GetGridUserInfo() would use the longest.
Looks to address http://opensimulator.org/mantis/view.php?id=6986
2014-02-15 01:13:58 +00:00
Justin Clark-Casey (justincc) 4fed301e65 Don't request group information in SP.MakeRootAgent() if the presence belongs to no group (UUID.Zero)
This was trigger the XmlRpcGroups errors described in http://opensimulator.org/mantis/view.php?id=6986
Introduced in commit 5b73b9c4 (Wed Dec 11 01:39:56 2013)
2014-02-14 23:43:07 +00:00
Justin Clark-Casey (justincc) 733e067958 Log information about which function, request data and agent ID triggered an XmlRpcGroupsServiceConnector error 2014-02-14 21:28:45 +00:00
Justin Clark-Casey (justincc) ffd0da23fb Merge branch 'justincc-master' 2014-02-14 00:16:17 +00:00
Justin Clark-Casey (justincc) f49d513089 Change warns associated with UserAgentServiceConnector to debugs, as this is not necessarily a problen with the source simulator (e.g. someone else's remote simulator cannot be contacted).
This is Oren Hurvitz's second patch from http://opensimulator.org/mantis/view.php?id=6956 with a small amount of correction
2014-02-14 00:08:13 +00:00
Justin Clark-Casey (justincc) fc35b45e21 If calls to UserAgentServiceConnector fail then throw an exception. This lets the caller decide whether to discard the error or not.
This is Oren Hurvitz's 0001 patch from http://opensimulator.org/mantis/view.php?id=6956 but I ended up doing some tweaking to resolve patch application issues.
2014-02-14 00:01:12 +00:00
Justin Clark-Casey (justincc) bc7fda39b4 Merge branch 'justincc-master' 2014-02-12 23:23:56 +00:00
Justin Clark-Casey (justincc) e10012a7a6 If a caller tries to queue a CAPs message to a scene presence that has no event queue (e.g. an NPC), only warn if event queue debugging is greater than zero.
Removes the spurious log warnings if groups are active when NPCs are used.
Adds more regression tests associated with adding messages to the event queue
2014-02-12 23:18:10 +00:00
Robert Adams 3a7c8d1f32 BulletSim: the minimum vehicle velocity was set too low so moving slow
was getting zeroed too easily. Added VehicleMinVelocity parameter.
2014-02-11 21:07:55 -08:00
Robert Adams c0cc5e0fa4 varregion: Send large region patches for wind and clouds. 2014-02-11 21:07:55 -08:00
Mic Bowman b83a224147 Add JsonRezAtRoot script function. Operation is very similar to
llRezAtRoot except that the start parameter is a Json string that will
be unpacked into a json store identified by the objects uuid.  This
makes a much more expressive (and simpler) way of passing initial
parameters to a rezzed object.
2014-02-09 18:07:49 -08:00
Robert Adams 4a1c1fc009 Add zadark to CONTRIBUTORS.txt 2014-02-06 11:47:19 -08:00
Roger Kirkman cf61cdf58c Fix - Viewer crash during HG Teleport
Signed-off-by: Robert Adams <misterblue@misterblue.com>
2014-02-06 11:33:17 -08:00
Mic Bowman 1913ab5ad5 Update the SimianMaptile uploader to accommodate varregions. 2014-02-05 21:26:39 -08:00
Melanie 29c8461631 Remove the added whitespace, test concluded 2014-02-04 05:54:28 +00:00
Melanie 8f372b8ac8 Bot test 2014-02-04 05:52:22 +00:00
Robert Adams 342be228c6 Remove compile error from returning value in void function 2014-02-03 21:53:14 -08:00
Michael Cerquoni 87abf06956 test again undoing previous changes 2014-02-04 00:32:40 -05:00
Michael Cerquoni f81841a2c5 this is just a test 2014-02-04 00:30:35 -05:00
Robert Adams 1b41ec0a85 Fix raw32 terrain heightmap reader so it estimates terrain size from
the size of the input stream. This is required since the raw heightmap
format (.r32) does not contain any size information.
The estimation relies on terrain being square.
2014-02-03 21:23:32 -08:00
Melanie 31cba5aa66 Add one check for a blank URL because the module wasn't quite sure not to work when unconfigured :| 2014-02-04 04:20:37 +00:00
Melanie 1aed6567a8 Samle configurations for the baked texture server. 2014-02-04 02:49:13 +00:00
413 changed files with 32856 additions and 42805 deletions
+5 -1
View File
@@ -19,10 +19,14 @@ Prereqs:
From the distribution type:
* ./runprebuild.sh
* nant (or xbuild)
* nant (or !* xbuild)
* cd bin
* copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
* run mono OpenSim.exe
!* xbuild option switches
!* clean: xbuild /target:clean
!* debug: (default) xbuild /property:Configuration=Debug
!* release: xbuild /property:Configuration=Release
# Using Monodevelop
+16 -7
View File
@@ -9,13 +9,15 @@ people that make the day to day of OpenSim happen.
* dahlia
* Melanie Thielker
* Diva (Crista Lopes, University of California, Irvine)
* Dan Lake (Intel)
* Dan Lake
* Marck
* Mic Bowman (Intel)
* Mic Bowman
* BlueWall (James Hughes)
* Nebadon Izumi (Michael Cerquoni, OSgrid)
* Snoopy Pfeffer
* Robert Adams (Intel)
* Robert Adams
* Oren Hurvitz (Kitely)
* Kevin Cozens
= Core Developers Following the White Rabbit =
Core developers who have temporarily (we hope) gone chasing the white rabbit.
@@ -78,12 +80,13 @@ what it is today.
* ctrlaltdavid (David Rowe)
* Daedius
* daTwitch
* Dev Random
* devalnor-#708
* dmiles (Daxtron Labs)
* Dong Jun Lan (IBM)
* DoranZemlja
* dr0b3rts
* dslake (Intel)
* dslake
* FredoChaplin
* Garmin Kawaguichi
* Gerhard
@@ -97,10 +100,12 @@ what it is today.
* Flyte Xevious
* Garmin Kawaguichi
* Gryc Ueusp
* H-H-H (ginge264)
* Hiro Lecker
* Iain Oliver
* Imaze Rhiano
* Intimidated
* Jak Daniels
* Jeremy Bongio (IBM)
* jhurliman
* John R Sohn (XenReborn)
@@ -108,26 +113,30 @@ what it is today.
* Jon Cundill
* Junta Kohime
* Kayne
* Kevin Cozens
* kinoc (Daxtron Labs)
* Kira
* Kitto Flora
* KittyLiu
* Kurt Taylor (IBM)
* Lani Global
* lillith_xue
* lkalif
* LuciusSirnah
* lulurun
* M.Igarashi
* maimedleech
* Mana Janus
* MarcelEdward
* Matt Lehmann
* Mic Bowman
* Michelle Argus
* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
* Micheil Merlin
* Mike Osias (IBM)
* Mike Pitman (IBM)
* mikemig
* mikkopa/_someone - RealXtend
* Misterblue (Intel)
* Misterblue
* Mircea Kitsune
* mpallari
* MrMonkE
@@ -136,7 +145,6 @@ what it is today.
* nornalbion
* Omar Vera Ustariz (IBM)
* openlifegrid.com
* Oren Hurvitz (Kitely)
* otakup0pe
* Pixel Tomsen
* ralphos
@@ -145,6 +153,7 @@ what it is today.
* Richard Alimi (IBM)
* Rick Alther (IBM)
* Rob Smart (IBM)
* Roger Kirkman (zadark)
* rtomita
* Ruud Lathorp
* SachaMagne
+69 -12
View File
@@ -56,8 +56,8 @@ namespace OpenSim.Groups
private IGroupsServicesConnector m_groupData = null;
// Config Options
private bool m_groupMessagingEnabled = false;
private bool m_debugEnabled = true;
private bool m_groupMessagingEnabled;
private bool m_debugEnabled;
/// <summary>
/// If enabled, module only tries to send group IMs to online users by querying cached presence information.
@@ -83,7 +83,6 @@ namespace OpenSim.Groups
private Dictionary<UUID, List<string>> m_groupsAgentsDroppedFromChatSession = new Dictionary<UUID, List<string>>();
private Dictionary<UUID, List<string>> m_groupsAgentsInvitedToChatSession = new Dictionary<UUID, List<string>>();
#region Region Module interfaceBase Members
public void Initialise(IConfigSource config)
@@ -111,9 +110,17 @@ namespace OpenSim.Groups
m_messageOnlineAgentsOnly = groupsConfig.GetBoolean("MessageOnlineUsersOnly", false);
if (m_messageOnlineAgentsOnly)
{
m_usersOnlineCache = new ExpiringCache<UUID, PresenceInfo[]>();
}
else
{
m_log.Error("[Groups.Messaging]: GroupsMessagingModule V2 requires MessageOnlineUsersOnly = true");
m_groupMessagingEnabled = false;
return;
}
m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true);
m_debugEnabled = groupsConfig.GetBoolean("MessagingDebugEnabled", m_debugEnabled);
m_log.InfoFormat(
"[Groups.Messaging]: GroupsMessagingModule enabled with MessageOnlineOnly = {0}, DebugEnabled = {1}",
@@ -133,6 +140,14 @@ namespace OpenSim.Groups
scene.EventManager.OnMakeChildAgent += OnMakeChildAgent;
scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
scene.EventManager.OnClientLogin += OnClientLogin;
scene.AddCommand(
"Debug",
this,
"debug groups messaging verbose",
"debug groups messaging verbose <true|false>",
"This setting turns on very verbose groups messaging debugging",
HandleDebugGroupsMessagingVerbose);
}
public void RegionLoaded(Scene scene)
@@ -172,10 +187,8 @@ namespace OpenSim.Groups
return;
}
if (m_presenceService == null)
m_presenceService = scene.PresenceService;
}
public void RemoveRegion(Scene scene)
@@ -222,6 +235,25 @@ namespace OpenSim.Groups
#endregion
private void HandleDebugGroupsMessagingVerbose(object modules, string[] args)
{
if (args.Length < 5)
{
MainConsole.Instance.Output("Usage: debug groups messaging verbose <true|false>");
return;
}
bool verbose = false;
if (!bool.TryParse(args[4], out verbose))
{
MainConsole.Instance.Output("Usage: debug groups messaging verbose <true|false>");
return;
}
m_debugEnabled = verbose;
MainConsole.Instance.OutputFormat("{0} verbose logging set to {1}", Name, m_debugEnabled);
}
/// <summary>
/// Not really needed, but does confirm that the group exists.
@@ -242,11 +274,23 @@ namespace OpenSim.Groups
return false;
}
}
public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
{
SendMessageToGroup(im, groupID, UUID.Zero, null);
}
public void SendMessageToGroup(
GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func<GroupMembersData, bool> sendCondition)
{
int requestStartTick = Environment.TickCount;
UUID fromAgentID = new UUID(im.fromAgentID);
// Unlike current XmlRpcGroups, Groups V2 can accept UUID.Zero when a perms check for the requesting agent
// is not necessary.
List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), groupID);
int groupMembersCount = groupMembers.Count;
PresenceInfo[] onlineAgents = null;
@@ -254,7 +298,7 @@ namespace OpenSim.Groups
// Sending to offline members is not an option.
string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray();
// We cache in order not to overwhlem the presence service on large grids with many groups. This does
// We cache in order not to overwhelm the presence service on large grids with many groups. This does
// mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
// (assuming this is the same across all grid simulators).
if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
@@ -273,8 +317,6 @@ namespace OpenSim.Groups
// "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
// groupID, groupMembersCount, groupMembers.Count());
int requestStartTick = Environment.TickCount;
im.imSessionID = groupID.Guid;
im.fromGroup = true;
IClientAPI thisClient = GetActiveClient(fromAgentID);
@@ -299,12 +341,27 @@ namespace OpenSim.Groups
if (clientsAlreadySent.Contains(member.AgentID))
continue;
clientsAlreadySent.Add(member.AgentID);
if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
if (sendCondition != null)
{
if (!sendCondition(member))
{
if (m_debugEnabled)
m_log.DebugFormat(
"[Groups.Messaging]: Not sending to {0} as they do not fulfill send condition",
member.AgentID);
continue;
}
}
else if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
{
// Don't deliver messages to people who have dropped this session
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
if (m_debugEnabled)
m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
continue;
}
+5 -6
View File
@@ -45,9 +45,6 @@ namespace OpenSim.Groups
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsModule")]
public class GroupsModule : ISharedRegionModule, IGroupsModule
{
/// <summary>
/// </summary>
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -104,7 +101,7 @@ namespace OpenSim.Groups
{
scene.RegisterModuleInterface<IGroupsModule>(this);
scene.AddCommand(
"debug",
"Debug",
this,
"debug groups verbose",
"debug groups verbose <true|false>",
@@ -466,6 +463,7 @@ namespace OpenSim.Groups
OnNewGroupNotice(GroupID, NoticeID);
}
// Send notice out to everyone that wants notices
foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), GroupID))
{
@@ -498,12 +496,13 @@ namespace OpenSim.Groups
Util.ParseUniversalUserIdentifier(notice.noticeData.AttachmentOwnerID, out giver, out tmp, out tmp, out tmp, out tmp);
m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId);
string message;
InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId,
giver, notice.noticeData.AttachmentItemID);
giver, notice.noticeData.AttachmentItemID, out message);
if (itemCopy == null)
{
remoteClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false);
remoteClient.SendAgentAlertMessage(message, false);
return;
}
@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -560,7 +560,7 @@ namespace OpenSim.Groups
// so we have the list of urls to send the notice to
// this may take a long time...
Util.FireAndForget(delegate
Util.RunThreadNoTimeout(delegate
{
foreach (string u in urls)
{
@@ -571,7 +571,7 @@ namespace OpenSim.Groups
hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID));
}
}
});
}, "AddGroupNotice", null);
return true;
}
@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -158,7 +158,7 @@ namespace OpenSim.Groups
}
catch (Exception e)
{
m_log.DebugFormat("[Groups.RobustHGConnector]: Exception {0}", e.StackTrace);
m_log.Error(string.Format("[Groups.RobustHGConnector]: Exception {0} ", e.Message), e);
}
return FailureResult();
@@ -32,27 +32,47 @@ using System.Reflection;
using System.Text;
using OpenSim.Framework;
using OpenSim.Framework.ServiceAuth;
using OpenSim.Server.Base;
using OpenMetaverse;
using log4net;
using Nini.Config;
namespace OpenSim.Groups
{
public class GroupsServiceRemoteConnector
public class GroupsServiceRemoteConnector
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string m_ServerURI;
private IServiceAuth m_Auth;
private object m_Lock = new object();
public GroupsServiceRemoteConnector(string url)
public GroupsServiceRemoteConnector(IConfigSource config)
{
IConfig groupsConfig = config.Configs["Groups"];
string url = groupsConfig.GetString("GroupsServerURI", string.Empty);
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
throw new Exception(string.Format("[Groups.RemoteConnector]: Malformed groups server URL {0}. Fix it or disable the Groups feature.", url));
m_ServerURI = url;
if (!m_ServerURI.EndsWith("/"))
m_ServerURI += "/";
m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}", m_ServerURI);
/// This is from BaseServiceConnector
string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", "Groups" }, "None");
switch (authType)
{
case "BasicHttpAuthentication":
m_Auth = new BasicHttpAuthentication(config, "Groups");
break;
}
///
m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, authentication {1}",
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
}
public ExtendedGroupRecord CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
@@ -106,7 +126,7 @@ namespace OpenSim.Groups
sendData["OP"] = "UPDATE";
Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData);
if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL"))
if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
return null;
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
@@ -127,7 +147,7 @@ namespace OpenSim.Groups
Dictionary<string, object> ret = MakeRequest("GETGROUP", sendData);
if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL"))
if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
return null;
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
@@ -267,6 +287,7 @@ namespace OpenSim.Groups
if (ret["RESULT"].ToString() == "NULL")
return members;
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
{
ExtendedGroupMembersData m = GroupsDataUtils.GroupMembersData((Dictionary<string, object>)v);
@@ -357,6 +378,7 @@ namespace OpenSim.Groups
if (ret["RESULT"].ToString() == "NULL")
return roles;
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
{
GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v);
@@ -657,7 +679,8 @@ namespace OpenSim.Groups
lock (m_Lock)
reply = SynchronousRestFormsRequester.MakeRequest("POST",
m_ServerURI + "groups",
ServerUtils.BuildQueryString(sendData));
ServerUtils.BuildQueryString(sendData),
m_Auth);
if (reply == string.Empty)
return null;
@@ -667,7 +690,7 @@ namespace OpenSim.Groups
return replyData;
}
#endregion
#endregion
}
}
}
@@ -72,12 +72,7 @@ namespace OpenSim.Groups
private void Init(IConfigSource config)
{
IConfig groupsConfig = config.Configs["Groups"];
string url = groupsConfig.GetString("GroupsServerURI", string.Empty);
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
throw new Exception(string.Format("[Groups.RemoteConnector]: Malformed groups server URL {0}. Fix it or disable the Groups feature.", url));
m_GroupsService = new GroupsServiceRemoteConnector(url);
m_GroupsService = new GroupsServiceRemoteConnector(config);
m_Scenes = new List<Scene>();
}
@@ -36,6 +36,7 @@ using OpenSim.Framework;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Framework.ServiceAuth;
using OpenSim.Server.Handlers.Base;
using log4net;
using OpenMetaverse;
@@ -52,14 +53,26 @@ namespace OpenSim.Groups
public GroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
base(config, server, configName)
{
string key = string.Empty;
if (configName != String.Empty)
m_ConfigName = configName;
m_log.DebugFormat("[Groups.RobustConnector]: Starting with config name {0}", m_ConfigName);
IConfig groupsConfig = config.Configs[m_ConfigName];
if (groupsConfig != null)
{
key = groupsConfig.GetString("SecretKey", string.Empty);
m_log.DebugFormat("[Groups.RobustConnector]: Starting with secret key {0}", key);
}
// else
// m_log.DebugFormat("[Groups.RobustConnector]: Unable to find {0} section in configuration", m_ConfigName);
m_GroupsService = new GroupsService(config);
server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService));
IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService, auth));
}
}
@@ -69,8 +82,8 @@ namespace OpenSim.Groups
private GroupsService m_GroupsService;
public GroupsServicePostHandler(GroupsService service) :
base("POST", "/groups")
public GroupsServicePostHandler(GroupsService service, IServiceAuth auth) :
base("POST", "/groups", auth)
{
m_GroupsService = service;
}
@@ -96,7 +109,7 @@ namespace OpenSim.Groups
string method = request["METHOD"].ToString();
request.Remove("METHOD");
m_log.DebugFormat("[Groups.Handler]: {0}", method);
// m_log.DebugFormat("[Groups.Handler]: {0}", method);
switch (method)
{
case "PUTGROUP":
@@ -140,7 +153,7 @@ namespace OpenSim.Groups
}
catch (Exception e)
{
m_log.DebugFormat("[GROUPS HANDLER]: Exception {0}", e.StackTrace);
m_log.Error(string.Format("[GROUPS HANDLER]: Exception {0} ", e.Message), e);
}
return FailureResult();
@@ -784,6 +797,14 @@ namespace OpenSim.Groups
string xmlString = ServerUtils.BuildXmlResponse(result);
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
}
private byte[] FailureResult(string reason)
{
Dictionary<string, object> result = new Dictionary<string, object>();
NullResult(result, reason);
string xmlString = ServerUtils.BuildXmlResponse(result);
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
}
#endregion
}
}
@@ -66,7 +66,7 @@ namespace OpenSim.OfflineIM
if (serviceLocation == string.Empty)
m_OfflineIMService = new OfflineIMService(config);
else
m_OfflineIMService = new OfflineIMServiceRemoteConnector(serviceLocation);
m_OfflineIMService = new OfflineIMServiceRemoteConnector(config);
m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", m_ForwardOfflineGroupMessages);
m_log.DebugFormat("[OfflineIM.V2]: Offline messages enabled by {0}", Name);
@@ -226,10 +226,6 @@ namespace OpenSim.OfflineIM
return;
}
Scene scene = FindScene(new UUID(im.fromAgentID));
if (scene == null)
scene = m_SceneList[0];
string reason = string.Empty;
bool success = m_OfflineIMService.StoreMessage(im, out reason);
@@ -32,6 +32,7 @@ using System.Reflection;
using System.Text;
using OpenSim.Framework;
using OpenSim.Framework.ServiceAuth;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
@@ -46,6 +47,7 @@ namespace OpenSim.OfflineIM
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string m_ServerURI = string.Empty;
private IServiceAuth m_Auth;
private object m_Lock = new object();
public OfflineIMServiceRemoteConnector(string url)
@@ -65,6 +67,18 @@ namespace OpenSim.OfflineIM
m_ServerURI = cnf.GetString("OfflineMessageURL", string.Empty);
/// This is from BaseServiceConnector
string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", "Messaging" }, "None");
switch (authType)
{
case "BasicHttpAuthentication":
m_Auth = new BasicHttpAuthentication(config, "Messaging");
break;
}
///
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: Offline IM server at {0} with auth {1}",
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
}
#region IOfflineIMService
@@ -82,8 +96,13 @@ namespace OpenSim.OfflineIM
if (!ret.ContainsKey("RESULT"))
return ims;
if (ret["RESULT"].ToString() == "NULL")
string result = ret["RESULT"].ToString();
if (result == "NULL" || result.ToLower() == "false")
{
string reason = ret.ContainsKey("REASON") ? ret["REASON"].ToString() : "Unknown error";
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: GetMessages for {0} failed: {1}", principalID, reason);
return ims;
}
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
{
@@ -110,7 +129,7 @@ namespace OpenSim.OfflineIM
string result = ret["RESULT"].ToString();
if (result == "NULL" || result.ToLower() == "false")
{
reason = ret["REASON"].ToString();
reason = ret.ContainsKey("REASON") ? ret["REASON"].ToString() : "Unknown error";
return false;
}
@@ -138,7 +157,8 @@ namespace OpenSim.OfflineIM
lock (m_Lock)
reply = SynchronousRestFormsRequester.MakeRequest("POST",
m_ServerURI + "/offlineim",
ServerUtils.BuildQueryString(sendData));
ServerUtils.BuildQueryString(sendData),
m_Auth);
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
reply);
@@ -36,6 +36,7 @@ using OpenSim.Framework;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Framework.ServiceAuth;
using OpenSim.Server.Handlers.Base;
using log4net;
using OpenMetaverse;
@@ -59,7 +60,9 @@ namespace OpenSim.OfflineIM
m_OfflineIMService = new OfflineIMService(config);
server.AddStreamHandler(new OfflineIMServicePostHandler(m_OfflineIMService));
IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
server.AddStreamHandler(new OfflineIMServicePostHandler(m_OfflineIMService, auth));
}
}
@@ -69,8 +72,8 @@ namespace OpenSim.OfflineIM
private IOfflineIMService m_OfflineIMService;
public OfflineIMServicePostHandler(IOfflineIMService service) :
base("POST", "/offlineim")
public OfflineIMServicePostHandler(IOfflineIMService service, IServiceAuth auth) :
base("POST", "/offlineim", auth)
{
m_OfflineIMService = service;
}
@@ -109,7 +112,7 @@ namespace OpenSim.OfflineIM
}
catch (Exception e)
{
m_log.DebugFormat("[OFFLINE IM HANDLER]: Exception {0}", e.StackTrace);
m_log.Error(string.Format("[OFFLINE IM HANDLER]: Exception {0} ", e.Message), e);
}
return FailureResult();
@@ -104,7 +104,7 @@ namespace OpenSim.OfflineIM
using (MemoryStream mstream = new MemoryStream())
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
settings.Encoding = Util.UTF8NoBomEncoding;
using (XmlWriter writer = XmlWriter.Create(mstream, settings))
{
@@ -112,7 +112,7 @@ namespace OpenSim.OfflineIM
writer.Flush();
}
imXml = Util.UTF8.GetString(mstream.ToArray());
imXml = Util.UTF8NoBomEncoding.GetString(mstream.ToArray());
}
OfflineIMData data = new OfflineIMData();
@@ -39,6 +39,7 @@ using OpenSim.Region.CoreModules.Avatar.InstantMessage;
using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
using OpenSim.Region.CoreModules.Scripting.LoadImageURL;
using OpenSim.Region.CoreModules.Scripting.XMLRPC;
using OpenSim.Services.Interfaces;
namespace OpenSim.ApplicationPlugins.LoadRegions
{
@@ -130,7 +131,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
createdScenes.Add(scene);
if (changed)
regionsToLoad[i].EstateSettings.Save();
m_openSim.EstateDataService.StoreEstateSettings(regionsToLoad[i].EstateSettings);
}
foreach (IScene scene in createdScenes)
@@ -694,7 +694,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
region.EstateSettings.EstateName = (string) requestData["estate_name"];
region.EstateSettings.EstateOwner = userID;
// Persistence does not seem to effect the need to save a new estate
region.EstateSettings.Save();
m_application.EstateDataService.StoreEstateSettings(region.EstateSettings);
if (!m_application.EstateDataService.LinkRegion(region.RegionID, (int) region.EstateSettings.EstateID))
throw new Exception("Failed to join estate.");
@@ -724,7 +724,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
// If an access specification was provided, use it.
// Otherwise accept the default.
newScene.RegionInfo.EstateSettings.PublicAccess = GetBoolean(requestData, "public", m_publicAccess);
newScene.RegionInfo.EstateSettings.Save();
m_application.EstateDataService.StoreEstateSettings(newScene.RegionInfo.EstateSettings);
// enable voice on newly created region if
// requested by either the XmlRpc request or the
@@ -910,7 +910,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
scene.RegionInfo.EstateSettings.PublicAccess =
GetBoolean(requestData,"public", scene.RegionInfo.EstateSettings.PublicAccess);
if (scene.RegionInfo.Persistent)
scene.RegionInfo.EstateSettings.Save();
m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
if (requestData.ContainsKey("enable_voice"))
{
@@ -1792,7 +1792,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
scene.RegionInfo.EstateSettings.EstateAccess = new UUID[]{};
if (scene.RegionInfo.Persistent)
scene.RegionInfo.EstateSettings.Save();
m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
m_log.Info("[RADMIN]: Access List Clear Request complete");
}
@@ -1838,7 +1838,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
}
scene.RegionInfo.EstateSettings.EstateAccess = accessControlList.ToArray();
if (scene.RegionInfo.Persistent)
scene.RegionInfo.EstateSettings.Save();
m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
}
responseData["added"] = addedUsers;
@@ -1887,7 +1887,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
}
scene.RegionInfo.EstateSettings.EstateAccess = accessControlList.ToArray();
if (scene.RegionInfo.Persistent)
scene.RegionInfo.EstateSettings.Save();
m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
}
responseData["removed"] = removedUsers;
@@ -2238,7 +2238,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
{
account.ServiceURLs = new Dictionary<string, object>();
account.ServiceURLs["HomeURI"] = string.Empty;
account.ServiceURLs["GatekeeperURI"] = string.Empty;
account.ServiceURLs["InventoryServerURI"] = string.Empty;
account.ServiceURLs["AssetServerURI"] = string.Empty;
}
+5 -2
View File
@@ -50,8 +50,7 @@ namespace OpenSim.Framework.Capabilities
public class Caps
{
// private static readonly ILog m_log =
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string m_httpListenerHostName;
private uint m_httpListenPort;
@@ -152,6 +151,10 @@ namespace OpenSim.Framework.Capabilities
public void RegisterPollHandler(string capName, PollServiceEventArgs pollServiceHandler)
{
// m_log.DebugFormat(
// "[CAPS]: Registering handler with name {0}, url {1} for {2}",
// capName, pollServiceHandler.Url, m_agentID, m_regionName);
m_pollServiceHandlers.Add(capName, pollServiceHandler);
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler.Url, pollServiceHandler);
@@ -56,12 +56,15 @@ namespace OpenSim.Capabilities.Handlers
public const string DefaultFormat = "x-j2c";
// TODO: Change this to a config option
const string REDIRECT_URL = null;
private string m_RedirectURL = null;
public GetTextureHandler(string path, IAssetService assService, string name, string description)
public GetTextureHandler(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)
@@ -134,7 +137,7 @@ namespace OpenSim.Capabilities.Handlers
if (format != DefaultFormat)
fullID = fullID + "-" + format;
if (!String.IsNullOrEmpty(REDIRECT_URL))
if (!String.IsNullOrEmpty(m_RedirectURL))
{
// Only try to fetch locally cached textures. Misses are redirected
texture = m_assetService.GetCached(fullID);
@@ -150,8 +153,9 @@ namespace OpenSim.Capabilities.Handlers
}
else
{
string textureUrl = REDIRECT_URL + textureID.ToString();
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;
}
@@ -62,8 +62,10 @@ namespace OpenSim.Capabilities.Handlers
if (m_AssetService == null)
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
string rurl = serverConfig.GetString("GetTextureRedirectURL");
;
server.AddStreamHandler(
new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null));
new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null, rurl));
}
}
}
@@ -52,7 +52,7 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
// Overkill - we only really need the asset service, not a whole scene.
Scene scene = new SceneHelpers().SetupScene();
GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService, "TestGetTexture", null);
GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService, "TestGetTexture", null, null);
TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse();
req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");
@@ -238,7 +238,15 @@ namespace OpenSim.Capabilities.Handlers
if (folderID != UUID.Zero)
{
contents = m_InventoryService.GetFolderContent(agentID, folderID);
InventoryCollection fetchedContents = m_InventoryService.GetFolderContent(agentID, folderID);
if (fetchedContents == null)
{
m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of folder {0} for user {1}", folderID, agentID);
return contents;
}
contents = fetchedContents;
InventoryFolderBase containingFolder = new InventoryFolderBase();
containingFolder.ID = folderID;
containingFolder.Owner = agentID;
+1 -2
View File
@@ -37,9 +37,8 @@ namespace OpenSim.Data
public abstract class AssetDataBase : IAssetDataPlugin
{
public abstract AssetBase GetAsset(UUID uuid);
public abstract void StoreAsset(AssetBase asset);
public abstract bool ExistsAsset(UUID uuid);
public abstract bool[] AssetsExist(UUID[] uuids);
public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
+1 -1
View File
@@ -35,7 +35,7 @@ namespace OpenSim.Data
{
AssetBase GetAsset(UUID uuid);
void StoreAsset(AssetBase asset);
bool ExistsAsset(UUID uuid);
bool[] AssetsExist(UUID[] uuids);
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
void Initialise(string connect);
bool Delete(string id);
@@ -29,7 +29,7 @@ using System.Collections.Generic;
using OpenMetaverse;
using OpenSim.Framework;
namespace OpenSim.Region.Framework.Interfaces
namespace OpenSim.Data
{
public interface IEstateDataStore
{
+1 -1
View File
@@ -39,7 +39,7 @@ namespace OpenSim.Data
{
AssetBase GetAsset(UUID uuid);
void StoreAsset(AssetBase asset);
bool ExistsAsset(UUID uuid);
bool[] AssetsExist(UUID[] uuids);
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
void Initialise(string connect);
bool Delete(string id);
+53 -6
View File
@@ -48,9 +48,57 @@ namespace OpenSim.Data
public ulong everyonePowers;
public ulong ownersPowers;
public Dictionary<UUID, XGroupMember> members = new Dictionary<UUID, XGroupMember>();
public Dictionary<UUID, XGroupNotice> notices = new Dictionary<UUID, XGroupNotice>();
public XGroup Clone()
{
return (XGroup)MemberwiseClone();
XGroup clone = (XGroup)MemberwiseClone();
clone.members = new Dictionary<UUID, XGroupMember>();
clone.notices = new Dictionary<UUID, XGroupNotice>();
foreach (KeyValuePair<UUID, XGroupMember> kvp in members)
clone.members[kvp.Key] = kvp.Value.Clone();
foreach (KeyValuePair<UUID, XGroupNotice> kvp in notices)
clone.notices[kvp.Key] = kvp.Value.Clone();
return clone;
}
}
public class XGroupMember
{
public UUID agentID;
public UUID groupID;
public UUID roleID;
public bool acceptNotices = true;
public bool listInProfile = true;
public XGroupMember Clone()
{
return (XGroupMember)MemberwiseClone();
}
}
public class XGroupNotice
{
public UUID groupID;
public UUID noticeID;
public uint timestamp;
public string fromName;
public string subject;
public string message;
public byte[] binaryBucket;
public bool hasAttachment;
public int assetType;
public XGroupNotice Clone()
{
XGroupNotice clone = (XGroupNotice)MemberwiseClone();
clone.binaryBucket = (byte[])binaryBucket.Clone();
return clone;
}
}
@@ -58,14 +106,13 @@ namespace OpenSim.Data
/// Early stub interface for groups data, not final.
/// </summary>
/// <remarks>
/// Currently in-use only for regression test purposes. Needs to be filled out over time.
/// Currently in-use only for regression test purposes.
/// </remarks>
public interface IXGroupData
{
bool StoreGroup(XGroup group);
XGroup[] GetGroups(string field, string val);
XGroup[] GetGroups(string[] fields, string[] vals);
bool DeleteGroups(string field, string val);
bool DeleteGroups(string[] fields, string[] vals);
XGroup GetGroup(UUID groupID);
Dictionary<UUID, XGroup> GetGroups();
bool DeleteGroup(UUID groupID);
}
}
+32 -11
View File
@@ -160,18 +160,18 @@ namespace OpenSim.Data.MSSQL
@temporary, @create_time, @access_time, @creatorid, @asset_flags, @data)";
string assetName = asset.Name;
if (asset.Name.Length > 64)
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
{
assetName = asset.Name.Substring(0, 64);
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 > 64)
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
{
assetDescription = asset.Description.Substring(0, 64);
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);
@@ -225,17 +225,38 @@ namespace OpenSim.Data.MSSQL
// }
/// <summary>
/// Check if asset exist in m_database
/// Check if the assets exist in the database.
/// </summary>
/// <param name="uuid"></param>
/// <returns>true if exist.</returns>
override public bool ExistsAsset(UUID uuid)
/// <param name="uuids">The assets' IDs</param>
/// <returns>For each asset: true if it exists, false otherwise</returns>
public override bool[] AssetsExist(UUID[] uuids)
{
if (GetAsset(uuid) != null)
if (uuids.Length == 0)
return new bool[0];
HashSet<UUID> exist = new HashSet<UUID>();
string ids = "'" + string.Join("','", uuids) + "'";
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
return true;
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
UUID id = DBGuid.FromDB(reader["id"]);
exist.Add(id);
}
}
}
return false;
bool[] results = new bool[uuids.Length];
for (int i = 0; i < uuids.Length; i++)
results[i] = exist.Contains(uuids[i]);
return results;
}
/// <summary>
+2 -2
View File
@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -55,7 +55,7 @@ namespace OpenSim.Data.MSSQL
return Delete(principalID.ToString(), friend);
}
public bool Delete(string principalID, string friend)
public override bool Delete(string principalID, string friend)
{
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
using (SqlCommand cmd = new SqlCommand())
+1 -1
View File
@@ -278,7 +278,7 @@ namespace OpenSim.Data.MSSQL
// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
// Util.PrintCallStack();
string sql = "update inventoryfolders set version=version+1 where folderID = ?folderID";
string sql = "update inventoryfolders set version=version+1 where folderID = @folderID";
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
{
@@ -331,4 +331,12 @@ ALTER TABLE dbo.estate_map ADD CONSTRAINT
COMMIT
:VERSION 10
BEGIN transaction
ALTER TABLE estate_settings ADD AllowLandmark tinyint NOT NULL default 1;
ALTER TABLE estate_settings ADD AllowParcelChanges tinyint NOT NULL default 1;
ALTER TABLE estate_settings ADD AllowSetHome tinyint NOT NULL default 1;
COMMIT;
@@ -1,4 +1,4 @@
:VERSION 1
:VERSION 1
BEGIN TRANSACTION
@@ -26,6 +26,14 @@ COMMIT
BEGIN TRANSACTION
ALTER TABLE Presence ADD LastSeen DateTime
ALTER TABLE Presence ADD LastSeen DateTime;
COMMIT
COMMIT
:VERSION 3
BEGIN TRANSACTION
CREATE INDEX RegionID ON Presence(RegionID);
COMMIT
@@ -1161,11 +1161,11 @@ COMMIT
BEGIN TRANSACTION
ALTER TABLE prims ADD `PhysicsShapeType` tinyint(4) NOT NULL default '0';
ALTER TABLE prims ADD `Density` double NOT NULL default '1000';
ALTER TABLE prims ADD `GravityModifier` double NOT NULL default '1';
ALTER TABLE prims ADD `Friction` double NOT NULL default '0.6';
ALTER TABLE prims ADD `Restitution` double NOT NULL default '0.5';
ALTER TABLE prims ADD PhysicsShapeType tinyint NOT NULL default 0;
ALTER TABLE prims ADD Density float NOT NULL default 1000;
ALTER TABLE prims ADD GravityModifier float NOT NULL default 1;
ALTER TABLE prims ADD Friction float NOT NULL default 0.6;
ALTER TABLE prims ADD Restitution float NOT NULL default 0.5;
COMMIT
+24 -26
View File
@@ -171,18 +171,18 @@ namespace OpenSim.Data.MySQL
dbcon))
{
string assetName = asset.Name;
if (asset.Name.Length > 64)
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
{
assetName = asset.Name.Substring(0, 64);
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 > 64)
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
{
assetDescription = asset.Description.Substring(0, 64);
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);
@@ -257,46 +257,44 @@ namespace OpenSim.Data.MySQL
}
/// <summary>
/// Check if the asset exists in the database
/// Check if the assets exist in the database.
/// </summary>
/// <param name="uuid">The asset UUID</param>
/// <returns>true if it exists, false otherwise.</returns>
override public bool ExistsAsset(UUID uuid)
/// <param name="uuidss">The assets' IDs</param>
/// <returns>For each asset: true if it exists, false otherwise</returns>
public override bool[] AssetsExist(UUID[] uuids)
{
// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
if (uuids.Length == 0)
return new bool[0];
bool assetExists = false;
HashSet<UUID> exist = new HashSet<UUID>();
string ids = "'" + string.Join("','", uuids) + "'";
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand("SELECT id FROM assets WHERE id=?id", dbcon))
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
{
cmd.Parameters.AddWithValue("?id", uuid.ToString());
try
using (MySqlDataReader dbReader = cmd.ExecuteReader())
{
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
while (dbReader.Read())
{
if (dbReader.Read())
{
// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
assetExists = true;
}
UUID id = DBGuid.FromDB(dbReader["id"]);
exist.Add(id);
}
}
catch (Exception e)
{
m_log.Error(
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", uuid), e);
}
}
}
}
return assetExists;
bool[] results = new bool[uuids.Length];
for (int i = 0; i < uuids.Length; i++)
results[i] = exist.Contains(uuids[i]);
return results;
}
/// <summary>
+9 -2
View File
@@ -145,7 +145,11 @@ namespace OpenSim.Data.MySQL
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
return DoLoad(cmd, regionID, create);
EstateSettings e = DoLoad(cmd, regionID, create);
if (!create && e.EstateID == 0) // Not found
return null;
return e;
}
}
@@ -427,7 +431,10 @@ namespace OpenSim.Data.MySQL
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("?EstateID", estateID);
return DoLoad(cmd, UUID.Zero, false);
EstateSettings e = DoLoad(cmd, UUID.Zero, false);
if (e.EstateID != estateID)
return null;
return e;
}
}
+1 -1
View File
@@ -47,7 +47,7 @@ namespace OpenSim.Data.MySQL
return Delete(principalID.ToString(), friend);
}
public bool Delete(string principalID, string friend)
public override bool Delete(string principalID, string friend)
{
using (MySqlCommand cmd = new MySqlCommand())
{
+3 -3
View File
@@ -86,11 +86,11 @@ namespace OpenSim.Data.MySQL
public GroupData[] RetrieveGroups(string pattern)
{
if (string.IsNullOrEmpty(pattern))
pattern = "1 ORDER BY Name LIMIT 100";
pattern = "1";
else
pattern = string.Format("Name LIKE '%{0}%' ORDER BY Name LIMIT 100", pattern);
pattern = string.Format("Name LIKE '%{0}%'", MySqlHelper.EscapeString(pattern));
return m_Groups.Get(pattern);
return m_Groups.Get(string.Format("ShowInList=1 AND ({0}) ORDER BY Name LIMIT 100", pattern));
}
public bool DeleteGroup(UUID groupID)
+4 -3
View File
@@ -695,7 +695,7 @@ namespace OpenSim.Data.MySQL
"MusicURL, PassHours, PassPrice, SnapshotUUID, " +
"UserLocationX, UserLocationY, UserLocationZ, " +
"UserLookAtX, UserLookAtY, UserLookAtZ, " +
"AuthbuyerID, OtherCleanTime, MediaType, MediaDescription, " +
"AuthbuyerID, OtherCleanTime, Dwell, MediaType, MediaDescription, " +
"MediaSize, MediaLoop, ObscureMusic, ObscureMedia) values (" +
"?UUID, ?RegionUUID, " +
"?LocalLandID, ?Bitmap, ?Name, ?Description, " +
@@ -706,7 +706,7 @@ namespace OpenSim.Data.MySQL
"?MusicURL, ?PassHours, ?PassPrice, ?SnapshotUUID, " +
"?UserLocationX, ?UserLocationY, ?UserLocationZ, " +
"?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " +
"?AuthbuyerID, ?OtherCleanTime, ?MediaType, ?MediaDescription, "+
"?AuthbuyerID, ?OtherCleanTime, ?Dwell, ?MediaType, ?MediaDescription, "+
"CONCAT(?MediaWidth, ',', ?MediaHeight), ?MediaLoop, ?ObscureMusic, ?ObscureMedia)";
FillLandCommand(cmd, parcel.LandData, parcel.RegionUUID);
@@ -1484,6 +1484,7 @@ namespace OpenSim.Data.MySQL
UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer);
UUID.TryParse((string)row["SnapshotUUID"], out snapshotID);
newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]);
newData.Dwell = Convert.ToSingle(row["Dwell"]);
newData.AuthBuyerID = authedbuyer;
newData.SnapshotID = snapshotID;
@@ -1815,6 +1816,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("UserLookAtZ", land.UserLookAt.Z);
cmd.Parameters.AddWithValue("AuthBuyerID", land.AuthBuyerID);
cmd.Parameters.AddWithValue("OtherCleanTime", land.OtherCleanTime);
cmd.Parameters.AddWithValue("Dwell", land.Dwell);
cmd.Parameters.AddWithValue("MediaDescription", land.MediaDescription);
cmd.Parameters.AddWithValue("MediaType", land.MediaType);
cmd.Parameters.AddWithValue("MediaWidth", land.MediaWidth);
@@ -1822,7 +1824,6 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("MediaLoop", land.MediaLoop);
cmd.Parameters.AddWithValue("ObscureMusic", land.ObscureMusic);
cmd.Parameters.AddWithValue("ObscureMedia", land.ObscureMedia);
}
/// <summary>
+2 -7
View File
@@ -634,8 +634,6 @@ namespace OpenSim.Data.MySQL
{
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);
@@ -651,9 +649,6 @@ 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;
@@ -974,8 +969,8 @@ namespace OpenSim.Data.MySQL
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("?ImViaEmail", pref.IMViaEmail);
cmd.Parameters.AddWithValue("?Visible", pref.Visible);
cmd.Parameters.AddWithValue("?ImViaEmail", pref.IMViaEmail.ToString().ToLower());
cmd.Parameters.AddWithValue("?Visible", pref.Visible.ToString().ToLower());
cmd.Parameters.AddWithValue("?uuid", pref.UserId.ToString());
cmd.ExecuteNonQuery();
+24 -26
View File
@@ -210,18 +210,18 @@ namespace OpenSim.Data.MySQL
using (MySqlTransaction transaction = dbcon.BeginTransaction())
{
string assetName = asset.Name;
if (asset.Name.Length > 64)
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
{
assetName = asset.Name.Substring(0, 64);
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",
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
}
string assetDescription = asset.Description;
if (asset.Description.Length > 64)
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
{
assetDescription = asset.Description.Substring(0, 64);
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",
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
@@ -346,7 +346,7 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
catch (Exception)
{
m_log.ErrorFormat(
"[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}",
@@ -397,45 +397,43 @@ namespace OpenSim.Data.MySQL
}
/// <summary>
/// Check if the asset exists in the database
/// Check if the assets exist in the database.
/// </summary>
/// <param name="uuid">The asset UUID</param>
/// <returns>true if it exists, false otherwise.</returns>
public bool ExistsAsset(UUID uuid)
/// <param name="uuids">The asset UUID's</param>
/// <returns>For each asset: true if it exists, false otherwise</returns>
public bool[] AssetsExist(UUID[] uuids)
{
// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
if (uuids.Length == 0)
return new bool[0];
bool assetExists = false;
HashSet<UUID> exists = new HashSet<UUID>();
string ids = "'" + string.Join("','", uuids) + "'";
string sql = string.Format("SELECT ID FROM assets WHERE ID IN ({0})", ids);
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand("SELECT ID FROM XAssetsMeta WHERE ID=?ID", dbcon))
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
{
cmd.Parameters.AddWithValue("?ID", uuid.ToString());
try
using (MySqlDataReader dbReader = cmd.ExecuteReader())
{
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
while (dbReader.Read())
{
if (dbReader.Read())
{
// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
assetExists = true;
}
UUID id = DBGuid.FromDB(dbReader["ID"]);
exists.Add(id);
}
}
catch (Exception e)
{
m_log.Error(string.Format("[XASSETS DB]: MySql failure fetching asset {0}", uuid), e);
}
}
}
}
return assetExists;
bool[] results = new bool[uuids.Length];
for (int i = 0; i < uuids.Length; i++)
results[i] = exists.Contains(uuids[i]);
return results;
}
@@ -1,4 +1,4 @@
:VERSION 1 # --------------------------
:VERSION 1 # --------------------------
BEGIN;
@@ -32,3 +32,11 @@ ALTER TABLE `im_offline`
ADD KEY `FromID` (`FromID`);
COMMIT;
:VERSION 4 # --------------------------
BEGIN;
ALTER TABLE im_offline CONVERT TO CHARACTER SET utf8;
COMMIT;
@@ -1,4 +1,4 @@
:VERSION 1 # --------------------------
:VERSION 1 # --------------------------
BEGIN;
@@ -21,3 +21,11 @@ BEGIN;
ALTER TABLE `Presence` ADD COLUMN LastSeen timestamp;
COMMIT;
:VERSION 3 # --------------------------
BEGIN;
CREATE INDEX RegionID ON Presence(RegionID);
COMMIT;
+1 -1
View File
@@ -42,7 +42,7 @@ namespace OpenSim.Data.Null
// private string m_connectionString;
private Dictionary<uint, EstateSettings> m_knownEstates = new Dictionary<uint, EstateSettings>();
// private Dictionary<uint, EstateSettings> m_knownEstates = new Dictionary<uint, EstateSettings>();
private EstateSettings m_estate = null;
private EstateSettings GetEstate()
+1 -1
View File
@@ -40,7 +40,7 @@ namespace OpenSim.Data.Null
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static NullPresenceData Instance;
public static NullPresenceData Instance;
Dictionary<UUID, PresenceData> m_presenceData = new Dictionary<UUID, PresenceData>();
+21 -25
View File
@@ -38,7 +38,7 @@ using OpenSim.Data;
namespace OpenSim.Data.Null
{
public class NullXGroupData : NullGenericDataHandler, IXGroupData
public class NullXGroupData : IXGroupData
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -56,35 +56,31 @@ namespace OpenSim.Data.Null
return true;
}
public XGroup[] GetGroups(string field, string val)
public XGroup GetGroup(UUID groupID)
{
return GetGroups(new string[] { field }, new string[] { val });
XGroup group = null;
lock (m_groups)
m_groups.TryGetValue(groupID, out group);
return group;
}
public XGroup[] GetGroups(string[] fields, string[] vals)
public Dictionary<UUID, XGroup> GetGroups()
{
Dictionary<UUID, XGroup> groupsClone = new Dictionary<UUID, XGroup>();
lock (m_groups)
foreach (XGroup group in m_groups.Values)
groupsClone[group.groupID] = group.Clone();
return groupsClone;
}
public bool DeleteGroup(UUID groupID)
{
lock (m_groups)
{
List<XGroup> origGroups = Get<XGroup>(fields, vals, m_groups.Values.ToList());
return origGroups.Select(g => g.Clone()).ToArray();
}
}
public bool DeleteGroups(string field, string val)
{
return DeleteGroups(new string[] { field }, new string[] { val });
}
public bool DeleteGroups(string[] fields, string[] vals)
{
lock (m_groups)
{
XGroup[] groupsToDelete = GetGroups(fields, vals);
Array.ForEach(groupsToDelete, g => m_groups.Remove(g.groupID));
}
return true;
return m_groups.Remove(groupID);
}
}
}
+32 -11
View File
@@ -166,18 +166,18 @@ namespace OpenSim.Data.PGSQL
";
string assetName = asset.Name;
if (asset.Name.Length > 64)
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
{
assetName = asset.Name.Substring(0, 64);
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 > 64)
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
{
assetDescription = asset.Description.Substring(0, 64);
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);
@@ -231,17 +231,38 @@ namespace OpenSim.Data.PGSQL
// }
/// <summary>
/// Check if asset exist in m_database
/// Check if the assets exist in the database.
/// </summary>
/// <param name="uuid"></param>
/// <returns>true if exist.</returns>
override public bool ExistsAsset(UUID uuid)
/// <param name="uuids">The assets' IDs</param>
/// <returns>For each asset: true if it exists, false otherwise</returns>
public override bool[] AssetsExist(UUID[] uuids)
{
if (GetAsset(uuid) != null)
if (uuids.Length == 0)
return new bool[0];
HashSet<UUID> exist = new HashSet<UUID>();
string ids = "'" + string.Join("','", uuids) + "'";
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
{
return true;
conn.Open();
using (NpgsqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
UUID id = DBGuid.FromDB(reader["id"]);
exist.Add(id);
}
}
}
return false;
bool[] results = new bool[uuids.Length];
for (int i = 0; i < uuids.Length; i++)
results[i] = exist.Contains(uuids[i]);
return results;
}
/// <summary>
+1 -1
View File
@@ -51,7 +51,7 @@ namespace OpenSim.Data.PGSQL
}
public bool Delete(string principalID, string friend)
public override bool Delete(string principalID, string friend)
{
UUID princUUID = UUID.Zero;
+19 -1
View File
@@ -300,7 +300,6 @@ namespace OpenSim.Data.PGSQL
m_Realm, where);
cmd.Connection = conn;
cmd.CommandText = query;
//m_log.WarnFormat("[PGSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where);
conn.Open();
@@ -308,6 +307,25 @@ namespace OpenSim.Data.PGSQL
}
}
public virtual T[] Get(string where, NpgsqlParameter parameter)
{
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
using (NpgsqlCommand cmd = new NpgsqlCommand())
{
string query = String.Format("SELECT * FROM {0} WHERE {1}",
m_Realm, where);
cmd.Connection = conn;
cmd.CommandText = query;
//m_log.WarnFormat("[PGSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where);
cmd.Parameters.Add(parameter);
conn.Open();
return DoQuery(cmd);
}
}
public virtual bool Store(T row)
{
List<string> constraintFields = GetConstraints();
+7 -3
View File
@@ -83,11 +83,15 @@ namespace OpenSim.Data.PGSQL
public GroupData[] RetrieveGroups(string pattern)
{
if (string.IsNullOrEmpty(pattern)) // True for where clause
{
pattern = " true ORDER BY lower(\"Name\") LIMIT 100";
return m_Groups.Get(pattern);
}
else
pattern = string.Format(" lower(\"Name\") LIKE lower('%{0}%') ORDER BY lower(\"Name\") LIMIT 100", pattern);
return m_Groups.Get(pattern);
{
pattern = " lower(\"Name\") LIKE lower('%:pattern%') ORDER BY lower(\"Name\") LIMIT 100";
return m_Groups.Get(pattern, new NpgsqlParameter("pattern", pattern));
}
}
public bool DeleteGroup(UUID groupID)
+37
View File
@@ -406,6 +406,43 @@ namespace OpenSim.Data.PGSQL
return exists;
}
/// <summary>
/// Check if the assets exist in the database.
/// </summary>
/// <param name="uuids">The assets' IDs</param>
/// <returns>For each asset: true if it exists, false otherwise</returns>
public bool[] AssetsExist(UUID[] uuids)
{
if (uuids.Length == 0)
return new bool[0];
HashSet<UUID> exist = new HashSet<UUID>();
string ids = "'" + string.Join("','", uuids) + "'";
string sql = string.Format(@"SELECT ""ID"" FROM XAssetsMeta WHERE ""ID"" IN ({0})", ids);
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
{
conn.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
{
using (NpgsqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
UUID id = DBGuid.FromDB(reader["id"]);
exist.Add(id);
}
}
}
}
bool[] results = new bool[uuids.Length];
for (int i = 0; i < uuids.Length; i++)
results[i] = exist.Contains(uuids[i]);
return results;
}
/// <summary>
/// Check if the asset exists in the database
/// </summary>
@@ -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.7.6.*")]
[assembly : AssemblyVersion("0.8.0.*")]
+27 -20
View File
@@ -134,25 +134,25 @@ namespace OpenSim.Data.SQLite
override public void StoreAsset(AssetBase asset)
{
string assetName = asset.Name;
if (asset.Name.Length > 64)
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
{
assetName = asset.Name.Substring(0, 64);
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 > 64)
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
{
assetDescription = asset.Description.Substring(0, 64);
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);
}
//m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString());
if (ExistsAsset(asset.FullID))
if (AssetsExist(new[] { asset.FullID })[0])
{
//LogAssetLoad(asset);
@@ -214,32 +214,39 @@ namespace OpenSim.Data.SQLite
// }
/// <summary>
/// Check if an asset exist in database
/// Check if the assets exist in the database.
/// </summary>
/// <param name="uuid">The asset UUID</param>
/// <returns>True if exist, or false.</returns>
override public bool ExistsAsset(UUID uuid)
/// <param name="uuids">The assets' IDs</param>
/// <returns>For each asset: true if it exists, false otherwise</returns>
public override bool[] AssetsExist(UUID[] uuids)
{
lock (this)
if (uuids.Length == 0)
return new bool[0];
HashSet<UUID> exist = new HashSet<UUID>();
string ids = "'" + string.Join("','", uuids) + "'";
string sql = string.Format("select UUID from assets where UUID in ({0})", ids);
lock (this)
{
using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn))
using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))
{
cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
using (IDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
while (reader.Read())
{
reader.Close();
return true;
}
else
{
reader.Close();
return false;
UUID id = new UUID((string)reader["UUID"]);
exist.Add(id);
}
}
}
}
bool[] results = new bool[uuids.Length];
for (int i = 0; i < uuids.Length; i++)
results[i] = exist.Contains(uuids[i]);
return results;
}
/// <summary>
+1 -1
View File
@@ -67,7 +67,7 @@ namespace OpenSim.Data.SQLite
return Delete(principalID.ToString(), friend);
}
public bool Delete(string principalID, string friend)
public override bool Delete(string principalID, string friend)
{
using (SqliteCommand cmd = new SqliteCommand())
{
+2 -2
View File
@@ -1605,7 +1605,7 @@ namespace OpenSim.Data.SQLite
prim.SitName = (String)row["SitName"];
prim.TouchName = (String)row["TouchName"];
// permissions
prim.ObjectFlags = Convert.ToUInt32(row["ObjectFlags"]);
prim.Flags = (PrimFlags)Convert.ToUInt32(row["ObjectFlags"]);
prim.CreatorIdentification = (String)row["CreatorID"];
prim.OwnerID = new UUID((String)row["OwnerID"]);
prim.GroupID = new UUID((String)row["GroupID"]);
@@ -2034,7 +2034,7 @@ namespace OpenSim.Data.SQLite
row["SitName"] = prim.SitName;
row["TouchName"] = prim.TouchName;
// permissions
row["ObjectFlags"] = prim.ObjectFlags;
row["ObjectFlags"] = (uint)prim.Flags;
row["CreatorID"] = prim.CreatorIdentification.ToString();
row["OwnerID"] = prim.OwnerID.ToString();
row["GroupID"] = prim.GroupID.ToString();
@@ -50,7 +50,6 @@ namespace OpenSim.Data.SQLite
private SqliteConnection m_connection;
private string m_connectionString;
private FieldInfo[] m_Fields;
private Dictionary<string, FieldInfo> m_FieldMap =
new Dictionary<string, FieldInfo>();
@@ -585,9 +584,6 @@ namespace OpenSim.Data.SQLite
}
if(reader != null && reader.Read())
{
m_log.DebugFormat("[PROFILES_DATA]" +
": Getting data for {0}.", props.UserId);
props.WebUrl = (string)reader["profileURL"];
UUID.TryParse((string)reader["profileImage"], out props.ImageId);
props.AboutText = (string)reader["profileAboutText"];
@@ -602,9 +598,6 @@ namespace OpenSim.Data.SQLite
}
else
{
m_log.DebugFormat("[PROFILES_DATA]" +
": No data for {0}", props.UserId);
props.WebUrl = string.Empty;
props.ImageId = UUID.Zero;
props.AboutText = string.Empty;
+9 -7
View File
@@ -107,10 +107,11 @@ namespace OpenSim.Data.Tests
public void T001_LoadEmpty()
{
TestHelpers.InMethod();
Assert.That(m_db.ExistsAsset(uuid1), Is.False);
Assert.That(m_db.ExistsAsset(uuid2), Is.False);
Assert.That(m_db.ExistsAsset(uuid3), Is.False);
bool[] exist = m_db.AssetsExist(new[] { uuid1, uuid2, uuid3 });
Assert.IsFalse(exist[0]);
Assert.IsFalse(exist[1]);
Assert.IsFalse(exist[2]);
}
[Test]
@@ -159,9 +160,10 @@ namespace OpenSim.Data.Tests
AssetBase a3b = m_db.GetAsset(uuid3);
Assert.That(a3b, Constraints.PropertyCompareConstraint(a3a));
Assert.That(m_db.ExistsAsset(uuid1), Is.True);
Assert.That(m_db.ExistsAsset(uuid2), Is.True);
Assert.That(m_db.ExistsAsset(uuid3), Is.True);
bool[] exist = m_db.AssetsExist(new[] { uuid1, uuid2, uuid3 });
Assert.IsTrue(exist[0]);
Assert.IsTrue(exist[1]);
Assert.IsTrue(exist[2]);
List<AssetMetadata> metadatas = m_db.FetchAssetMetadataSet(0, 1000);
@@ -99,6 +99,9 @@ namespace OpenSim.Data.Tests
if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd"))
Assert.Ignore();
if (Util.IsWindows())
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
// for SQLite, if no explicit conn string is specified, use a temp file
if (String.IsNullOrEmpty(m_connStr))
{
+2
View File
@@ -321,6 +321,8 @@ namespace OpenSim.Framework
Mac = args["mac"].AsString();
if (args["id0"] != null)
Id0 = args["id0"].AsString();
if (args["teleport_flags"] != null)
teleportFlags = args["teleport_flags"].AsUInteger();
if (args["start_pos"] != null)
Vector3.TryParse(args["start_pos"].AsString(), out startpos);
+5
View File
@@ -132,6 +132,11 @@ namespace OpenSim.Framework
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public override string ToString()
{
return "AnimID=" + AnimID.ToString()
+3
View File
@@ -50,6 +50,9 @@ namespace OpenSim.Framework
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public static readonly int MAX_ASSET_NAME = 64;
public static readonly int MAX_ASSET_DESC = 64;
/// <summary>
/// Data of the Asset
/// </summary>
+8 -10
View File
@@ -98,11 +98,11 @@ namespace OpenSim.Framework
/// </remarks>
public bool Contains(T item)
{
if (m_queue.Count < 1 && m_pqueue.Count < 1)
return false;
lock (m_queueSync)
{
if (m_queue.Count < 1 && m_pqueue.Count < 1)
return false;
if (m_pqueue.Contains(item))
return true;
return m_queue.Contains(item);
@@ -112,12 +112,10 @@ namespace OpenSim.Framework
/// <summary>
/// Return a count of the number of requests on this queue.
/// </summary>
/// <remarks>
/// This method is not thread-safe. Do not rely on the result without consistent external locking.
/// </remarks>
public int Count()
{
return m_queue.Count + m_pqueue.Count;
lock (m_queueSync)
return m_queue.Count + m_pqueue.Count;
}
/// <summary>
@@ -128,11 +126,11 @@ namespace OpenSim.Framework
/// </remarks>
public T[] GetQueueArray()
{
if (m_queue.Count < 1 && m_pqueue.Count < 1)
return new T[0];
lock (m_queueSync)
{
if (m_queue.Count < 1 && m_pqueue.Count < 1)
return new T[0];
return m_queue.ToArray();
}
}
+35 -6
View File
@@ -35,6 +35,8 @@ using System.Threading;
using System.Web;
using log4net;
using OpenSim.Framework.ServiceAuth;
namespace OpenSim.Framework.Communications
{
/// <summary>
@@ -298,6 +300,14 @@ namespace OpenSim.Framework.Communications
/// Perform a synchronous request
/// </summary>
public Stream Request()
{
return Request(null);
}
/// <summary>
/// Perform a synchronous request
/// </summary>
public Stream Request(IServiceAuth auth)
{
lock (_lock)
{
@@ -307,6 +317,8 @@ namespace OpenSim.Framework.Communications
_request.Timeout = 200000;
_request.Method = RequestMethod;
_asyncException = null;
if (auth != null)
auth.AddAuthorization(_request.Headers);
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
try
@@ -318,12 +330,12 @@ namespace OpenSim.Framework.Communications
HttpWebResponse errorResponse = e.Response as HttpWebResponse;
if (null != errorResponse && HttpStatusCode.NotFound == errorResponse.StatusCode)
{
m_log.Warn("[REST CLIENT] Resource not found (404)");
// This is often benign. E.g., requesting a missing asset will return 404.
m_log.DebugFormat("[REST CLIENT] Resource not found (404): {0}", _request.Address.ToString());
}
else
{
m_log.Error("[REST CLIENT] Error fetching resource from server " + _request.Address.ToString());
m_log.Debug(e.ToString());
m_log.Error(string.Format("[REST CLIENT] Error fetching resource from server: {0} ", _request.Address.ToString()), e);
}
return null;
@@ -358,7 +370,7 @@ namespace OpenSim.Framework.Communications
}
}
public Stream Request(Stream src)
public Stream Request(Stream src, IServiceAuth auth)
{
_request = (HttpWebRequest) WebRequest.Create(buildUri());
_request.KeepAlive = false;
@@ -367,6 +379,8 @@ namespace OpenSim.Framework.Communications
_request.Method = RequestMethod;
_asyncException = null;
_request.ContentLength = src.Length;
if (auth != null)
auth.AddAuthorization(_request.Headers);
m_log.InfoFormat("[REST]: Request Length {0}", _request.ContentLength);
m_log.InfoFormat("[REST]: Sending Web Request {0}", buildUri());
@@ -384,7 +398,22 @@ namespace OpenSim.Framework.Communications
length = src.Read(buf, 0, 1024);
}
_response = (HttpWebResponse) _request.GetResponse();
try
{
_response = (HttpWebResponse)_request.GetResponse();
}
catch (WebException e)
{
m_log.WarnFormat("[REST]: Request {0} {1} failed with status {2} and message {3}",
RequestMethod, _request.RequestUri, e.Status, e.Message);
}
catch (Exception e)
{
m_log.WarnFormat(
"[REST]: Request {0} {1} failed with exception {2} {3}",
RequestMethod, _request.RequestUri, e.Message, e.StackTrace);
}
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
@@ -423,7 +452,7 @@ namespace OpenSim.Framework.Communications
try
{
// Perform the operation; if sucessful set the result
Stream s = Request();
Stream s = Request(null);
ar.SetAsCompleted(s, false);
}
catch (Exception e)
@@ -1,123 +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.IO;
using System.Net;
using System.Reflection;
using System.Text;
using log4net;
using OpenSim.Framework.Configuration.XML;
namespace OpenSim.Framework.Configuration.HTTP
{
public class HTTPConfiguration : IGenericConfig
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private RemoteConfigSettings remoteConfigSettings;
private XmlConfiguration xmlConfig;
private string configFileName = String.Empty;
public HTTPConfiguration()
{
remoteConfigSettings = new RemoteConfigSettings("remoteconfig.xml");
xmlConfig = new XmlConfiguration();
}
public void SetFileName(string fileName)
{
configFileName = fileName;
}
public void LoadData()
{
try
{
StringBuilder sb = new StringBuilder();
byte[] buf = new byte[8192];
HttpWebRequest request =
(HttpWebRequest) WebRequest.Create(remoteConfigSettings.baseConfigURL + configFileName);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream resStream = response.GetResponseStream())
{
string tempString = null;
int count = 0;
do
{
count = resStream.Read(buf, 0, buf.Length);
if (count != 0)
{
tempString = Util.UTF8.GetString(buf, 0, count);
sb.Append(tempString);
}
}
while (count > 0);
LoadDataFromString(sb.ToString());
}
}
}
catch (WebException)
{
m_log.Warn("Unable to connect to remote configuration file (" +
remoteConfigSettings.baseConfigURL + configFileName +
"). Creating local file instead.");
xmlConfig.SetFileName(configFileName);
xmlConfig.LoadData();
}
}
public void LoadDataFromString(string data)
{
xmlConfig.LoadDataFromString(data);
}
public string GetAttribute(string attributeName)
{
return xmlConfig.GetAttribute(attributeName);
}
public bool SetAttribute(string attributeName, string attributeValue)
{
return true;
}
public void Commit()
{
}
public void Close()
{
}
}
}
@@ -1,33 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 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.Configuration.HTTP")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("http://opensimulator.org")]
[assembly: AssemblyProduct("OpenSim")]
[assembly: AssemblyCopyright("OpenSimulator develoeprs")]
[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
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("cb78b672-d000-4f93-88f9-dae151cc0061")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("0.8.0.*")]
@@ -1,33 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 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.Configuration.XML")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("http://opensimulator.org")]
[assembly: AssemblyProduct("OpenSim")]
[assembly: AssemblyCopyright("OpenSimulator developers")]
[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
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("eeb880df-0112-4c3d-87ed-b2108d614c55")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("0.8.0.*")]
@@ -1,141 +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.IO;
using System.Xml;
namespace OpenSim.Framework.Configuration.XML
{
public class XmlConfiguration : IGenericConfig
{
private XmlDocument doc;
private XmlNode rootNode;
private XmlNode configNode;
private string fileName;
private bool createdFile = false;
public void SetFileName(string file)
{
fileName = file;
}
private void LoadDataToClass()
{
rootNode = doc.SelectSingleNode("Root");
if (null == rootNode)
throw new Exception("Error: Invalid .xml File. Missing <Root>");
configNode = rootNode.SelectSingleNode("Config");
if (null == configNode)
throw new Exception("Error: Invalid .xml File. <Root> should contain a <Config>");
}
public void LoadData()
{
lock (this)
{
doc = new XmlDocument();
if (File.Exists(fileName))
{
XmlTextReader reader = new XmlTextReader(fileName);
reader.WhitespaceHandling = WhitespaceHandling.None;
doc.Load(reader);
reader.Close();
}
else
{
createdFile = true;
rootNode = doc.CreateNode(XmlNodeType.Element, "Root", String.Empty);
doc.AppendChild(rootNode);
configNode = doc.CreateNode(XmlNodeType.Element, "Config", String.Empty);
rootNode.AppendChild(configNode);
}
LoadDataToClass();
if (createdFile)
{
Commit();
}
}
}
public void LoadDataFromString(string data)
{
doc = new XmlDocument();
doc.LoadXml(data);
LoadDataToClass();
}
public string GetAttribute(string attributeName)
{
string result = null;
if (configNode.Attributes[attributeName] != null)
{
result = ((XmlAttribute) configNode.Attributes.GetNamedItem(attributeName)).Value;
}
return result;
}
public bool SetAttribute(string attributeName, string attributeValue)
{
if (configNode.Attributes[attributeName] != null)
{
((XmlAttribute) configNode.Attributes.GetNamedItem(attributeName)).Value = attributeValue;
}
else
{
XmlAttribute attri;
attri = doc.CreateAttribute(attributeName);
attri.Value = attributeValue;
configNode.Attributes.Append(attri);
}
return true;
}
public void Commit()
{
if (string.IsNullOrEmpty(fileName))
return;
if (!Directory.Exists(Util.configDir()))
{
Directory.CreateDirectory(Util.configDir());
}
doc.Save(fileName);
}
public void Close()
{
configNode = null;
rootNode = null;
doc = null;
}
}
}
-530
View File
@@ -1,530 +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.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<ConfigurationOption> configurationOptions = new List<ConfigurationOption>();
private IGenericConfig configurationPlugin = null;
/// <summary>
/// This is the default configuration DLL loaded
/// </summary>
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();
}
}
}
@@ -27,37 +27,22 @@
using System;
namespace OpenSim.Framework.Configuration.HTTP
namespace OpenSim.Framework.Console
{
public class RemoteConfigSettings
/// <summary>
/// This will be a set of typical column sizes to allow greater consistency between console commands.
/// </summary>
public static class ConsoleDisplayUtil
{
private ConfigurationMember configMember;
public const int CoordTupleSize = 11;
public const int PortSize = 5;
public string baseConfigURL = String.Empty;
public const int EstateNameSize = 20;
public const int ParcelNameSize = 40;
public const int RegionNameSize = 20;
public const int UserNameSize = 35;
public RemoteConfigSettings(string filename)
{
configMember =
new ConfigurationMember(filename, "REMOTE CONFIG SETTINGS", loadConfigurationOptions,
handleIncomingConfiguration,true);
configMember.forceConfigurationPluginLibrary("OpenSim.Framework.Configuration.XML.dll");
configMember.performConfigurationRetrieve();
}
public void loadConfigurationOptions()
{
configMember.addConfigurationOption("base_config_url",
ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"URL Containing Configuration Files", "http://localhost/", false);
}
public bool handleIncomingConfiguration(string configuration_key, object configuration_result)
{
if (configuration_key == "base_config_url")
{
baseConfigURL = (string) configuration_result;
}
return true;
}
public const int UuidSize = 36;
public const int VectorSize = 15;
}
}
}
+67 -13
View File
@@ -252,24 +252,82 @@ namespace OpenSim.Framework.Console
/// The strings "~" and "-~" are valid in components. The first substitutes float.MaxValue whilst the second is float.MinValue
/// Other than that, component values must be numeric.
/// </param>
/// <param name='blankComponentFunc'></param>
/// <param name='blankComponentFunc'>
/// Behaviour if component is blank. If null then conversion fails on a blank component.
/// </param>
/// <param name='vector'></param>
/// <returns></returns>
public static bool TryParseConsoleVector(
string rawConsoleVector, Func<string, string> blankComponentFunc, out Vector3 vector)
{
List<string> components = rawConsoleVector.Split(VectorSeparatorChars).ToList();
if (components.Count < 1 || components.Count > 3)
return Vector3.TryParse(CookVector(rawConsoleVector, 3, blankComponentFunc), out vector);
}
/// <summary>
/// Convert a vector input from the console to an OpenMetaverse.Vector2
/// </summary>
/// <param name='rawConsoleVector'>
/// A string in the form <x>,<y> where there is no space between values.
/// Any component can be missing (e.g. ,40). blankComponentFunc is invoked to replace the blank with a suitable value
/// Also, if the blank component is at the end, then the comma can be missed off entirely (e.g. 40)
/// The strings "~" and "-~" are valid in components. The first substitutes float.MaxValue whilst the second is float.MinValue
/// Other than that, component values must be numeric.
/// </param>
/// <param name='blankComponentFunc'>
/// Behaviour if component is blank. If null then conversion fails on a blank component.
/// </param>
/// <param name='vector'></param>
/// <returns></returns>
public static bool TryParseConsole2DVector(
string rawConsoleVector, Func<string, string> blankComponentFunc, out Vector2 vector)
{
// We don't use Vector2.TryParse() for now because for some reason it expects an input with 3 components
// rather than 2.
string cookedVector = CookVector(rawConsoleVector, 2, blankComponentFunc);
if (cookedVector == null)
{
vector = Vector3.Zero;
vector = Vector2.Zero;
return false;
}
else
{
string[] cookedComponents = cookedVector.Split(VectorSeparatorChars);
vector = new Vector2(float.Parse(cookedComponents[0]), float.Parse(cookedComponents[1]));
return true;
}
//return Vector2.TryParse(CookVector(rawConsoleVector, 2, blankComponentFunc), out vector);
}
/// <summary>
/// Convert a raw console vector into a vector that can be be parsed by the relevant OpenMetaverse.TryParse()
/// </summary>
/// <param name='rawConsoleVector'></param>
/// <param name='dimensions'></param>
/// <param name='blankComponentFunc'></param>
/// <returns>null if conversion was not possible</returns>
private static string CookVector(
string rawConsoleVector, int dimensions, Func<string, string> blankComponentFunc)
{
List<string> components = rawConsoleVector.Split(VectorSeparatorChars).ToList();
for (int i = components.Count; i < 3; i++)
components.Add("");
if (components.Count < 1 || components.Count > dimensions)
return null;
List<string> semiDigestedComponents
if (components.Count < dimensions)
{
if (blankComponentFunc == null)
return null;
else
for (int i = components.Count; i < dimensions; i++)
components.Add("");
}
List<string> cookedComponents
= components.ConvertAll<string>(
c =>
{
@@ -283,11 +341,7 @@ namespace OpenSim.Framework.Console
return c;
});
string semiDigestedConsoleVector = string.Join(VectorSeparator, semiDigestedComponents.ToArray());
// m_log.DebugFormat("[CONSOLE UTIL]: Parsing {0} into OpenMetaverse.Vector3", semiDigestedConsoleVector);
return Vector3.TryParse(semiDigestedConsoleVector, out vector);
return string.Join(VectorSeparator, cookedComponents.ToArray());
}
}
}
+7 -5
View File
@@ -46,6 +46,11 @@ namespace OpenSim.Framework.Console
// private readonly object m_syncRoot = new object();
private const string LOGLEVEL_NONE = "(none)";
// Used to extract categories for colourization.
private Regex m_categoryRegex
= new Regex(
@"^(?<Front>.*?)\[(?<Category>[^\]]+)\]:?(?<End>.*)", RegexOptions.Singleline | RegexOptions.Compiled);
private int m_cursorYPosition = -1;
private int m_cursorXPosition = 0;
private StringBuilder m_commandLine = new StringBuilder();
@@ -280,11 +285,8 @@ namespace OpenSim.Framework.Console
string outText = text;
if (level != LOGLEVEL_NONE)
{
string regex = @"^(?<Front>.*?)\[(?<Category>[^\]]+)\]:?(?<End>.*)";
Regex RE = new Regex(regex, RegexOptions.Multiline);
MatchCollection matches = RE.Matches(text);
{
MatchCollection matches = m_categoryRegex.Matches(text);
if (matches.Count == 1)
{
+2
View File
@@ -40,7 +40,9 @@ namespace OpenSim.Framework.Console
/// </summary>
public class MockConsole : ICommandConsole
{
#pragma warning disable 0067
public event OnOutputDelegate OnOutput;
#pragma warning restore 0067
private MockCommands m_commands = new MockCommands();
+49
View File
@@ -25,6 +25,10 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using OpenMetaverse;
namespace OpenSim.Framework
@@ -111,5 +115,50 @@ namespace OpenSim.Framework
}
}
public EstateBan() { }
public Dictionary<string, object> ToMap()
{
Dictionary<string, object> map = new Dictionary<string, object>();
PropertyInfo[] properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo p in properties)
map[p.Name] = p.GetValue(this, null);
return map;
}
public EstateBan(Dictionary<string, object> map)
{
foreach (KeyValuePair<string, object> kvp in map)
{
PropertyInfo p = this.GetType().GetProperty(kvp.Key, BindingFlags.Public | BindingFlags.Instance);
if (p == null)
continue;
object value = p.GetValue(this, null);
if (value is String)
p.SetValue(this, map[p.Name], null);
else if (value is UInt32)
p.SetValue(this, UInt32.Parse((string)map[p.Name]), null);
else if (value is Boolean)
p.SetValue(this, Boolean.Parse((string)map[p.Name]), null);
else if (value is UUID)
p.SetValue(this, UUID.Parse((string)map[p.Name]), null);
}
}
/// <summary>
/// For debugging
/// </summary>
/// <returns></returns>
public override string ToString()
{
Dictionary<string, object> map = ToMap();
string result = string.Empty;
foreach (KeyValuePair<string, object> kvp in map)
result += string.Format("{0}: {1} {2}", kvp.Key, kvp.Value, Environment.NewLine);
return result;
}
}
}
+115
View File
@@ -28,6 +28,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using OpenMetaverse;
namespace OpenSim.Framework
@@ -411,5 +412,119 @@ namespace OpenSim.Framework
{
return l_EstateGroups.Contains(groupID);
}
public Dictionary<string, object> ToMap()
{
Dictionary<string, object> map = new Dictionary<string, object>();
PropertyInfo[] properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo p in properties)
{
// EstateBans is a complex type, let's treat it as special
if (p.Name == "EstateBans")
continue;
object value = p.GetValue(this, null);
if (value != null)
{
if (p.PropertyType.IsArray) // of UUIDs
{
if (((Array)value).Length > 0)
{
string[] args = new string[((Array)value).Length];
int index = 0;
foreach (object o in (Array)value)
args[index++] = o.ToString();
map[p.Name] = String.Join(",", args);
}
}
else // simple types
map[p.Name] = value;
}
}
// EstateBans are special
if (EstateBans.Length > 0)
{
Dictionary<string, object> bans = new Dictionary<string, object>();
int i = 0;
foreach (EstateBan ban in EstateBans)
bans["ban" + i++] = ban.ToMap();
map["EstateBans"] = bans;
}
return map;
}
/// <summary>
/// For debugging
/// </summary>
/// <returns></returns>
public override string ToString()
{
Dictionary<string, object> map = ToMap();
String result = String.Empty;
foreach (KeyValuePair<string, object> kvp in map)
{
if (kvp.Key == "EstateBans")
{
result += "EstateBans:" + Environment.NewLine;
foreach (KeyValuePair<string, object> ban in (Dictionary<string, object>)kvp.Value)
result += ban.Value.ToString();
}
else
result += string.Format("{0}: {1} {2}", kvp.Key, kvp.Value.ToString(), Environment.NewLine);
}
return result;
}
public EstateSettings(Dictionary<string, object> map)
{
foreach (KeyValuePair<string, object> kvp in map)
{
PropertyInfo p = this.GetType().GetProperty(kvp.Key, BindingFlags.Public | BindingFlags.Instance);
if (p == null)
continue;
// EstateBans is a complex type, let's treat it as special
if (p.Name == "EstateBans")
continue;
if (p.PropertyType.IsArray)
{
string[] elements = ((string)map[p.Name]).Split(new char[] { ',' });
UUID[] uuids = new UUID[elements.Length];
int i = 0;
foreach (string e in elements)
uuids[i++] = new UUID(e);
p.SetValue(this, uuids, null);
}
else
{
object value = p.GetValue(this, null);
if (value is String)
p.SetValue(this, map[p.Name], null);
else if (value is UInt32)
p.SetValue(this, UInt32.Parse((string)map[p.Name]), null);
else if (value is Boolean)
p.SetValue(this, Boolean.Parse((string)map[p.Name]), null);
else if (value is UUID)
p.SetValue(this, UUID.Parse((string)map[p.Name]), null);
}
}
// EstateBans are special
if (map.ContainsKey("EstateBans"))
{
var banData = ((Dictionary<string, object>)map["EstateBans"]).Values;
EstateBan[] bans = new EstateBan[banData.Count];
int b = 0;
foreach (Dictionary<string, object> ban in banData)
bans[b++] = new EstateBan(ban);
PropertyInfo bansProperty = this.GetType().GetProperty("EstateBans", BindingFlags.Public | BindingFlags.Instance);
bansProperty.SetValue(this, bans, null);
}
}
}
}
+1
View File
@@ -38,6 +38,7 @@ namespace OpenSim.Framework
int GetParcelMaxPrimCount();
int GetSimulatorMaxPrimCount();
int GetPrimsFree();
Dictionary<UUID, int> GetLandObjectOwners();
LandData LandData { get; set; }
bool[,] LandBitmap { get; set; }
+8 -1
View File
@@ -35,6 +35,10 @@ namespace OpenSim.Framework
/// </summary>
public class InventoryItemBase : InventoryNodeBase, ICloneable
{
public static readonly string SUITCASE_FOLDER_NAME = "My Suitcase";
public static readonly sbyte SUITCASE_FOLDER_TYPE = 100;
public static readonly sbyte SUITCASE_FOLDER_FAKE_TYPE = 8;
/// <value>
/// The inventory type of the item. This is slightly different from the asset type in some situations.
/// </value>
@@ -82,12 +86,15 @@ namespace OpenSim.Framework
set
{
m_creatorId = value;
if ((m_creatorId == null) || !UUID.TryParse(m_creatorId, out m_creatorIdAsUuid))
m_creatorIdAsUuid = UUID.Zero;
}
}
protected string m_creatorId;
/// <value>
/// The CreatorId expressed as a UUID.tely
/// The CreatorId expressed as a UUID.
/// </value>
public UUID CreatorIdAsUuid
{
+50 -7
View File
@@ -26,7 +26,10 @@
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Timers;
using log4net;
@@ -45,13 +48,22 @@ namespace OpenSim.Framework.Monitoring
public static void RegisterConsoleCommands(ICommandConsole console)
{
console.Commands.AddCommand(
"Debug",
"General",
false,
"debug stats record",
"debug stats record start|stop",
"stats record",
"stats record start|stop",
"Control whether stats are being regularly recorded to a separate file.",
"For debug purposes. Experimental.",
HandleStatsRecordCommand);
console.Commands.AddCommand(
"General",
false,
"stats save",
"stats save <path>",
"Save stats snapshot to a file. If the file already exists, then the report is appended.",
"For debug purposes. Experimental.",
HandleStatsSaveCommand);
}
public static void HandleStatsRecordCommand(string module, string[] cmd)
@@ -76,6 +88,27 @@ namespace OpenSim.Framework.Monitoring
}
}
public static void HandleStatsSaveCommand(string module, string[] cmd)
{
ICommandConsole con = MainConsole.Instance;
if (cmd.Length != 3)
{
con.Output("Usage: stats save <path>");
return;
}
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);
}
public static void Start()
{
if (m_loggingTimer != null)
@@ -97,12 +130,22 @@ namespace OpenSim.Framework.Monitoring
private static void Log(object sender, ElapsedEventArgs e)
{
m_statsLog.InfoFormat("*** STATS REPORT AT {0} ***", DateTime.Now);
foreach (string report in StatsManager.GetAllStatsReports())
m_statsLog.Info(report);
foreach (string line in GetReport())
m_statsLog.Info(line);
m_loggingTimer.Start();
}
private static List<string> GetReport()
{
List<string> lines = new List<string>();
lines.Add(string.Format("*** STATS REPORT AT {0} ***", DateTime.Now));
foreach (string report in StatsManager.GetAllStatsReports())
lines.Add(report);
return lines;
}
}
}
+33 -3
View File
@@ -72,8 +72,8 @@ namespace OpenSim.Framework.Monitoring
console.Commands.AddCommand(
"General",
false,
"show stats",
"show stats [list|all|(<category>[.<container>])+",
"stats show",
"stats show [list|all|(<category>[.<container>])+",
"Show statistical information for this server",
"If no final argument is specified then legacy statistics information is currently shown.\n"
+ "'list' argument will show statistic categories.\n"
@@ -84,6 +84,14 @@ namespace OpenSim.Framework.Monitoring
+ "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS",
HandleShowStatsCommand);
console.Commands.AddCommand(
"General",
false,
"show stats",
"show stats [list|all|(<category>[.<container>])+",
"Alias for 'stats show' command",
HandleShowStatsCommand);
StatsLogger.RegisterConsoleCommands(console);
}
@@ -99,6 +107,7 @@ namespace OpenSim.Framework.Monitoring
string categoryName = components[0];
string containerName = components.Length > 1 ? components[1] : null;
string statName = components.Length > 2 ? components[2] : null;
if (categoryName == AllSubCommand)
{
@@ -128,7 +137,23 @@ namespace OpenSim.Framework.Monitoring
SortedDictionary<string, Stat> container;
if (category.TryGetValue(containerName, out container))
{
OutputContainerStatsToConsole(con, container);
if (String.IsNullOrEmpty(statName))
{
OutputContainerStatsToConsole(con, container);
}
else
{
Stat stat;
if (container.TryGetValue(statName, out stat))
{
OutputStatToConsole(con, stat);
}
else
{
con.OutputFormat(
"No such stat {0} in {1}.{2}", statName, categoryName, containerName);
}
}
}
else
{
@@ -200,6 +225,11 @@ namespace OpenSim.Framework.Monitoring
con.Output(report);
}
private static void OutputStatToConsole(ICommandConsole con, Stat stat)
{
con.Output(stat.ToConsoleString());
}
// Creates an OSDMap of the format:
// { categoryName: {
// containerName: {
+26
View File
@@ -82,12 +82,32 @@ namespace OpenSim.Framework.Monitoring
/// </summary>
public Func<string> AlarmMethod { get; set; }
/// <summary>
/// Stat structure associated with this thread.
/// </summary>
public Stat Stat { get; set; }
public ThreadWatchdogInfo(Thread thread, int timeout)
{
Thread = thread;
Timeout = timeout;
FirstTick = Environment.TickCount & Int32.MaxValue;
LastTick = FirstTick;
Stat
= new Stat(
thread.Name,
string.Format("Last update of thread {0}", thread.Name),
"",
"ms",
"server",
"thread",
StatType.Pull,
MeasuresOfInterest.None,
stat => stat.Value = Environment.TickCount & Int32.MaxValue - LastTick,
StatVerbosity.Debug);
StatsManager.RegisterStat(Stat);
}
public ThreadWatchdogInfo(ThreadWatchdogInfo previousTwi)
@@ -100,6 +120,11 @@ namespace OpenSim.Framework.Monitoring
AlarmIfTimeout = previousTwi.AlarmIfTimeout;
AlarmMethod = previousTwi.AlarmMethod;
}
public void Cleanup()
{
StatsManager.DeregisterStat(Stat);
}
}
/// <summary>
@@ -238,6 +263,7 @@ namespace OpenSim.Framework.Monitoring
m_log.DebugFormat(
"[WATCHDOG]: Removing thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
twi.Cleanup();
m_threads.Remove(threadID);
return true;
+7 -6
View File
@@ -215,7 +215,7 @@ namespace OpenSim.Framework
AddinManager.AddinLoadError += on_addinloaderror_;
AddinManager.AddinLoaded += on_addinloaded_;
clear_registry_();
clear_registry_(dir);
suppress_console_output_(true);
AddinManager.Initialize(dir);
@@ -239,18 +239,19 @@ namespace OpenSim.Framework
+ args.Exception.StackTrace);
}
private void clear_registry_()
private void clear_registry_(string dir)
{
// The Mono addin manager (in Mono.Addins.dll version 0.2.0.0)
// occasionally seems to corrupt its addin cache
// Hence, as a temporary solution we'll remove it before each startup
try
{
if (Directory.Exists("addin-db-000"))
Directory.Delete("addin-db-000", true);
if (Directory.Exists(dir + "/addin-db-000"))
Directory.Delete(dir + "/addin-db-000", true);
if (Directory.Exists("addin-db-001"))
Directory.Delete("addin-db-001", true);
if (Directory.Exists(dir + "/addin-db-001"))
Directory.Delete(dir + "/addin-db-001", true);
}
catch (IOException)
{
+53 -252
View File
@@ -102,7 +102,6 @@ namespace OpenSim.Framework
private static readonly string LogHeader = "[REGION INFO]";
public bool commFailTF = false;
public ConfigurationMember configMember;
public string RegionFile = String.Empty;
public bool isSandbox = false;
public bool Persistent = true;
@@ -127,6 +126,7 @@ namespace OpenSim.Framework
private int m_physPrimMax = 0;
private bool m_clampPrimSize = false;
private int m_objectCapacity = 0;
private int m_maxPrimsPerUser = -1;
private int m_linksetCapacity = 0;
private int m_agentCapacity = 0;
private string m_regionType = String.Empty;
@@ -147,11 +147,32 @@ namespace OpenSim.Framework
public uint WorldLocX = 0;
public uint WorldLocY = 0;
public uint WorldLocZ = 0;
/// <summary>
/// X dimension of the region.
/// </summary>
/// <remarks>
/// If this is a varregion then the default size set here will be replaced when we load the region config.
/// </remarks>
public uint RegionSizeX = Constants.RegionSize;
/// <summary>
/// X dimension of the region.
/// </summary>
/// <remarks>
/// If this is a varregion then the default size set here will be replaced when we load the region config.
/// </remarks>
public uint RegionSizeY = Constants.RegionSize;
/// <summary>
/// Z dimension of the region.
/// </summary>
/// <remarks>
/// XXX: Unknown if this accounts for regions with negative Z.
/// </remarks>
public uint RegionSizeZ = Constants.RegionHeight;
private Dictionary<String, String> m_otherSettings = new Dictionary<string, string>();
private Dictionary<String, String> m_extraSettings = new Dictionary<string, string>();
// Apparently, we're applying the same estatesettings regardless of whether it's local or remote.
@@ -203,7 +224,6 @@ namespace OpenSim.Framework
try
{
// This will throw if it's not legal Nini XML format
// and thereby toss it to the legacy loader
//
IConfigSource xmlsource = new XmlConfigSource(filename);
@@ -216,21 +236,18 @@ namespace OpenSim.Framework
catch (Exception)
{
}
configMember =
new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration, !skipConsoleConfig);
configMember.performConfigurationRetrieve();
RegionFile = filename;
}
// The web loader uses this
//
public RegionInfo(string description, XmlNode xmlNode, bool skipConsoleConfig, IConfigSource configSource)
{
// m_configSource = configSource;
configMember =
new ConfigurationMember(xmlNode, description, loadConfigurationOptions, handleIncomingConfiguration, !skipConsoleConfig);
configMember.performConfigurationRetrieve();
XmlElement elem = (XmlElement)xmlNode;
string name = elem.GetAttribute("Name");
string xmlstr = "<Nini>" + xmlNode.OuterXml + "</Nini>";
XmlConfigSource source = new XmlConfigSource(XmlReader.Create(new StringReader(xmlstr)));
ReadNiniConfig(source, name);
m_serverURI = string.Empty;
}
@@ -325,6 +342,11 @@ namespace OpenSim.Framework
get { return m_objectCapacity; }
}
public int MaxPrimsPerUser
{
get { return m_maxPrimsPerUser; }
}
public int LinksetCapacity
{
get { return m_linksetCapacity; }
@@ -349,6 +371,8 @@ namespace OpenSim.Framework
{
get { return m_maptileStaticUUID; }
}
public string MaptileStaticFile { get; private set; }
/// <summary>
/// The port by which http communication occurs with the region (most noticeably, CAPS communication)
@@ -498,20 +522,20 @@ namespace OpenSim.Framework
m_internalEndPoint = tmpEPE;
}
public string GetOtherSetting(string key)
public string GetSetting(string key)
{
string val;
string keylower = key.ToLower();
if (m_otherSettings.TryGetValue(keylower, out val))
if (m_extraSettings.TryGetValue(keylower, out val))
return val;
m_log.DebugFormat("[RegionInfo] Could not locate value for parameter {0}", key);
return null;
}
public void SetOtherSetting(string key, string value)
private void SetExtraSetting(string key, string value)
{
string keylower = key.ToLower();
m_otherSettings[keylower] = value;
m_extraSettings[keylower] = value;
}
private void ReadNiniConfig(IConfigSource source, string name)
@@ -707,6 +731,9 @@ namespace OpenSim.Framework
m_objectCapacity = config.GetInt("MaxPrims", 15000);
allKeys.Remove("MaxPrims");
m_maxPrimsPerUser = config.GetInt("MaxPrimsPerUser", -1);
allKeys.Remove("MaxPrimsPerUser");
m_linksetCapacity = config.GetInt("LinksetPrims", 0);
allKeys.Remove("LinksetPrims");
@@ -716,6 +743,9 @@ namespace OpenSim.Framework
{
config.Set("MaptileStaticUUID", m_maptileStaticUUID.ToString());
}
MaptileStaticFile = config.GetString("MaptileStaticFile", String.Empty);
allKeys.Remove("MaptileStaticFile");
#endregion
@@ -729,7 +759,7 @@ namespace OpenSim.Framework
foreach (String s in allKeys)
{
SetOtherSetting(s, config.GetString(s));
SetExtraSetting(s, config.GetString(s));
}
}
@@ -829,6 +859,9 @@ namespace OpenSim.Framework
if (m_objectCapacity > 0)
config.Set("MaxPrims", m_objectCapacity);
if (m_maxPrimsPerUser > -1)
config.Set("MaxPrimsPerUser", m_maxPrimsPerUser);
if (m_linksetCapacity > 0)
config.Set("LinksetPrims", m_linksetCapacity);
@@ -843,6 +876,9 @@ namespace OpenSim.Framework
if (m_maptileStaticUUID != UUID.Zero)
config.Set("MaptileStaticUUID", m_maptileStaticUUID.ToString());
if (MaptileStaticFile != String.Empty)
config.Set("MaptileStaticFile", MaptileStaticFile);
}
public bool ignoreIncomingConfiguration(string configuration_key, object configuration_result)
@@ -869,249 +905,14 @@ namespace OpenSim.Framework
return;
}
else if (filename.ToLower().EndsWith(".xml"))
{
configMember = new ConfigurationMember(filename, description, loadConfigurationOptionsFromMe,
ignoreIncomingConfiguration, false);
configMember.performConfigurationRetrieve();
RegionFile = filename;
}
else
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("allow_alternate_ports",
ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
"Allow sim to find alternate UDP ports when ports are in use?",
m_allow_alternate_ports.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", m_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("allow_alternate_ports", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
"Allow sim to find alternate UDP ports when ports are in use?",
"false", true);
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 "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 "allow_alternate_ports":
m_allow_alternate_ports = (bool) 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":
m_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;
lastMapRefresh = Util.UnixTimeSinceEpoch().ToString();
if (configMember == null)
return;
configMember.forceSetConfigurationOption("lastmap_uuid", mapUUID.ToString());
configMember.forceSetConfigurationOption("lastmap_refresh", lastMapRefresh);
}
public OSDMap PackRegionInfoData()
@@ -98,7 +98,7 @@ namespace OpenSim.Framework.RegionLoader.Web
xmlSource.Length);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlSource);
if (xmlDoc.FirstChild.Name == "Regions")
if (xmlDoc.FirstChild.Name == "Nini")
{
regionCount = xmlDoc.FirstChild.ChildNodes.Count;
@@ -144,4 +144,4 @@ namespace OpenSim.Framework.RegionLoader.Web
}
}
}
}
}
@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -161,7 +161,7 @@ namespace OpenSim.Framework.Serialization.External
if (!hasCreatorData && creator != null)
{
XmlElement creatorData = doc.CreateElement("CreatorData");
creatorData.InnerText = homeURL + ";" + creator.FirstName + " " + creator.LastName;
creatorData.InnerText = CalcCreatorData(homeURL, creator.FirstName + " " + creator.LastName);
sop.AppendChild(creatorData);
}
}
@@ -172,5 +172,15 @@ namespace OpenSim.Framework.Serialization.External
return wr.ToString();
}
}
public static string CalcCreatorData(string homeURL, string name)
{
return homeURL + ";" + name;
}
internal static string CalcCreatorData(string homeURL, UUID uuid, string name)
{
return homeURL + "/" + uuid + ";" + name;
}
}
}
}
@@ -213,8 +213,13 @@ namespace OpenSim.Framework.Serialization.External
xtw.WriteElementString("ClaimDate", Convert.ToString(landData.ClaimDate));
xtw.WriteElementString("ClaimPrice", Convert.ToString(landData.ClaimPrice));
xtw.WriteElementString("GlobalID", landData.GlobalID.ToString());
xtw.WriteElementString("GroupID", landData.GroupID.ToString());
xtw.WriteElementString("IsGroupOwned", Convert.ToString(landData.IsGroupOwned));
UUID groupID = options.ContainsKey("wipe-owners") ? UUID.Zero : landData.GroupID;
xtw.WriteElementString("GroupID", groupID.ToString());
bool isGroupOwned = options.ContainsKey("wipe-owners") ? false : landData.IsGroupOwned;
xtw.WriteElementString("IsGroupOwned", Convert.ToString(isGroupOwned));
xtw.WriteElementString("Bitmap", Convert.ToBase64String(landData.Bitmap));
xtw.WriteElementString("Description", landData.Description);
xtw.WriteElementString("Flags", Convert.ToString((uint)landData.Flags));
@@ -227,13 +232,8 @@ namespace OpenSim.Framework.Serialization.External
xtw.WriteElementString("MediaURL", landData.MediaURL);
xtw.WriteElementString("MusicURL", landData.MusicURL);
UUID ownerIdToWrite;
if (options != null && options.ContainsKey("wipe-owners"))
ownerIdToWrite = UUID.Zero;
else
ownerIdToWrite = landData.OwnerID;
xtw.WriteElementString("OwnerID", ownerIdToWrite.ToString());
UUID ownerID = options.ContainsKey("wipe-owners") ? UUID.Zero : landData.OwnerID;
xtw.WriteElementString("OwnerID", ownerID.ToString());
xtw.WriteStartElement("ParcelAccessList");
foreach (LandAccessEntry pal in landData.ParcelAccessList)
@@ -286,7 +286,8 @@ namespace OpenSim.Framework.Serialization.External
UserAccount account = userAccountService.GetUserAccount(UUID.Zero, inventoryItem.CreatorIdAsUuid);
if (account != null)
{
writer.WriteElementString("CreatorData", (string)options["home"] + "/" + inventoryItem.CreatorIdAsUuid + ";" + account.FirstName + " " + account.LastName);
string creatorData = ExternalRepresentationUtils.CalcCreatorData((string)options["home"], inventoryItem.CreatorIdAsUuid, account.FirstName + " " + account.LastName);
writer.WriteElementString("CreatorData", creatorData);
}
writer.WriteElementString("CreatorID", inventoryItem.CreatorId);
}
@@ -121,7 +121,8 @@ namespace OpenSim.Framework.Serialization.Tests
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
LandData ld = LandDataSerializer.Deserialize(LandDataSerializer.Serialize(this.land, null));
Dictionary<string, object> options = new Dictionary<string, object>();
LandData ld = LandDataSerializer.Deserialize(LandDataSerializer.Serialize(this.land, options));
Assert.That(ld, Is.Not.Null, "Deserialize(string) returned null");
// Assert.That(ld.AABBMax, Is.EqualTo(land.AABBMax));
// Assert.That(ld.AABBMin, Is.EqualTo(land.AABBMin));
@@ -46,6 +46,7 @@ using CoolHTTPListener = HttpServer.HttpListener;
using HttpListener=System.Net.HttpListener;
using LogPrio=HttpServer.LogPrio;
using OpenSim.Framework.Monitoring;
using System.IO.Compression;
namespace OpenSim.Framework.Servers.HttpServer
{
@@ -113,7 +114,7 @@ namespace OpenSim.Framework.Servers.HttpServer
protected IPAddress m_listenIPAddress = IPAddress.Any;
private PollServiceRequestManager m_PollServiceManager;
public PollServiceRequestManager PollServiceRequestManager { get; private set; }
public uint SSLPort
{
@@ -374,7 +375,7 @@ namespace OpenSim.Framework.Servers.HttpServer
return true;
}
private void OnRequest(object source, RequestEventArgs args)
public void OnRequest(object source, RequestEventArgs args)
{
RequestNumber++;
@@ -429,7 +430,7 @@ namespace OpenSim.Framework.Servers.HttpServer
psEvArgs.Request(psreq.RequestID, keysvals);
}
m_PollServiceManager.Enqueue(psreq);
PollServiceRequestManager.Enqueue(psreq);
}
else
{
@@ -491,8 +492,8 @@ namespace OpenSim.Framework.Servers.HttpServer
try
{
byte[] buffer500 = SendHTML500(response);
response.Body.Write(buffer500,0,buffer500.Length);
response.Body.Close();
response.OutputStream.Write(buffer500, 0, buffer500.Length);
response.Send();
}
catch
{
@@ -690,6 +691,23 @@ namespace OpenSim.Framework.Servers.HttpServer
if (buffer != null)
{
if (WebUtil.DebugLevel >= 5)
{
string output = System.Text.Encoding.UTF8.GetString(buffer);
if (WebUtil.DebugLevel >= 6)
{
// Always truncate binary blobs. We don't have a ContentType, so detect them using the request name.
if ((requestHandler != null && requestHandler.Name == "GetMesh"))
{
if (output.Length > WebUtil.MaxRequestDiagLength)
output = output.Substring(0, WebUtil.MaxRequestDiagLength) + "...";
}
}
WebUtil.LogResponseDetail(RequestNumber, output);
}
if (!response.SendChunked && response.ContentLength64 <= 0)
response.ContentLength64 = buffer.LongLength;
@@ -720,16 +738,16 @@ namespace OpenSim.Framework.Servers.HttpServer
}
catch (IOException e)
{
m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.StackTrace), e);
m_log.Error("[BASE HTTP SERVER]: HandleRequest() threw exception ", e);
}
catch (Exception e)
{
m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.StackTrace), e);
m_log.Error("[BASE HTTP SERVER]: HandleRequest() threw exception ", e);
try
{
byte[] buffer500 = SendHTML500(response);
response.Body.Write(buffer500, 0, buffer500.Length);
response.Body.Close();
response.OutputStream.Write(buffer500, 0, buffer500.Length);
response.Send();
}
catch
{
@@ -743,7 +761,7 @@ namespace OpenSim.Framework.Servers.HttpServer
if (tickdiff > 3000 && requestHandler != null && requestHandler.Name != "GetTexture")
{
m_log.InfoFormat(
"[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms",
"[LOGHTTP] Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms",
RequestNumber,
requestMethod,
uriString,
@@ -755,7 +773,7 @@ namespace OpenSim.Framework.Servers.HttpServer
else if (DebugLevel >= 4)
{
m_log.DebugFormat(
"[BASE HTTP SERVER]: HTTP IN {0} :{1} took {2}ms",
"[LOGHTTP] HTTP IN {0} :{1} took {2}ms",
RequestNumber,
Port,
tickdiff);
@@ -766,7 +784,7 @@ namespace OpenSim.Framework.Servers.HttpServer
private void LogIncomingToStreamHandler(OSHttpRequest request, IRequestHandler requestHandler)
{
m_log.DebugFormat(
"[BASE HTTP SERVER]: HTTP IN {0} :{1} stream handler {2} {3} {4} {5} from {6}",
"[LOGHTTP] HTTP IN {0} :{1} stream handler {2} {3} {4} {5} from {6}",
RequestNumber,
Port,
request.HttpMethod,
@@ -782,7 +800,7 @@ namespace OpenSim.Framework.Servers.HttpServer
private void LogIncomingToContentTypeHandler(OSHttpRequest request)
{
m_log.DebugFormat(
"[BASE HTTP SERVER]: HTTP IN {0} :{1} {2} content type handler {3} {4} from {5}",
"[LOGHTTP] HTTP IN {0} :{1} {2} content type handler {3} {4} from {5}",
RequestNumber,
Port,
string.IsNullOrEmpty(request.ContentType) ? "not set" : request.ContentType,
@@ -797,7 +815,7 @@ namespace OpenSim.Framework.Servers.HttpServer
private void LogIncomingToXmlRpcHandler(OSHttpRequest request)
{
m_log.DebugFormat(
"[BASE HTTP SERVER]: HTTP IN {0} :{1} assumed generic XMLRPC request {2} {3} from {4}",
"[LOGHTTP] HTTP IN {0} :{1} assumed generic XMLRPC request {2} {3} from {4}",
RequestNumber,
Port,
request.HttpMethod,
@@ -810,29 +828,37 @@ namespace OpenSim.Framework.Servers.HttpServer
private void LogIncomingInDetail(OSHttpRequest request)
{
using (StreamReader reader = new StreamReader(Util.Copy(request.InputStream), Encoding.UTF8))
if (request.ContentType == "application/octet-stream")
return; // never log these; they're just binary data
Stream inputStream = Util.Copy(request.InputStream);
if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip"))
inputStream = new GZipStream(inputStream, System.IO.Compression.CompressionMode.Decompress);
using (StreamReader reader = new StreamReader(inputStream, Encoding.UTF8))
{
string output;
if (DebugLevel == 5)
{
const int sampleLength = 80;
char[] sampleChars = new char[sampleLength + 3];
reader.Read(sampleChars, 0, sampleLength);
sampleChars[80] = '.';
sampleChars[81] = '.';
sampleChars[82] = '.';
output = new string(sampleChars);
char[] chars = new char[WebUtil.MaxRequestDiagLength + 1]; // +1 so we know to add "..." only if needed
int len = reader.Read(chars, 0, WebUtil.MaxRequestDiagLength + 1);
output = new string(chars, 0, Math.Min(len, WebUtil.MaxRequestDiagLength));
if (len > WebUtil.MaxRequestDiagLength)
output += "...";
}
else
{
output = reader.ReadToEnd();
}
m_log.DebugFormat("[BASE HTTP SERVER]: {0}", output.Replace("\n", @"\n"));
m_log.DebugFormat("[LOGHTTP] {0}", Util.BinaryToASCII(output));
}
}
private readonly string HANDLER_SEPARATORS = "/?&#-";
private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler)
{
string bestMatch = null;
@@ -841,7 +867,8 @@ namespace OpenSim.Framework.Servers.HttpServer
{
foreach (string pattern in m_streamHandlers.Keys)
{
if (handlerKey.StartsWith(pattern))
if ((handlerKey == pattern)
|| (handlerKey.StartsWith(pattern) && (HANDLER_SEPARATORS.IndexOf(handlerKey[pattern.Length]) >= 0)))
{
if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length)
{
@@ -871,7 +898,8 @@ namespace OpenSim.Framework.Servers.HttpServer
{
foreach (string pattern in m_pollHandlers.Keys)
{
if (handlerKey.StartsWith(pattern))
if ((handlerKey == pattern)
|| (handlerKey.StartsWith(pattern) && (HANDLER_SEPARATORS.IndexOf(handlerKey[pattern.Length]) >= 0)))
{
if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length)
{
@@ -903,7 +931,8 @@ namespace OpenSim.Framework.Servers.HttpServer
{
foreach (string pattern in m_HTTPHandlers.Keys)
{
if (handlerKey.StartsWith(pattern))
if ((handlerKey == pattern)
|| (handlerKey.StartsWith(pattern) && (HANDLER_SEPARATORS.IndexOf(handlerKey[pattern.Length]) >= 0)))
{
if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length)
{
@@ -954,6 +983,9 @@ namespace OpenSim.Framework.Servers.HttpServer
{
Stream requestStream = request.InputStream;
if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip"))
requestStream = new GZipStream(requestStream, System.IO.Compression.CompressionMode.Decompress);
Encoding encoding = Encoding.UTF8;
StreamReader reader = new StreamReader(requestStream, encoding);
@@ -1781,10 +1813,17 @@ namespace OpenSim.Framework.Servers.HttpServer
public void Start()
{
StartHTTP();
Start(true);
}
private void StartHTTP()
/// <summary>
/// Start the http server
/// </summary>
/// <param name='processPollRequestsAsync'>
/// If true then poll responses are performed asynchronsly.
/// Option exists to allow regression tests to perform processing synchronously.
/// </param>
public void Start(bool performPollResponsesAsync)
{
m_log.InfoFormat(
"[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port);
@@ -1822,8 +1861,9 @@ namespace OpenSim.Framework.Servers.HttpServer
m_httpListener2.Start(64);
// Long Poll Service Manager with 3 worker threads a 25 second timeout for no events
m_PollServiceManager = new PollServiceRequestManager(this, 3, 25000);
m_PollServiceManager.Start();
PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 3, 25000);
PollServiceRequestManager.Start();
HTTPDRunning = true;
//HttpListenerContext context;
@@ -1892,7 +1932,7 @@ namespace OpenSim.Framework.Servers.HttpServer
try
{
m_PollServiceManager.Stop();
PollServiceRequestManager.Stop();
m_httpListener2.ExceptionThrown -= httpServerException;
//m_httpListener2.DisconnectHandler = null;
@@ -26,6 +26,8 @@
*/
using System.IO;
using System.Net;
using OpenSim.Framework.ServiceAuth;
namespace OpenSim.Framework.Servers.HttpServer
{
@@ -37,15 +39,30 @@ namespace OpenSim.Framework.Servers.HttpServer
/// </remarks>
public abstract class BaseStreamHandler : BaseRequestHandler, IStreamedRequestHandler
{
protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
protected IServiceAuth m_Auth;
protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) { }
protected BaseStreamHandler(string httpMethod, string path, string name, string description)
: base(httpMethod, path, name, description) {}
protected BaseStreamHandler(string httpMethod, string path, IServiceAuth auth)
: base(httpMethod, path, null, null)
{
m_Auth = auth;
}
public virtual byte[] Handle(
string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
RequestsReceived++;
if (m_Auth != null && !m_Auth.Authenticate(httpRequest.Headers, httpResponse.AddHeader))
{
httpResponse.StatusCode = (int)HttpStatusCode.Unauthorized;
httpResponse.ContentType = "text/plain";
return new byte[0];
}
byte[] result = ProcessRequest(path, request, httpRequest, httpResponse);
@@ -0,0 +1,190 @@
/*
* 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.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.IO;
using OpenMetaverse.StructuredData;
using OpenMetaverse;
using log4net;
namespace OpenSim.Framework.Servers.HttpServer
{
/// <summary>
/// Json rpc request manager.
/// </summary>
public class JsonRpcRequestManager
{
static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public JsonRpcRequestManager()
{
}
/// <summary>
/// Sends json-rpc request with a serializable type.
/// </summary>
/// <returns>
/// OSD Map.
/// </returns>
/// <param name='parameters'>
/// Serializable type .
/// </param>
/// <param name='method'>
/// Json-rpc method to call.
/// </param>
/// <param name='uri'>
/// URI of json-rpc service.
/// </param>
/// <param name='jsonId'>
/// Id for our call.
/// </param>
public bool JsonRpcRequest(ref object parameters, string method, string uri, string jsonId)
{
if (jsonId == null)
throw new ArgumentNullException("jsonId");
if (uri == null)
throw new ArgumentNullException("uri");
if (method == null)
throw new ArgumentNullException("method");
if (parameters == null)
throw new ArgumentNullException("parameters");
OSDMap request = new OSDMap();
request.Add("jsonrpc", OSD.FromString("2.0"));
request.Add("id", OSD.FromString(jsonId));
request.Add("method", OSD.FromString(method));
request.Add("params", OSD.SerializeMembers(parameters));
OSDMap response;
try
{
response = WebUtil.PostToService(uri, request, 10000, true);
}
catch (Exception e)
{
m_log.Debug(string.Format("JsonRpc request '{0}' to {1} failed", method, uri), e);
return false;
}
if (!response.ContainsKey("_Result"))
{
m_log.DebugFormat("JsonRpc request '{0}' to {1} returned an invalid response: {2}",
method, uri, OSDParser.SerializeJsonString(response));
return false;
}
response = (OSDMap)response["_Result"];
OSD data;
if (response.ContainsKey("error"))
{
data = response["error"];
m_log.DebugFormat("JsonRpc request '{0}' to {1} returned an error: {2}",
method, uri, OSDParser.SerializeJsonString(data));
return false;
}
if (!response.ContainsKey("result"))
{
m_log.DebugFormat("JsonRpc request '{0}' to {1} returned an invalid response: {2}",
method, uri, OSDParser.SerializeJsonString(response));
return false;
}
data = response["result"];
OSD.DeserializeMembers(ref parameters, (OSDMap)data);
return true;
}
/// <summary>
/// Sends json-rpc request with OSD parameter.
/// </summary>
/// <returns>
/// The rpc request.
/// </returns>
/// <param name='data'>
/// data - incoming as parameters, outgoing as result/error
/// </param>
/// <param name='method'>
/// Json-rpc method to call.
/// </param>
/// <param name='uri'>
/// URI of json-rpc service.
/// </param>
/// <param name='jsonId'>
/// If set to <c>true</c> json identifier.
/// </param>
public bool JsonRpcRequest(ref OSD data, string method, string uri, string jsonId)
{
if (string.IsNullOrEmpty(jsonId))
jsonId = UUID.Random().ToString();
OSDMap request = new OSDMap();
request.Add("jsonrpc", OSD.FromString("2.0"));
request.Add("id", OSD.FromString(jsonId));
request.Add("method", OSD.FromString(method));
request.Add("params", data);
OSDMap response;
try
{
response = WebUtil.PostToService(uri, request, 10000, true);
}
catch (Exception e)
{
m_log.Debug(string.Format("JsonRpc request '{0}' to {1} failed", method, uri), e);
return false;
}
if (!response.ContainsKey("_Result"))
{
m_log.DebugFormat("JsonRpc request '{0}' to {1} returned an invalid response: {2}",
method, uri, OSDParser.SerializeJsonString(response));
return false;
}
response = (OSDMap)response["_Result"];
if (response.ContainsKey("error"))
{
data = response["error"];
m_log.DebugFormat("JsonRpc request '{0}' to {1} returned an error: {2}",
method, uri, OSDParser.SerializeJsonString(data));
return false;
}
data = response;
return true;
}
}
}
@@ -182,11 +182,22 @@ namespace OpenSim.Framework.Servers.HttpServer
_context = context;
if (null != req.Headers["content-encoding"])
_contentEncoding = Encoding.GetEncoding(_request.Headers["content-encoding"]);
{
try
{
_contentEncoding = Encoding.GetEncoding(_request.Headers["content-encoding"]);
}
catch (Exception)
{
// 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
@@ -44,6 +44,25 @@ namespace OpenSim.Framework.Servers.HttpServer
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Is the poll service request manager running?
/// </summary>
/// <remarks>
/// Can be running either synchronously or asynchronously
/// </remarks>
public bool IsRunning { get; private set; }
/// <summary>
/// Is the poll service performing responses asynchronously (with its own threads) or synchronously (via
/// external calls)?
/// </summary>
public bool PerformResponsesAsync { get; private set; }
/// <summary>
/// Number of responses actually processed and sent to viewer (or aborted due to error).
/// </summary>
public int ResponsesProcessed { get; private set; }
private readonly BaseHttpServer m_server;
private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>();
@@ -52,48 +71,79 @@ namespace OpenSim.Framework.Servers.HttpServer
private uint m_WorkerThreadCount = 0;
private Thread[] m_workerThreads;
private bool m_running = true;
private SmartThreadPool m_threadPool = new SmartThreadPool(20000, 12, 2);
// private int m_timeout = 1000; // increase timeout 250; now use the event one
public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout)
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));
}
public void Start()
{
//startup worker threads
for (uint i = 0; i < m_WorkerThreadCount; i++)
{
m_workerThreads[i]
= Watchdog.StartThread(
PoolWorkerJob,
string.Format("PollServiceWorkerThread{0}:{1}", i, m_server.Port),
ThreadPriority.Normal,
false,
false,
null,
int.MaxValue);
}
IsRunning = true;
Watchdog.StartThread(
this.CheckLongPollThreads,
string.Format("LongPollServiceWatcherThread:{0}", m_server.Port),
ThreadPriority.Normal,
false,
true,
null,
1000 * 60 * 10);
if (PerformResponsesAsync)
{
//startup worker threads
for (uint i = 0; i < m_WorkerThreadCount; i++)
{
m_workerThreads[i]
= Watchdog.StartThread(
PoolWorkerJob,
string.Format("PollServiceWorkerThread{0}:{1}", i, m_server.Port),
ThreadPriority.Normal,
false,
false,
null,
int.MaxValue);
}
Watchdog.StartThread(
this.CheckLongPollThreads,
string.Format("LongPollServiceWatcherThread:{0}", m_server.Port),
ThreadPriority.Normal,
false,
true,
null,
1000 * 60 * 10);
}
}
private void ReQueueEvent(PollServiceHttpRequest req)
{
if (m_running)
if (IsRunning)
{
// delay the enqueueing for 100ms. There's no need to have the event
// actively on the queue
@@ -109,7 +159,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public void Enqueue(PollServiceHttpRequest req)
{
if (m_running)
if (IsRunning)
{
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll)
{
@@ -129,7 +179,7 @@ namespace OpenSim.Framework.Servers.HttpServer
// 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 (m_running)
while (IsRunning)
{
Thread.Sleep(500);
Watchdog.UpdateThread();
@@ -137,7 +187,7 @@ namespace OpenSim.Framework.Servers.HttpServer
// List<PollServiceHttpRequest> not_ready = new List<PollServiceHttpRequest>();
lock (m_longPollRequests)
{
if (m_longPollRequests.Count > 0 && m_running)
if (m_longPollRequests.Count > 0 && IsRunning)
{
List<PollServiceHttpRequest> ready = m_longPollRequests.FindAll(req =>
(req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id) || // there are events in this EQ
@@ -158,7 +208,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public void Stop()
{
m_running = false;
IsRunning = false;
// m_timeout = -10000; // cause all to expire
Thread.Sleep(1000); // let the world move
@@ -169,7 +219,7 @@ namespace OpenSim.Framework.Servers.HttpServer
lock (m_longPollRequests)
{
if (m_longPollRequests.Count > 0 && m_running)
if (m_longPollRequests.Count > 0 && IsRunning)
m_longPollRequests.ForEach(req => m_requests.Enqueue(req));
}
@@ -178,6 +228,7 @@ namespace OpenSim.Framework.Servers.HttpServer
try
{
wreq = m_requests.Dequeue(0);
ResponsesProcessed++;
wreq.DoHTTPGruntWork(
m_server, wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id));
}
@@ -194,69 +245,86 @@ namespace OpenSim.Framework.Servers.HttpServer
private void PoolWorkerJob()
{
while (m_running)
while (IsRunning)
{
PollServiceHttpRequest req = m_requests.Dequeue(5000);
//m_log.WarnFormat("[YYY]: Dequeued {0}", (req == null ? "null" : req.PollServiceArgs.Type.ToString()));
Watchdog.UpdateThread();
if (req != null)
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
{
try
if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
{
if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
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)
{
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
if (responsedata == null)
continue;
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) // This is the event queue
try
{
try
{
req.DoHTTPGruntWork(m_server, responsedata);
}
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
{
// Ignore it, no need to reply
}
ResponsesProcessed++;
req.DoHTTPGruntWork(m_server, responsedata);
}
else
catch (ObjectDisposedException e) // Browser aborted before we could read body, server closed the stream
{
m_threadPool.QueueWorkItem(x =>
{
try
{
req.DoHTTPGruntWork(m_server, responsedata);
}
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
{
// Ignore it, no need to reply
}
return null;
}, null);
// Ignore it, no need to reply
m_log.Error(e);
}
}
else
{
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
m_threadPool.QueueWorkItem(x =>
{
req.DoHTTPGruntWork(
m_server, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
}
else
{
ReQueueEvent(req);
}
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);
}
catch (Exception e)
{
m_log.Error(e);
}
return null;
}, null);
}
}
catch (Exception e)
else
{
m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
{
ResponsesProcessed++;
req.DoHTTPGruntWork(
m_server, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
}
else
{
ReQueueEvent(req);
}
}
}
catch (Exception e)
{
m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());
}
}
}
}
+38
View File
@@ -279,6 +279,17 @@ 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,
"Turn on logging of activity in the main thread pool.",
"Log levels:\n"
+ " 0 = no logging\n"
+ " 1 = only first line of stack trace; don't log common threads\n"
+ " 2 = full stack trace; don't log common threads\n"
+ " 3 = full stack trace, including common threads\n",
HandleDebugThreadpoolLevel);
m_console.Commands.AddCommand(
"Debug", false, "force gc",
@@ -432,6 +443,33 @@ namespace OpenSim.Framework.Servers
}
}
private static void HandleDebugThreadpoolLevel(string module, string[] cmdparams)
{
if (cmdparams.Length < 4)
{
MainConsole.Instance.Output("Usage: debug threadpool level 0.." + Util.MAX_THREADPOOL_LEVEL);
return;
}
string rawLevel = cmdparams[3];
int newLevel;
if (!int.TryParse(rawLevel, out newLevel))
{
MainConsole.Instance.OutputFormat("{0} is not a valid debug level", rawLevel);
return;
}
if (newLevel < 0 || newLevel > Util.MAX_THREADPOOL_LEVEL)
{
MainConsole.Instance.OutputFormat("{0} is outside the valid debug level range of 0.." + Util.MAX_THREADPOOL_LEVEL, newLevel);
return;
}
Util.LogThreadPool = newLevel;
MainConsole.Instance.OutputFormat("LogThreadPool set to {0}", newLevel);
}
private void HandleForceGc(string module, string[] args)
{
Notice("Manually invoking runtime garbage collection");
+2 -318
View File
@@ -41,323 +41,7 @@ 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<DisconnectedEventArgs> Disconnected = delegate { };
/// <summary>
/// A request have been received in the context.
/// </summary>
public event EventHandler<RequestEventArgs> RequestReceived = delegate { };
}
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);
}
/// <summary>
/// Path and query (will be merged with the host header) and put in Uri
/// </summary>
/// <see cref="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;
@@ -429,4 +113,4 @@ namespace OpenSim.Framework.Servers.Tests
Assert.That(rsp0.ContentType, Is.EqualTo("text/xml"));
}
}
}
}
@@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using Nini.Config;
using log4net;
namespace OpenSim.Framework.ServiceAuth
{
public class BasicHttpAuthentication : IServiceAuth
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string m_Username, m_Password;
private string m_CredentialsB64;
private string remove_me;
public string Credentials
{
get { return m_CredentialsB64; }
}
public BasicHttpAuthentication(IConfigSource config, string section)
{
remove_me = section;
m_Username = Util.GetConfigVarFromSections<string>(config, "HttpAuthUsername", new string[] { "Network", section }, string.Empty);
m_Password = Util.GetConfigVarFromSections<string>(config, "HttpAuthPassword", new string[] { "Network", section }, string.Empty);
string str = m_Username + ":" + m_Password;
byte[] encData_byte = Util.UTF8.GetBytes(str);
m_CredentialsB64 = Convert.ToBase64String(encData_byte);
m_log.DebugFormat("[HTTP BASIC AUTH]: {0} {1} [{2}]", m_Username, m_Password, section);
}
public void AddAuthorization(NameValueCollection headers)
{
//m_log.DebugFormat("[HTTP BASIC AUTH]: Adding authorization for {0}", remove_me);
headers["Authorization"] = "Basic " + m_CredentialsB64;
}
public bool Authenticate(string data)
{
string recovered = Util.Base64ToString(data);
if (!String.IsNullOrEmpty(recovered))
{
string[] parts = recovered.Split(new char[] { ':' });
if (parts.Length >= 2)
{
return m_Username.Equals(parts[0]) && m_Password.Equals(parts[1]);
}
}
return false;
}
public bool Authenticate(NameValueCollection requestHeaders, AddHeaderDelegate d)
{
//m_log.DebugFormat("[HTTP BASIC AUTH]: Authenticate in {0}", remove_me);
if (requestHeaders != null)
{
string value = requestHeaders.Get("Authorization");
if (value != null)
{
value = value.Trim();
if (value.StartsWith("Basic "))
{
value = value.Replace("Basic ", string.Empty);
if (Authenticate(value))
return true;
}
}
}
d("WWW-Authenticate", "Basic realm = \"Asset Server\"");
return false;
}
}
}
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
namespace OpenSim.Framework.ServiceAuth
{
public delegate void AddHeaderDelegate(string key, string value);
public interface IServiceAuth
{
bool Authenticate(string data);
bool Authenticate(NameValueCollection headers, AddHeaderDelegate d);
void AddAuthorization(NameValueCollection headers);
}
}
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using Nini.Config;
namespace OpenSim.Framework.ServiceAuth
{
public class ServiceAuth
{
public static IServiceAuth Create(IConfigSource config, string section)
{
string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", section }, "None");
switch (authType)
{
case "BasicHttpAuthentication":
return new BasicHttpAuthentication(config, section);
}
return null;
}
}
}
+63 -22
View File
@@ -50,8 +50,9 @@ namespace OpenSim.Framework
// Someday terrain will have caves
public abstract float this[int x, int y, int z] { get; set; }
public bool IsTainted { get; protected set; }
public abstract bool IsTaintedAt(int xx, int yy);
public abstract bool IsTaintedAt(int xx, int yy, bool clearOnTest);
public abstract void TaintAllTerrain();
public abstract void ClearTaint();
public abstract void ClearLand();
@@ -71,10 +72,11 @@ namespace OpenSim.Framework
return new HeightmapTerrainData(pSizeX, pSizeY, pSizeZ, pFormatCode, pBlob);
}
// return a special compressed representation of the heightmap in shorts
public abstract short[] GetCompressedMap();
// return a special compressed representation of the heightmap in ints
public abstract int[] GetCompressedMap();
public abstract float CompressionFactor { get; }
public abstract float[] GetFloatsSerialized();
public abstract double[,] GetDoubles();
public abstract TerrainData Clone();
}
@@ -97,7 +99,7 @@ namespace OpenSim.Framework
Variable2D = 22,
// 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
// "short compressedHeight = (short)(height * compressionFactor);"
// "int compressedHeight = (int)(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'.
@@ -107,8 +109,8 @@ 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 short integers. The integer values are converted to
// and from floats by TerrainCompressionFactor. Shorts are used to limit storage used.
// The heighmap is kept as an array of integers. The integer values are converted to
// and from floats by TerrainCompressionFactor.
public class HeightmapTerrainData : TerrainData
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -119,7 +121,7 @@ namespace OpenSim.Framework
{
get { return FromCompressedHeight(m_heightmap[x, y]); }
set {
short newVal = ToCompressedHeight(value);
int newVal = ToCompressedHeight(value);
if (m_heightmap[x, y] != newVal)
{
m_heightmap[x, y] = newVal;
@@ -138,10 +140,20 @@ namespace OpenSim.Framework
// TerrainData.ClearTaint
public override void ClearTaint()
{
IsTainted = false;
SetAllTaint(false);
}
// TerrainData.TaintAllTerrain
public override void TaintAllTerrain()
{
SetAllTaint(true);
}
private void SetAllTaint(bool setting)
{
for (int ii = 0; ii < m_taint.GetLength(0); ii++)
for (int jj = 0; jj < m_taint.GetLength(1); jj++)
m_taint[ii, jj] = false;
m_taint[ii, jj] = setting;
}
// TerrainData.ClearLand
@@ -152,21 +164,31 @@ namespace OpenSim.Framework
// TerrainData.ClearLand(float)
public override void ClearLand(float pHeight)
{
short flatHeight = ToCompressedHeight(pHeight);
int flatHeight = ToCompressedHeight(pHeight);
for (int xx = 0; xx < SizeX; xx++)
for (int yy = 0; yy < SizeY; yy++)
m_heightmap[xx, yy] = flatHeight;
}
public override bool IsTaintedAt(int xx, int yy)
// Return 'true' of the patch that contains these region coordinates has been modified.
// Note that checking the taint clears it.
// There is existing code that relies on this feature.
public override bool IsTaintedAt(int xx, int yy, bool clearOnTest)
{
int tx = xx / Constants.TerrainPatchSize;
int ty = yy / Constants.TerrainPatchSize;
bool ret = m_taint[tx, ty];
m_taint[tx, ty] = false;
if (ret && clearOnTest)
m_taint[tx, ty] = false;
return ret;
}
// Old form that clears the taint flag when we check it.
public override bool IsTaintedAt(int xx, int yy)
{
return IsTaintedAt(xx, yy, true /* clearOnTest */);
}
// TerrainData.GetDatabaseBlob
// The user wants something to store in the database.
public override bool GetDatabaseBlob(out int DBRevisionCode, out Array blob)
@@ -192,9 +214,9 @@ namespace OpenSim.Framework
public override float CompressionFactor { get { return m_compressionFactor; } }
// TerrainData.GetCompressedMap
public override short[] GetCompressedMap()
public override int[] GetCompressedMap()
{
short[] newMap = new short[SizeX * SizeY];
int[] newMap = new int[SizeX * SizeY];
int ind = 0;
for (int xx = 0; xx < SizeX; xx++)
@@ -208,10 +230,29 @@ namespace OpenSim.Framework
public override TerrainData Clone()
{
HeightmapTerrainData ret = new HeightmapTerrainData(SizeX, SizeY, SizeZ);
ret.m_heightmap = (short[,])this.m_heightmap.Clone();
ret.m_heightmap = (int[,])this.m_heightmap.Clone();
return ret;
}
// TerrainData.GetFloatsSerialized
// This one dimensional version is ordered so height = map[y*sizeX+x];
// DEPRECATED: don't use this function as it does not retain the dimensions of the terrain
// and the caller will probably do the wrong thing if the terrain is not the legacy 256x256.
public override float[] GetFloatsSerialized()
{
int points = SizeX * SizeY;
float[] heights = new float[points];
int idx = 0;
for (int jj = 0; jj < SizeY; jj++)
for (int ii = 0; ii < SizeX; ii++)
{
heights[idx++] = FromCompressedHeight(m_heightmap[ii, jj]);
}
return heights;
}
// TerrainData.GetDoubles
public override double[,] GetDoubles()
{
@@ -226,19 +267,19 @@ namespace OpenSim.Framework
// =============================================================
private short[,] m_heightmap;
private int[,] 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 short ToCompressedHeight(double pHeight)
public int ToCompressedHeight(double pHeight)
{
return (short)(pHeight * CompressionFactor);
return (int)(pHeight * CompressionFactor);
}
public float FromCompressedHeight(short pHeight)
public float FromCompressedHeight(int pHeight)
{
return ((float)pHeight) / CompressionFactor;
}
@@ -252,7 +293,7 @@ namespace OpenSim.Framework
SizeZ = (int)Constants.RegionHeight;
m_compressionFactor = 100.0f;
m_heightmap = new short[SizeX, SizeY];
m_heightmap = new int[SizeX, SizeY];
for (int ii = 0; ii < SizeX; ii++)
{
for (int jj = 0; jj < SizeY; jj++)
@@ -274,14 +315,14 @@ namespace OpenSim.Framework
SizeY = pY;
SizeZ = pZ;
m_compressionFactor = 100.0f;
m_heightmap = new short[SizeX, SizeY];
m_heightmap = new int[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(short[] cmap, float pCompressionFactor, int pX, int pY, int pZ) : this(pX, pY, pZ)
public HeightmapTerrainData(int[] cmap, float pCompressionFactor, int pX, int pY, int pZ) : this(pX, pY, pZ)
{
m_compressionFactor = pCompressionFactor;
int ind = 0;
+1 -1
View File
@@ -299,7 +299,7 @@ namespace OpenSim.Framework.Tests
uint z1 = 22;
ulong regionHandle2;
uint x2, y2, z2;
UUID fakeParcelID1, fakeParcelID2, uuid;
UUID fakeParcelID1, uuid;
ulong bigInt64 = Util.BytesToUInt64Big(hexBytes8);
Assert.AreEqual(var64Bit, bigInt64,
-230
View File
@@ -1,230 +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.IO;
using System.Net;
using System.Net.Security;
using System.Text;
using log4net;
namespace OpenSim.Framework
{
/// <summary>
/// Used for requests to untrusted endpoints that may potentially be
/// malicious
/// </summary>
public static class UntrustedHttpWebRequest
{
/// <summary>Setting this to true will allow HTTP connections to localhost</summary>
private const bool DEBUG = true;
private static readonly ILog m_log =
LogManager.GetLogger(
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static readonly ICollection<string> allowableSchemes = new List<string> { "http", "https" };
/// <summary>
/// Creates an HttpWebRequest that is hardened against malicious
/// endpoints after ensuring the given Uri is safe to retrieve
/// </summary>
/// <param name="uri">Web location to request</param>
/// <returns>A hardened HttpWebRequest if the uri was determined to be safe</returns>
/// <exception cref="ArgumentNullException">If uri is null</exception>
/// <exception cref="ArgumentException">If uri is unsafe</exception>
public static HttpWebRequest Create(Uri uri)
{
return Create(uri, DEBUG, 1000 * 5, 1000 * 20, 10);
}
/// <summary>
/// Creates an HttpWebRequest that is hardened against malicious
/// endpoints after ensuring the given Uri is safe to retrieve
/// </summary>
/// <param name="uri">Web location to request</param>
/// <param name="allowLoopback">True to allow connections to localhost, otherwise false</param>
/// <param name="readWriteTimeoutMS">Read write timeout, in milliseconds</param>
/// <param name="timeoutMS">Connection timeout, in milliseconds</param>
/// <param name="maximumRedirects">Maximum number of allowed redirects</param>
/// <returns>A hardened HttpWebRequest if the uri was determined to be safe</returns>
/// <exception cref="ArgumentNullException">If uri is null</exception>
/// <exception cref="ArgumentException">If uri is unsafe</exception>
public static HttpWebRequest Create(Uri uri, bool allowLoopback, int readWriteTimeoutMS, int timeoutMS, int maximumRedirects)
{
if (uri == null)
throw new ArgumentNullException("uri");
if (!IsUriAllowable(uri, allowLoopback))
throw new ArgumentException("Uri " + uri + " was rejected");
HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(uri);
httpWebRequest.MaximumAutomaticRedirections = maximumRedirects;
httpWebRequest.ReadWriteTimeout = readWriteTimeoutMS;
httpWebRequest.Timeout = timeoutMS;
httpWebRequest.KeepAlive = false;
return httpWebRequest;
}
public static string PostToUntrustedUrl(Uri url, string data)
{
try
{
byte[] requestData = System.Text.Encoding.UTF8.GetBytes(data);
HttpWebRequest request = Create(url);
request.Method = "POST";
request.ContentLength = requestData.Length;
request.ContentType = "application/x-www-form-urlencoded";
using (Stream requestStream = request.GetRequestStream())
requestStream.Write(requestData, 0, requestData.Length);
using (WebResponse response = request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
return responseStream.GetStreamString();
}
}
catch (Exception ex)
{
m_log.Warn("POST to untrusted URL " + url + " failed: " + ex.Message);
return null;
}
}
public static string GetUntrustedUrl(Uri url)
{
try
{
HttpWebRequest request = Create(url);
using (WebResponse response = request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
return responseStream.GetStreamString();
}
}
catch (Exception ex)
{
m_log.Warn("GET from untrusted URL " + url + " failed: " + ex.Message);
return null;
}
}
/// <summary>
/// Determines whether a URI is allowed based on scheme and host name.
/// No requireSSL check is done here
/// </summary>
/// <param name="allowLoopback">True to allow loopback addresses to be used</param>
/// <param name="uri">The URI to test for whether it should be allowed.</param>
/// <returns>
/// <c>true</c> if [is URI allowable] [the specified URI]; otherwise, <c>false</c>.
/// </returns>
private static bool IsUriAllowable(Uri uri, bool allowLoopback)
{
if (!allowableSchemes.Contains(uri.Scheme))
{
m_log.WarnFormat("Rejecting URL {0} because it uses a disallowed scheme.", uri);
return false;
}
// Try to interpret the hostname as an IP address so we can test for internal
// IP address ranges. Note that IP addresses can appear in many forms
// (e.g. http://127.0.0.1, http://2130706433, http://0x0100007f, http://::1
// So we convert them to a canonical IPAddress instance, and test for all
// non-routable IP ranges: 10.*.*.*, 127.*.*.*, ::1
// Note that Uri.IsLoopback is very unreliable, not catching many of these variants.
IPAddress hostIPAddress;
if (IPAddress.TryParse(uri.DnsSafeHost, out hostIPAddress))
{
byte[] addressBytes = hostIPAddress.GetAddressBytes();
// The host is actually an IP address.
switch (hostIPAddress.AddressFamily)
{
case System.Net.Sockets.AddressFamily.InterNetwork:
if (!allowLoopback && (addressBytes[0] == 127 || addressBytes[0] == 10))
{
m_log.WarnFormat("Rejecting URL {0} because it is a loopback address.", uri);
return false;
}
break;
case System.Net.Sockets.AddressFamily.InterNetworkV6:
if (!allowLoopback && IsIPv6Loopback(hostIPAddress))
{
m_log.WarnFormat("Rejecting URL {0} because it is a loopback address.", uri);
return false;
}
break;
default:
m_log.WarnFormat("Rejecting URL {0} because it does not use an IPv4 or IPv6 address.", uri);
return false;
}
}
else
{
// The host is given by name. We require names to contain periods to
// help make sure it's not an internal address.
if (!allowLoopback && !uri.Host.Contains("."))
{
m_log.WarnFormat("Rejecting URL {0} because it does not contain a period in the host name.", uri);
return false;
}
}
return true;
}
/// <summary>
/// Determines whether an IP address is the IPv6 equivalent of "localhost/127.0.0.1".
/// </summary>
/// <param name="ip">The ip address to check.</param>
/// <returns>
/// <c>true</c> if this is a loopback IP address; <c>false</c> otherwise.
/// </returns>
private static bool IsIPv6Loopback(IPAddress ip)
{
if (ip == null)
throw new ArgumentNullException("ip");
byte[] addressBytes = ip.GetAddressBytes();
for (int i = 0; i < addressBytes.Length - 1; i++)
{
if (addressBytes[i] != 0)
return false;
}
if (addressBytes[addressBytes.Length - 1] != 1)
return false;
return true;
}
}
}
+710 -118
View File
@@ -51,6 +51,9 @@ using Nwc.XmlRpc;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using Amib.Threading;
using System.Collections.Concurrent;
using System.Collections.Specialized;
using System.Web;
namespace OpenSim.Framework
{
@@ -67,7 +70,7 @@ namespace OpenSim.Framework
// All does not contain Export, which is special and must be
// explicitly given
All = (1 << 13) | (1 << 14) | (1 << 15) | (1 << 19)
}
}
/// <summary>
/// The method used by Util.FireAndForget for asynchronously firing events
@@ -116,6 +119,24 @@ namespace OpenSim.Framework
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Log-level for the thread pool:
/// 0 = no logging
/// 1 = only first line of stack trace; don't log common threads
/// 2 = full stack trace; don't log common threads
/// 3 = full stack trace, including common threads
/// </summary>
public static int LogThreadPool { get; set; }
public static bool LogOverloads { get; set; }
public static readonly int MAX_THREADPOOL_LEVEL = 3;
static Util()
{
LogThreadPool = 0;
LogOverloads = true;
}
private static uint nextXferID = 5000;
private static Random randomClass = new Random();
@@ -129,6 +150,9 @@ namespace OpenSim.Framework
/// </summary>
private static SmartThreadPool m_ThreadPool;
// Watchdog timer that aborts threads that have timed-out
private static Timer m_threadPoolWatchdog;
// Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC.
public static readonly DateTime UnixEpoch =
DateTime.ParseExact("1970-01-01 00:00:00 +0", "yyyy-MM-dd hh:mm:ss z", DateTimeFormatInfo.InvariantInfo).ToUniversalTime();
@@ -845,6 +869,54 @@ namespace OpenSim.Framework
return null;
}
/// <summary>
/// Parses a foreign asset ID.
/// </summary>
/// <param name="id">A possibly-foreign asset ID: http://grid.example.com:8002/00000000-0000-0000-0000-000000000000 </param>
/// <param name="url">The URL: http://grid.example.com:8002</param>
/// <param name="assetID">The asset ID: 00000000-0000-0000-0000-000000000000. Returned even if 'id' isn't foreign.</param>
/// <returns>True: this is a foreign asset ID; False: it isn't</returns>
public static bool ParseForeignAssetID(string id, out string url, out string assetID)
{
url = String.Empty;
assetID = String.Empty;
UUID uuid;
if (UUID.TryParse(id, out uuid))
{
assetID = uuid.ToString();
return false;
}
if ((id.Length == 0) || (id[0] != 'h' && id[0] != 'H'))
return false;
Uri assetUri;
if (!Uri.TryCreate(id, UriKind.Absolute, out assetUri) || assetUri.Scheme != Uri.UriSchemeHttp)
return false;
// Simian
if (assetUri.Query != string.Empty)
{
NameValueCollection qscoll = HttpUtility.ParseQueryString(assetUri.Query);
assetID = qscoll["id"];
if (assetID != null)
url = id.Replace(assetID, ""); // Malformed again, as simian expects
else
url = id; // !!! best effort
}
else // robust
{
url = "http://" + assetUri.Authority;
assetID = assetUri.LocalPath.Trim(new char[] { '/' });
}
if (!UUID.TryParse(assetID, out uuid))
return false;
return true;
}
/// <summary>
/// Removes all invalid path chars (OS dependent)
/// </summary>
@@ -946,11 +1018,12 @@ namespace OpenSim.Framework
}
#region Nini (config) related Methods
public static IConfigSource ConvertDataRowToXMLConfig(DataRow row, string fileName)
{
if (!File.Exists(fileName))
{
//create new file
// create new file
}
XmlConfigSource config = new XmlConfigSource(fileName);
AddDataRowToConfig(config, row);
@@ -968,25 +1041,6 @@ 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;
}
/// <summary>
/// Gets the value of a configuration variable by looking into
/// multiple sections in order. The latter sections overwrite
@@ -1039,6 +1093,91 @@ namespace OpenSim.Framework
return (T)val;
}
public static void MergeEnvironmentToConfig(IConfigSource ConfigSource)
{
IConfig enVars = ConfigSource.Configs["Environment"];
// if section does not exist then user isn't expecting them, so don't bother.
if( enVars != null )
{
// load the values from the environment
EnvConfigSource envConfigSource = new EnvConfigSource();
// add the requested keys
string[] env_keys = enVars.GetKeys();
foreach ( string key in env_keys )
{
envConfigSource.AddEnv(key, string.Empty);
}
// load the values from environment
envConfigSource.LoadEnv();
// add them in to the master
ConfigSource.Merge(envConfigSource);
ConfigSource.ExpandKeyValues();
}
}
public static T ReadSettingsFromIniFile<T>(IConfig config, T settingsClass)
{
Type settingsType = settingsClass.GetType();
FieldInfo[] fieldInfos = settingsType.GetFields();
foreach (FieldInfo fieldInfo in fieldInfos)
{
if (!fieldInfo.IsStatic)
{
if (fieldInfo.FieldType == typeof(System.String))
{
fieldInfo.SetValue(settingsClass, config.Get(fieldInfo.Name, (string)fieldInfo.GetValue(settingsClass)));
}
else if (fieldInfo.FieldType == typeof(System.Boolean))
{
fieldInfo.SetValue(settingsClass, config.GetBoolean(fieldInfo.Name, (bool)fieldInfo.GetValue(settingsClass)));
}
else if (fieldInfo.FieldType == typeof(System.Int32))
{
fieldInfo.SetValue(settingsClass, config.GetInt(fieldInfo.Name, (int)fieldInfo.GetValue(settingsClass)));
}
else if (fieldInfo.FieldType == typeof(System.Single))
{
fieldInfo.SetValue(settingsClass, config.GetFloat(fieldInfo.Name, (float)fieldInfo.GetValue(settingsClass)));
}
else if (fieldInfo.FieldType == typeof(System.UInt32))
{
fieldInfo.SetValue(settingsClass, Convert.ToUInt32(config.Get(fieldInfo.Name, ((uint)fieldInfo.GetValue(settingsClass)).ToString())));
}
}
}
PropertyInfo[] propertyInfos = settingsType.GetProperties();
foreach (PropertyInfo propInfo in propertyInfos)
{
if ((propInfo.CanRead) && (propInfo.CanWrite))
{
if (propInfo.PropertyType == typeof(System.String))
{
propInfo.SetValue(settingsClass, config.Get(propInfo.Name, (string)propInfo.GetValue(settingsClass, null)), null);
}
else if (propInfo.PropertyType == typeof(System.Boolean))
{
propInfo.SetValue(settingsClass, config.GetBoolean(propInfo.Name, (bool)propInfo.GetValue(settingsClass, null)), null);
}
else if (propInfo.PropertyType == typeof(System.Int32))
{
propInfo.SetValue(settingsClass, config.GetInt(propInfo.Name, (int)propInfo.GetValue(settingsClass, null)), null);
}
else if (propInfo.PropertyType == typeof(System.Single))
{
propInfo.SetValue(settingsClass, config.GetFloat(propInfo.Name, (float)propInfo.GetValue(settingsClass, null)), null);
}
if (propInfo.PropertyType == typeof(System.UInt32))
{
propInfo.SetValue(settingsClass, Convert.ToUInt32(config.Get(propInfo.Name, ((uint)propInfo.GetValue(settingsClass, null)).ToString())), null);
}
}
}
return settingsClass;
}
#endregion
public static float Clip(float x, float min, float max)
@@ -1411,69 +1550,6 @@ namespace OpenSim.Framework
return displayConnectionString;
}
public static T ReadSettingsFromIniFile<T>(IConfig config, T settingsClass)
{
Type settingsType = settingsClass.GetType();
FieldInfo[] fieldInfos = settingsType.GetFields();
foreach (FieldInfo fieldInfo in fieldInfos)
{
if (!fieldInfo.IsStatic)
{
if (fieldInfo.FieldType == typeof(System.String))
{
fieldInfo.SetValue(settingsClass, config.Get(fieldInfo.Name, (string)fieldInfo.GetValue(settingsClass)));
}
else if (fieldInfo.FieldType == typeof(System.Boolean))
{
fieldInfo.SetValue(settingsClass, config.GetBoolean(fieldInfo.Name, (bool)fieldInfo.GetValue(settingsClass)));
}
else if (fieldInfo.FieldType == typeof(System.Int32))
{
fieldInfo.SetValue(settingsClass, config.GetInt(fieldInfo.Name, (int)fieldInfo.GetValue(settingsClass)));
}
else if (fieldInfo.FieldType == typeof(System.Single))
{
fieldInfo.SetValue(settingsClass, config.GetFloat(fieldInfo.Name, (float)fieldInfo.GetValue(settingsClass)));
}
else if (fieldInfo.FieldType == typeof(System.UInt32))
{
fieldInfo.SetValue(settingsClass, Convert.ToUInt32(config.Get(fieldInfo.Name, ((uint)fieldInfo.GetValue(settingsClass)).ToString())));
}
}
}
PropertyInfo[] propertyInfos = settingsType.GetProperties();
foreach (PropertyInfo propInfo in propertyInfos)
{
if ((propInfo.CanRead) && (propInfo.CanWrite))
{
if (propInfo.PropertyType == typeof(System.String))
{
propInfo.SetValue(settingsClass, config.Get(propInfo.Name, (string)propInfo.GetValue(settingsClass, null)), null);
}
else if (propInfo.PropertyType == typeof(System.Boolean))
{
propInfo.SetValue(settingsClass, config.GetBoolean(propInfo.Name, (bool)propInfo.GetValue(settingsClass, null)), null);
}
else if (propInfo.PropertyType == typeof(System.Int32))
{
propInfo.SetValue(settingsClass, config.GetInt(propInfo.Name, (int)propInfo.GetValue(settingsClass, null)), null);
}
else if (propInfo.PropertyType == typeof(System.Single))
{
propInfo.SetValue(settingsClass, config.GetFloat(propInfo.Name, (float)propInfo.GetValue(settingsClass, null)), null);
}
if (propInfo.PropertyType == typeof(System.UInt32))
{
propInfo.SetValue(settingsClass, Convert.ToUInt32(config.Get(propInfo.Name, ((uint)propInfo.GetValue(settingsClass, null)).ToString())), null);
}
}
}
return settingsClass;
}
public static string Base64ToString(string str)
{
Decoder utf8Decode = Encoding.UTF8.GetDecoder();
@@ -1486,6 +1562,46 @@ namespace OpenSim.Framework
return result;
}
public static void BinaryToASCII(char[] chars)
{
for (int i = 0; i < chars.Length; i++)
{
char ch = chars[i];
if (ch < 32 || ch > 127)
chars[i] = '.';
}
}
public static string BinaryToASCII(string src)
{
char[] chars = src.ToCharArray();
BinaryToASCII(chars);
return new String(chars);
}
/// <summary>
/// Reads a known number of bytes from a stream.
/// Throws EndOfStreamException if the stream doesn't contain enough data.
/// </summary>
/// <param name="stream">The stream to read data from</param>
/// <param name="data">The array to write bytes into. The array
/// will be completely filled from the stream, so an appropriate
/// size must be given.</param>
public static void ReadStream(Stream stream, byte[] data)
{
int offset = 0;
int remaining = data.Length;
while (remaining > 0)
{
int read = stream.Read(data, offset, remaining);
if (read <= 0)
throw new EndOfStreamException(String.Format("End of stream reached with {0} bytes left to read", remaining));
remaining -= read;
offset += read;
}
}
public static Guid GetHashGuid(string data, string salt)
{
byte[] hash = ComputeMD5Hash(data + salt);
@@ -1745,6 +1861,30 @@ namespace OpenSim.Framework
return data;
}
/// <summary>
/// Pretty format the hashtable contents to a single line.
/// </summary>
/// <remarks>
/// Used for debugging output.
/// </remarks>
/// <param name='ht'></param>
public static string PrettyFormatToSingleLine(Hashtable ht)
{
StringBuilder sb = new StringBuilder();
int i = 0;
foreach (string key in ht.Keys)
{
sb.AppendFormat("{0}:{1}", key, ht[key]);
if (++i < ht.Count)
sb.AppendFormat(", ");
}
return sb.ToString();
}
/// <summary>
/// Used to trigger an early library load on Windows systems.
/// </summary>
@@ -1817,7 +1957,7 @@ namespace OpenSim.Framework
public static void FireAndForget(System.Threading.WaitCallback callback)
{
FireAndForget(callback, null);
FireAndForget(callback, null, null);
}
public static void InitThreadPool(int minThreads, int maxThreads)
@@ -1836,6 +1976,7 @@ namespace OpenSim.Framework
startInfo.MinWorkerThreads = minThreads;
m_ThreadPool = new SmartThreadPool(startInfo);
m_threadPoolWatchdog = new Timer(ThreadPoolWatchdog, null, 0, 1000);
}
public static int FireAndForgetCount()
@@ -1859,10 +2000,129 @@ namespace OpenSim.Framework
}
}
/// <summary>
/// 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.
/// </summary>
private class ThreadInfo
{
public long ThreadFuncNum { get; set; }
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 ThreadInfo(long threadFuncNum, string context)
{
ThreadFuncNum = threadFuncNum;
this.context = context;
LogThread = true;
Thread = null;
Running = false;
Aborted = false;
}
public void Started()
{
Thread = Thread.CurrentThread;
started = EnvironmentTickCount();
Running = true;
}
public void Ended()
{
Running = false;
}
public int Elapsed()
{
return EnvironmentTickCountSubtract(started);
}
public void Abort()
{
Aborted = true;
WorkItem.Cancel(true);
}
/// <summary>
/// Returns the thread's stack trace.
/// </summary>
/// <remarks>
/// May return one of two stack traces. First, tries to get the thread's active stack
/// trace. But this can fail, so as a fallback this method will return the stack
/// trace that was active when the task was queued.
/// </remarks>
public string GetStackTrace()
{
string ret = (context == null) ? "" : ("(" + context + ") ");
StackTrace activeStackTrace = Util.GetStackTrace(Thread);
if (activeStackTrace != null)
ret += activeStackTrace.ToString();
else if (StackTrace != null)
ret += "(Stack trace when queued) " + StackTrace;
// else, no stack trace available
return ret;
}
}
private static long nextThreadFuncNum = 0;
private static long numQueuedThreadFuncs = 0;
private static long numRunningThreadFuncs = 0;
private static Int32 threadFuncOverloadMode = 0;
// Maps (ThreadFunc number -> Thread)
private static ConcurrentDictionary<long, ThreadInfo> activeThreads = new ConcurrentDictionary<long, ThreadInfo>();
private static readonly int THREAD_TIMEOUT = 10 * 60 * 1000; // 10 minutes
/// <summary>
/// Finds threads in the main thread pool that have timed-out, and aborts them.
/// </summary>
private static void ThreadPoolWatchdog(object state)
{
foreach (KeyValuePair<long, ThreadInfo> entry in activeThreads)
{
ThreadInfo t = entry.Value;
if (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();
ThreadInfo dummy;
activeThreads.TryRemove(entry.Key, out dummy);
// 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++;
}
}
}
public static void FireAndForget(System.Threading.WaitCallback callback, object obj)
{
FireAndForget(callback, obj, null);
}
public static void FireAndForget(System.Threading.WaitCallback callback, object obj, string context)
{
WaitCallback realCallback;
bool loggingEnabled = LogThreadPool > 0;
long threadFuncNum = Interlocked.Increment(ref nextThreadFuncNum);
ThreadInfo threadInfo = new ThreadInfo(threadFuncNum, context);
if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
{
// If we're running regression tests, then we want any exceptions to rise up to the test code.
@@ -1875,51 +2135,258 @@ namespace OpenSim.Framework
// for decimals places but is read by a culture that treats commas as number seperators.
realCallback = o =>
{
Culture.SetCurrentCulture();
long numQueued1 = Interlocked.Decrement(ref numQueuedThreadFuncs);
long numRunning1 = Interlocked.Increment(ref numRunningThreadFuncs);
threadInfo.Started();
activeThreads[threadFuncNum] = threadInfo;
try
{
if ((loggingEnabled || (threadFuncOverloadMode == 1)) && threadInfo.LogThread)
m_log.DebugFormat("Run threadfunc {0} (Queued {1}, Running {2})", threadFuncNum, numQueued1, numRunning1);
Culture.SetCurrentCulture();
callback(o);
}
catch (ThreadAbortException e)
{
m_log.Error(string.Format("Aborted threadfunc {0} ", threadFuncNum), e);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[UTIL]: Continuing after async_call_method thread terminated with exception {0}{1}",
e.Message, e.StackTrace);
m_log.Error(string.Format("[UTIL]: Util STP threadfunc {0} terminated with error ", threadFuncNum), e);
}
finally
{
Interlocked.Decrement(ref numRunningThreadFuncs);
threadInfo.Ended();
ThreadInfo dummy;
activeThreads.TryRemove(threadFuncNum, out dummy);
if ((loggingEnabled || (threadFuncOverloadMode == 1)) && threadInfo.LogThread)
m_log.DebugFormat("Exit threadfunc {0} ({1})", threadFuncNum, FormatDuration(threadInfo.Elapsed()));
}
};
}
switch (FireAndForgetMethod)
long numQueued = Interlocked.Increment(ref numQueuedThreadFuncs);
try
{
case FireAndForgetMethod.RegressionTest:
case FireAndForgetMethod.None:
realCallback.Invoke(obj);
break;
case FireAndForgetMethod.UnsafeQueueUserWorkItem:
ThreadPool.UnsafeQueueUserWorkItem(realCallback, obj);
break;
case FireAndForgetMethod.QueueUserWorkItem:
ThreadPool.QueueUserWorkItem(realCallback, obj);
break;
case FireAndForgetMethod.BeginInvoke:
FireAndForgetWrapper wrapper = FireAndForgetWrapper.Instance;
wrapper.FireAndForget(realCallback, obj);
break;
case FireAndForgetMethod.SmartThreadPool:
if (m_ThreadPool == null)
InitThreadPool(2, 15);
m_ThreadPool.QueueWorkItem((cb, o) => cb(o), realCallback, obj);
break;
case FireAndForgetMethod.Thread:
Thread thread = new Thread(delegate(object o) { realCallback(o); });
thread.Start(obj);
break;
default:
throw new NotImplementedException();
long numRunning = numRunningThreadFuncs;
if (m_ThreadPool != null && LogOverloads)
{
if ((threadFuncOverloadMode == 0) && (numRunning >= m_ThreadPool.MaxThreads))
{
if (Interlocked.CompareExchange(ref threadFuncOverloadMode, 1, 0) == 0)
m_log.DebugFormat("Threadfunc: enable overload mode (Queued {0}, Running {1})", numQueued, numRunning);
}
else if ((threadFuncOverloadMode == 1) && (numRunning <= (m_ThreadPool.MaxThreads * 2) / 3))
{
if (Interlocked.CompareExchange(ref threadFuncOverloadMode, 0, 1) == 1)
m_log.DebugFormat("Threadfunc: disable overload mode (Queued {0}, Running {1})", numQueued, numRunning);
}
}
if (loggingEnabled || (threadFuncOverloadMode == 1))
{
string full, partial;
GetFireAndForgetStackTrace(out full, out partial);
threadInfo.StackTrace = full;
threadInfo.LogThread = ShouldLogThread(partial);
if (threadInfo.LogThread)
{
m_log.DebugFormat("Queue threadfunc {0} (Queued {1}, Running {2}) {3}{4}",
threadFuncNum, numQueued, numRunningThreadFuncs,
(context == null) ? "" : ("(" + context + ") "),
(LogThreadPool >= 2) ? full : partial);
}
}
switch (FireAndForgetMethod)
{
case FireAndForgetMethod.RegressionTest:
case FireAndForgetMethod.None:
realCallback.Invoke(obj);
break;
case FireAndForgetMethod.UnsafeQueueUserWorkItem:
ThreadPool.UnsafeQueueUserWorkItem(realCallback, obj);
break;
case FireAndForgetMethod.QueueUserWorkItem:
ThreadPool.QueueUserWorkItem(realCallback, obj);
break;
case FireAndForgetMethod.BeginInvoke:
FireAndForgetWrapper wrapper = FireAndForgetWrapper.Instance;
wrapper.FireAndForget(realCallback, obj);
break;
case FireAndForgetMethod.SmartThreadPool:
if (m_ThreadPool == null)
InitThreadPool(2, 15);
threadInfo.WorkItem = m_ThreadPool.QueueWorkItem((cb, o) => cb(o), realCallback, obj);
break;
case FireAndForgetMethod.Thread:
Thread thread = new Thread(delegate(object o) { realCallback(o); });
thread.Start(obj);
break;
default:
throw new NotImplementedException();
}
}
catch (Exception)
{
Interlocked.Decrement(ref numQueuedThreadFuncs);
ThreadInfo dummy;
activeThreads.TryRemove(threadFuncNum, out dummy);
throw;
}
}
/// <summary>
/// Returns whether the thread should be logged. Some very common threads aren't logged,
/// to avoid filling up the log.
/// </summary>
/// <param name="stackTrace">A partial stack trace of where the thread was queued</param>
/// <returns>Whether to log this thread</returns>
private static bool ShouldLogThread(string stackTrace)
{
if (LogThreadPool < 3)
{
if (stackTrace.Contains("BeginFireQueueEmpty"))
return false;
}
return true;
}
/// <summary>
/// Returns a stack trace for a thread added using FireAndForget().
/// </summary>
/// <param name="full">Will contain the full stack trace</param>
/// <param name="partial">Will contain only the first frame of the stack trace</param>
private static void GetFireAndForgetStackTrace(out string full, out string partial)
{
string src = Environment.StackTrace;
string[] lines = src.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
StringBuilder dest = new StringBuilder(src.Length);
bool started = false;
bool first = true;
partial = "";
for (int i = 0; i < lines.Length; i++)
{
string line = lines[i];
if (!started)
{
// Skip the initial stack frames, because they're of no interest for debugging
if (line.Contains("StackTrace") || line.Contains("FireAndForget"))
continue;
started = true;
}
if (first)
{
line = line.TrimStart();
first = false;
partial = line;
}
bool last = (i == lines.Length - 1);
if (last)
dest.Append(line);
else
dest.AppendLine(line);
}
full = dest.ToString();
}
#pragma warning disable 0618
/// <summary>
/// Return the stack trace of a different thread.
/// </summary>
/// <remarks>
/// This is complicated because the thread needs to be paused in order to get its stack
/// 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
///
/// </remarks>
/// <returns>The stack trace, or null if failed to get it</returns>
private static StackTrace GetStackTrace(Thread targetThread)
{
if (IsPlatformMono)
{
// This doesn't work in Mono
return null;
}
ManualResetEventSlim fallbackThreadReady = new ManualResetEventSlim();
ManualResetEventSlim exitedSafely = new ManualResetEventSlim();
try
{
new Thread(delegate()
{
fallbackThreadReady.Set();
while (!exitedSafely.Wait(200))
{
try
{
targetThread.Resume();
}
catch (Exception)
{
// Whatever happens, do never stop to resume the main-thread regularly until the main-thread has exited safely.
}
}
}).Start();
fallbackThreadReady.Wait();
// From here, you have about 200ms to get the stack-trace
targetThread.Suspend();
StackTrace trace = null;
try
{
trace = new StackTrace(targetThread, true);
}
catch (ThreadStateException)
{
//failed to get stack trace, since the fallback-thread resumed the thread
//possible reasons:
//1.) This thread was just too slow
//2.) A deadlock ocurred
//Automatic retry seems too risky here, so just return null.
}
try
{
targetThread.Resume();
}
catch (ThreadStateException)
{
// Thread is running again already
}
return trace;
}
finally
{
// Signal the fallack-thread to stop
exitedSafely.Set();
}
}
#pragma warning restore 0618
/// <summary>
/// Get information about the current state of the smart thread pool.
/// </summary>
@@ -1948,6 +2415,36 @@ namespace OpenSim.Framework
#endregion FireAndForget Threading Pattern
/// <summary>
/// Run the callback on a different thread, outside the thread pool. This is used for tasks
/// that may take a long time.
/// </summary>
public static void RunThreadNoTimeout(WaitCallback callback, string name, object obj)
{
if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
{
Culture.SetCurrentCulture();
callback(obj);
return;
}
Thread t = new Thread(delegate()
{
try
{
Culture.SetCurrentCulture();
callback(obj);
}
catch (Exception e)
{
m_log.Error("Exception in thread " + name, e);
}
});
t.Name = name;
t.Start();
}
/// <summary>
/// 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
@@ -2003,6 +2500,60 @@ namespace OpenSim.Framework
return tcA - tcB;
}
/// <summary>
/// Formats a duration (given in milliseconds).
/// </summary>
public static string FormatDuration(int ms)
{
TimeSpan span = new TimeSpan(ms * TimeSpan.TicksPerMillisecond);
string str = "";
string suffix = null;
int hours = (int)span.TotalHours;
if (hours > 0)
{
str += hours.ToString(str.Length == 0 ? "0" : "00");
suffix = "hours";
}
if ((hours > 0) || (span.Minutes > 0))
{
if (str.Length > 0)
str += ":";
str += span.Minutes.ToString(str.Length == 0 ? "0" : "00");
if (suffix == null)
suffix = "min";
}
if ((hours > 0) || (span.Minutes > 0) || (span.Seconds > 0))
{
if (str.Length > 0)
str += ":";
str += span.Seconds.ToString(str.Length == 0 ? "0" : "00");
if (suffix == null)
suffix = "sec";
}
if (suffix == null)
suffix = "ms";
if (span.TotalMinutes < 1)
{
int ms1 = span.Milliseconds;
if (str.Length > 0)
{
ms1 /= 100;
str += ".";
}
str += ms1.ToString("0");
}
str += " " + suffix;
return str;
}
/// <summary>
/// Prints the call stack at any given point. Useful for debugging.
/// </summary>
@@ -2222,10 +2773,15 @@ namespace OpenSim.Framework
{
string[] parts = firstName.Split(new char[] { '.' });
if (parts.Length == 2)
return id.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
return CalcUniversalIdentifier(id, agentsURI, parts[0] + " " + parts[1]);
}
return id.ToString() + ";" + agentsURI + ";" + firstName + " " + lastName;
return CalcUniversalIdentifier(id, agentsURI, firstName + " " + lastName);
}
private static string CalcUniversalIdentifier(UUID id, string agentsURI, string name)
{
return id.ToString() + ";" + agentsURI + ";" + name;
}
/// <summary>
@@ -2260,6 +2816,38 @@ namespace OpenSim.Framework
{
return str.Replace("_", "\\_").Replace("%", "\\%");
}
/// <summary>
/// Returns the name of the user's viewer.
/// </summary>
/// <remarks>
/// This method handles two ways that viewers specify their name:
/// 1. Viewer = "Firestorm-Release 4.4.2.34167", Channel = "(don't care)" -> "Firestorm-Release 4.4.2.34167"
/// 2. Viewer = "4.5.1.38838", Channel = "Firestorm-Beta" -> "Firestorm-Beta 4.5.1.38838"
/// </remarks>
public static string GetViewerName(AgentCircuitData agent)
{
string name = agent.Viewer;
if (name == null)
name = "";
else
name = name.Trim();
// Check if 'Viewer' is just a version number. If it's *not*, then we
// assume that it contains the real viewer name, and we return it.
foreach (char c in name)
{
if (Char.IsLetter(c))
return name;
}
// The 'Viewer' string contains just a version number. If there's anything in
// 'Channel' then assume that it's the viewer name.
if ((agent.Channel != null) && (agent.Channel.Length > 0))
name = agent.Channel.Trim() + " " + name;
return name;
}
}
public class DoubleQueue<T> where T:class
@@ -2276,7 +2864,11 @@ namespace OpenSim.Framework
public virtual int Count
{
get { return m_highQueue.Count + m_lowQueue.Count; }
get
{
lock (m_syncRoot)
return m_highQueue.Count + m_lowQueue.Count;
}
}
public virtual void Enqueue(T data)
File diff suppressed because it is too large Load Diff
@@ -82,8 +82,7 @@ namespace OpenSim
List<string> sources = new List<string>();
string masterFileName =
startupConfig.GetString("inimaster", "OpenSimDefaults.ini");
string masterFileName = startupConfig.GetString("inimaster", "OpenSimDefaults.ini");
if (masterFileName == "none")
masterFileName = String.Empty;
@@ -207,26 +206,13 @@ namespace OpenSim
Environment.Exit(1);
}
// Merge OpSys env vars
m_log.Info("[CONFIG]: Loading environment variables for Config");
Util.MergeEnvironmentToConfig(m_config.Source);
// Make sure command line options take precedence
m_config.Source.Merge(argvSource);
IConfig enVars = m_config.Source.Configs["Environment"];
if( enVars != null )
{
string[] env_keys = enVars.GetKeys();
foreach ( string key in env_keys )
{
envConfigSource.AddEnv(key, string.Empty);
}
envConfigSource.LoadEnv();
m_config.Source.Merge(envConfigSource);
}
m_config.Source.ExpandKeyValues();
ReadConfigSettings();
return m_config;
+272 -18
View File
@@ -45,6 +45,7 @@ using OpenSim.Framework.Servers;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
namespace OpenSim
{
@@ -271,6 +272,7 @@ namespace OpenSim
+ " [--no-objects]"
+ " [--rotation degrees] [--rotation-center \"<x,y,z>\"]"
+ " [--displacement \"<x,y,z>\"]"
+ " [--default-user \"User Name\"]"
+ " [<OAR path>]",
"Load a region's data from an OAR archive.",
"--merge will merge the OAR with the existing scene (suppresses terrain and parcel info loading)." + Environment.NewLine
@@ -399,6 +401,27 @@ namespace OpenSim
"delete-region <name>",
"Delete a region from disk",
RunCommand);
m_console.Commands.AddCommand("Estates", false, "estate create",
"estate create <owner UUID> <estate name>",
"Creates a new estate with the specified name, owned by the specified user."
+ " Estate name must be unique.",
CreateEstateCommand);
m_console.Commands.AddCommand("Estates", false, "estate set owner",
"estate set owner <estate-id>[ <UUID> | <Firstname> <Lastname> ]",
"Sets the owner of the specified estate to the specified UUID or user. ",
SetEstateOwnerCommand);
m_console.Commands.AddCommand("Estates", false, "estate set name",
"estate set name <estate-id> <new name>",
"Sets the name of the specified estate to the specified value. New name must be unique.",
SetEstateNameCommand);
m_console.Commands.AddCommand("Estates", false, "estate link region",
"estate link region <estate ID> <region ID>",
"Attaches the specified region to the specified estate.",
EstateLinkRegionCommand);
}
protected override void ShutdownSpecific()
@@ -559,7 +582,7 @@ namespace OpenSim
{
scene.ForEachSOG(delegate(SceneObjectGroup sog)
{
if (sog.AttachmentPoint == 0)
if (!sog.IsAttachment)
{
sog.RootPart.UpdateRotation(rot * sog.GroupRotation);
Vector3 offset = sog.AbsolutePosition - center;
@@ -588,7 +611,7 @@ namespace OpenSim
{
scene.ForEachSOG(delegate(SceneObjectGroup sog)
{
if (sog.AttachmentPoint == 0)
if (!sog.IsAttachment)
{
if (sog.RootPart.AbsolutePosition.Z < minZ)
minZ = sog.RootPart.AbsolutePosition.Z;
@@ -600,7 +623,7 @@ namespace OpenSim
{
scene.ForEachSOG(delegate(SceneObjectGroup sog)
{
if (sog.AttachmentPoint == 0)
if (!sog.IsAttachment)
{
Vector3 tmpRootPos = sog.RootPart.AbsolutePosition;
tmpRootPos.Z -= minZ;
@@ -640,7 +663,7 @@ namespace OpenSim
{
scene.ForEachSOG(delegate(SceneObjectGroup sog)
{
if (sog.AttachmentPoint == 0)
if (!sog.IsAttachment)
sog.UpdateGroupPosition(sog.AbsolutePosition + offset);
});
});
@@ -707,7 +730,7 @@ namespace OpenSim
CreateRegion(regInfo, true, out scene);
if (changed)
regInfo.EstateSettings.Save();
m_estateDataService.StoreEstateSettings(regInfo.EstateSettings);
}
/// <summary>
@@ -916,17 +939,24 @@ namespace OpenSim
break;
case "regions":
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
cdt.AddColumn("Name", ConsoleDisplayUtil.RegionNameSize);
cdt.AddColumn("ID", ConsoleDisplayUtil.UuidSize);
cdt.AddColumn("Position", ConsoleDisplayUtil.CoordTupleSize);
cdt.AddColumn("Port", ConsoleDisplayUtil.PortSize);
cdt.AddColumn("Ready?", 6);
cdt.AddColumn("Estate", ConsoleDisplayUtil.EstateNameSize);
SceneManager.ForEachScene(
delegate(Scene scene)
{
MainConsole.Instance.Output(String.Format(
"Region Name: {0}, Region XLoc: {1}, Region YLoc: {2}, Region Port: {3}, Estate Name: {4}",
scene.RegionInfo.RegionName,
scene.RegionInfo.RegionLocX,
scene.RegionInfo.RegionLocY,
scene.RegionInfo.InternalEndPoint.Port,
scene.RegionInfo.EstateSettings.EstateName));
});
scene =>
{
RegionInfo ri = scene.RegionInfo;
cdt.AddRow(
ri.RegionName, ri.RegionID, string.Format("{0},{1}", ri.RegionLocX, ri.RegionLocY),
ri.InternalEndPoint.Port, scene.Ready ? "Yes" : "No", ri.EstateSettings.EstateName);
}
);
MainConsole.Instance.Output(cdt.ToString());
break;
case "ratings":
@@ -975,7 +1005,7 @@ namespace OpenSim
aCircuit.child ? "child" : "root",
aCircuit.circuitcode.ToString(),
aCircuit.IPAddress != null ? aCircuit.IPAddress.ToString() : "not set",
aCircuit.Viewer);
Util.GetViewerName(aCircuit));
});
MainConsole.Instance.Output(cdt.ToString());
@@ -1158,6 +1188,232 @@ namespace OpenSim
SceneManager.SaveCurrentSceneToArchive(cmdparams);
}
protected void CreateEstateCommand(string module, string[] args)
{
string response = null;
UUID userID;
if (args.Length == 2)
{
response = "No user specified.";
}
else if (!UUID.TryParse(args[2], out userID))
{
response = String.Format("{0} is not a valid UUID", args[2]);
}
else if (args.Length == 3)
{
response = "No estate name specified.";
}
else
{
Scene scene = SceneManager.CurrentOrFirstScene;
// TODO: Is there a better choice here?
UUID scopeID = UUID.Zero;
UserAccount account = scene.UserAccountService.GetUserAccount(scopeID, userID);
if (account == null)
{
response = String.Format("Could not find user {0}", userID);
}
else
{
// concatenate it all to "name"
StringBuilder sb = new StringBuilder(args[3]);
for (int i = 4; i < args.Length; i++)
sb.Append (" " + args[i]);
string estateName = sb.ToString().Trim();
// send it off for processing.
IEstateModule estateModule = scene.RequestModuleInterface<IEstateModule>();
response = estateModule.CreateEstate(estateName, userID);
if (response == String.Empty)
{
List<int> estates = scene.EstateDataService.GetEstates(estateName);
response = String.Format("Estate {0} created as \"{1}\"", estates.ElementAt(0), estateName);
}
}
}
// give the user some feedback
if (response != null)
MainConsole.Instance.Output(response);
}
protected void SetEstateOwnerCommand(string module, string[] args)
{
string response = null;
Scene scene = SceneManager.CurrentOrFirstScene;
IEstateModule estateModule = scene.RequestModuleInterface<IEstateModule>();
if (args.Length == 3)
{
response = "No estate specified.";
}
else
{
int estateId;
if (!int.TryParse(args[3], out estateId))
{
response = String.Format("\"{0}\" is not a valid ID for an Estate", args[3]);
}
else
{
if (args.Length == 4)
{
response = "No user specified.";
}
else
{
UserAccount account = null;
// TODO: Is there a better choice here?
UUID scopeID = UUID.Zero;
string s1 = args[4];
if (args.Length == 5)
{
// attempt to get account by UUID
UUID u;
if (UUID.TryParse(s1, out u))
{
account = scene.UserAccountService.GetUserAccount(scopeID, u);
if (account == null)
response = String.Format("Could not find user {0}", s1);
}
else
{
response = String.Format("Invalid UUID {0}", s1);
}
}
else
{
// attempt to get account by Firstname, Lastname
string s2 = args[5];
account = scene.UserAccountService.GetUserAccount(scopeID, s1, s2);
if (account == null)
response = String.Format("Could not find user {0} {1}", s1, s2);
}
// If it's valid, send it off for processing.
if (account != null)
response = estateModule.SetEstateOwner(estateId, account);
if (response == String.Empty)
{
response = String.Format("Estate owner changed to {0} ({1} {2})", account.PrincipalID, account.FirstName, account.LastName);
}
}
}
}
// give the user some feedback
if (response != null)
MainConsole.Instance.Output(response);
}
protected void SetEstateNameCommand(string module, string[] args)
{
string response = null;
Scene scene = SceneManager.CurrentOrFirstScene;
IEstateModule estateModule = scene.RequestModuleInterface<IEstateModule>();
if (args.Length == 3)
{
response = "No estate specified.";
}
else
{
int estateId;
if (!int.TryParse(args[3], out estateId))
{
response = String.Format("\"{0}\" is not a valid ID for an Estate", args[3]);
}
else
{
if (args.Length == 4)
{
response = "No name specified.";
}
else
{
// everything after the estate ID is "name"
StringBuilder sb = new StringBuilder(args[4]);
for (int i = 5; i < args.Length; i++)
sb.Append (" " + args[i]);
string estateName = sb.ToString();
// send it off for processing.
response = estateModule.SetEstateName(estateId, estateName);
if (response == String.Empty)
{
response = String.Format("Estate {0} renamed to \"{1}\"", estateId, estateName);
}
}
}
}
// give the user some feedback
if (response != null)
MainConsole.Instance.Output(response);
}
private void EstateLinkRegionCommand(string module, string[] args)
{
int estateId =-1;
UUID regionId = UUID.Zero;
Scene scene = null;
string response = null;
if (args.Length == 3)
{
response = "No estate specified.";
}
else if (!int.TryParse(args [3], out estateId))
{
response = String.Format("\"{0}\" is not a valid ID for an Estate", args [3]);
}
else if (args.Length == 4)
{
response = "No region specified.";
}
else if (!UUID.TryParse(args[4], out regionId))
{
response = String.Format("\"{0}\" is not a valid UUID for a Region", args [4]);
}
else if (!SceneManager.TryGetScene(regionId, out scene))
{
// region may exist, but on a different sim.
response = String.Format("No access to Region \"{0}\"", args [4]);
}
if (response != null)
{
MainConsole.Instance.Output(response);
return;
}
// send it off for processing.
IEstateModule estateModule = scene.RequestModuleInterface<IEstateModule>();
response = estateModule.SetRegionEstate(scene.RegionInfo, estateId);
if (response == String.Empty)
{
estateModule.TriggerRegionInfoChange();
estateModule.sendRegionHandshakeToAll();
response = String.Format ("Region {0} is now attached to estate {1}", regionId, estateId);
}
// give the user some feedback
if (response != null)
MainConsole.Instance.Output (response);
}
#endregion
private static string CombineParams(string[] commandParams, int pos)
{
string result = String.Empty;
@@ -1168,7 +1424,5 @@ namespace OpenSim
result = result.TrimEnd(' ');
return result;
}
#endregion
}
}

Some files were not shown because too many files have changed in this diff Show More