Compare commits

...

427 Commits

Author SHA1 Message Date
BlueWall 0a949a20ca Send the service so the pluggin can load other assemblies 2012-04-11 09:19:16 -04:00
BlueWall bb3aa1440d Tell git to remove these files (moved)
These are now living in lib32/lib64 directories.
2012-04-11 06:24:56 -04:00
BlueWall 1d4bee454e Merge branch 'master' of /home/opensim/var/repo/opensim 2012-04-10 19:19:00 -04:00
BlueWall d95e6ca0c6 More work on install/loading/unloading
Moved troublesome openjpeg libs - testing to see if opensim region can run with the change
2012-04-10 19:01:22 -04:00
Snoopy Pfeffer 78fd487a70 New OS scripting functions osSetTerrainTexture and osSetTerrainHeight as originally proposed in SL Jira (https://jira.secondlife.com/browse/SVC-244). 2012-04-10 21:49:43 +02:00
Justin Clark-Casey (justincc) 4ab479bf58 Add uri to various log messages when region registration fails. Upgrade some debug log messages to error. 2012-04-10 20:40:59 +01:00
BlueWall 3e6043bb47 Merge branch 'master' of /home/opensim/var/repo/opensim 2012-04-10 14:38:18 -04:00
BlueWall 679533f632 Work on loading new addins 2012-04-10 14:36:24 -04:00
Justin Clark-Casey (justincc) fb44e7b636 minor: convert tabs to spaces in config example files from recent 7c534e5 2012-04-10 17:46:34 +01:00
Justin Clark-Casey (justincc) 2b339bfd97 Correct max_listeners_per_region in OpenSimDefaults.ini to max_listens_per_region
Value for this setting in OpenSimDefaults.ini (1000) is same as setting in code (1000) so this should have no effect
Thanks to Ovi Chris Rouly for pointing this out.
2012-04-10 17:22:02 +01:00
Snoopy Pfeffer f9dd4ed89c Do not timeout group member cache entry, as long as there are frequent group membership requests. These are caused by movements within the parcel boundaries. 2012-04-10 15:51:26 +02:00
BlueWall a798b98f85 More work on dynamic loading/unloading 2012-04-10 00:20:55 -04:00
BlueWall 0838c5288f Add method for plugin teardown/unloading 2012-04-09 21:59:21 -04:00
BlueWall 35fa8b454d Working on run-time init
Working on build-up and tear-down for loading/unloading pluggins
2012-04-09 17:53:55 -04:00
BlueWall 4b278c64d6 Merge branch 'master' of /home/opensim/var/repo/opensim 2012-04-09 17:50:57 -04:00
Talun 78c0028179 Mantis5502 implementation of some of the new constants
Signed-off-by: Melanie <melanie@t-data.com>
2012-04-09 21:25:22 +01:00
BlueWall 27845de7ea Merge branch 'master' of /home/opensim/var/repo/opensim 2012-04-08 20:58:56 -04:00
Diva Canto 0f277dfa17 Addresses mantis #5846 2012-04-08 17:54:59 -07:00
BlueWall fb18476032 More work on comands
Getting this framed up. Will make generic returns so as to interface with external web service to manage plugins.
2012-04-08 20:25:28 -04:00
BlueWall 74776c4ee0 More command work
Start working toward using list entry numbers to select instead of the plugin id
2012-04-08 20:09:54 -04:00
BlueWall 952ad59c1f Work on commands 2012-04-08 17:38:44 -04:00
BlueWall c066f528ef Merge branch 'master' of /home/opensim/var/repo/opensim 2012-04-07 23:44:25 -04:00
BlueWall 0591a85787 More work on commands 2012-04-07 23:39:15 -04:00
Diva Canto d4a370a5f2 A few more minor improvements on Suitcase inventory service. 2012-04-07 14:52:15 -07:00
Diva Canto 7c534e558d Added gatekeeper and uas addresses to grid info, so that viewers can take advantage of that info. 2012-04-07 14:38:32 -07:00
BlueWall 7a686ef124 Some work on web interface
Adding some web handlers to manage plugins. Returns json for integration into external processing.
2012-04-07 14:52:02 -04:00
BlueWall 931c28888b Merge branch 'master' of /home/opensim/var/repo/opensim 2012-04-07 14:22:14 -04:00
Diva Canto 0d566aa385 Better Suitcase Inventory Service. 2012-04-06 21:52:48 -07:00
BlueWall d4a6ed3d98 Merge branch 'master' of /home/opensim/var/repo/opensim 2012-04-06 23:56:08 -04:00
Diva Canto 806082cd6e Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-04-06 20:35:01 -07:00
Diva Canto 9637e50956 Moved the inventory manipulation from HGEntityTransferModule to HGInventoryAccessModule where it belongs. They need to exchange some events, so added those to EventManager. Those events (TeleportStart and TeleportFail) are nice to have anyway. 2012-04-06 20:34:31 -07:00
BlueWall b8eafc6280 More work on commands
Install is working now
2012-04-06 22:22:55 -04:00
BlueWall 5509d981d4 Merge branch 'master' of /home/opensim/var/repo/opensim 2012-04-06 20:11:58 -04:00
Justin Clark-Casey (justincc) cce760dbfc Rather than having a FromFolderID property on every single prim and only ever using the root prim one, store on SOG instead.
This reduces pointless memory usage.
2012-04-07 00:40:55 +01:00
Justin Clark-Casey (justincc) 7d8bb33c5b Store FromItemID for attachments once on SOG instead of on every SOP and only ever using the root part entry.
This eliminates some pointless memory use.
2012-04-07 00:33:02 +01:00
BlueWall 4f4ca1625f Merge branch 'master' of /home/opensim/var/repo/opensim 2012-04-06 19:24:14 -04:00
BlueWall 90a2296983 Have some commands working
Still rough, but making some progress.
2012-04-06 19:22:34 -04:00
Justin Clark-Casey (justincc) 70b5a2dace refactor: Eliminate unnecessary SOP.m_physActor 2012-04-06 23:49:23 +01:00
Justin Clark-Casey (justincc) 33e91f1088 Implement PRIM_POS_LOCAL on llSetPrimitiveParams() and other prim params LSL functions.
This is the same as PRIM_POSITION
2012-04-06 23:43:03 +01:00
Justin Clark-Casey (justincc) 4a58d4c5a4 refactor: Use clearer part.ParentGroup.IsAttachment in LSL_Api.GetPartLocalPos() 2012-04-06 23:36:13 +01:00
Justin Clark-Casey (justincc) 3af1cd65f9 Fix llGetLinkPrimParams for PRIM_POS_LOCAL for child prims whether in scene or attachments.
Return relative position to root prim rather than 0,0,0.
Should fix same issue with llGetLocalPos()
http://opensimulator.org/mantis/view.php?id=5951
2012-04-06 22:41:35 +01:00
Justin Clark-Casey (justincc) 47108bb351 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-04-06 21:15:31 +01:00
Justin Clark-Casey (justincc) f2903db390 For llGetMass(), return the mass of the avatar is the object is attached.
As per http://lslwiki.net/lslwiki/wakka.php?wakka=llGetMass
This is the mass as used by the physics engine (ODE or Bullet).
2012-04-06 21:14:19 +01:00
Talun c3a8c00ce0 Addition of missing constants for llGetObjectDetails including for Mantis 5502
Signed-off-by: nebadon <michael@osgrid.org>
2012-04-06 12:42:46 -07:00
Justin Clark-Casey (justincc) 627efc172b Make llGetMass() return total mass of object when called on root prim.
As per http://lslwiki.net/lslwiki/wakka.php?wakka=llGetMass
Aims to resolve http://opensimulator.org/mantis/view.php?id=5954
2012-04-06 20:32:39 +01:00
Justin Clark-Casey (justincc) 908cebbea8 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-04-06 20:29:54 +01:00
Diva Canto 6a9f36788d Deleted the unused and commented code from 2 commits ago. 2012-04-06 12:28:15 -07:00
Diva Canto 4c32f79c10 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-04-06 11:52:38 -07:00
Diva Canto 7435582b70 If an AddItem fails, try adding it to the right folder type. 2012-04-06 11:52:05 -07:00
Diva Canto 25b3edc21c WARNING: LOTS OF COMMENTED AND UNUSED CODE IN THIS COMMIT. This is on purpose; it's an historical record of what works and what doesn't wrt manipulating inventory at the viewer. I'll remove the unused code in a subsequent commit, but wanted to place it in history. The uncommented code works. 2012-04-06 11:51:12 -07:00
Diva Canto 953fe46811 A few minor tweaks here and there in XInventoryService. 2012-04-06 11:48:41 -07:00
Diva Canto 6eaff18961 Finish the implementation of GetUserInventory, even though it's still not used. 2012-04-06 11:38:47 -07:00
Diva Canto 8fd86c9156 Packing of folder in SendBulkUpdateInventory always set the folder type to -1. Not sure if there's a reason for it, but I'm changing it to the given folder type. 2012-04-06 11:24:34 -07:00
Diva Canto e324fb2415 Guard against null inventory contents. 2012-04-06 11:22:30 -07:00
Diva Canto cdbe34716f Thank you, BaseHttpServer, for telling me where things go wrong. 2012-04-06 11:21:27 -07:00
BlueWall 1aab096a83 Start filling out commands 2012-04-05 23:48:25 -04:00
BlueWall de1d213117 Adding command skeleton 2012-04-05 13:55:04 -04:00
BlueWall f494e6b086 Working on plugin manager 2012-04-05 12:25:24 -04:00
BlueWall 2d9971ea93 Merge branch 'master' of /home/opensim/var/repo/opensim 2012-04-05 08:34:03 -04:00
Snoopy Pfeffer 67537f3596 Added missing refresh of group membership client side cache to the groups module. Before memberships of non active groups often were not stored in the cache (n_groupPowers). 2012-04-05 13:03:57 +02:00
Snoopy Pfeffer 8f45eb913c Revert last commit 2012-04-05 11:10:05 +02:00
Snoopy Pfeffer e4406c846d Group based access restrictions to parcels require group membership, but not that this group is active for that user. 2012-04-05 10:25:54 +02:00
Snoopy Pfeffer 600a86bcae Little bug fix in HasGroupAccess, to properly store the case "true" in the cache. 2012-04-05 10:02:18 +02:00
BlueWall f266e19243 automatic creation of ini form repository 2012-04-04 20:01:23 -04:00
BlueWall e4a69297f6 Merge branch 'master' of /home/opensim/var/repo/opensim 2012-04-04 20:00:47 -04:00
Melanie a5d6b624f6 Simplify group access checks and break them out into a separate method.
Use existing cache if the avatar is within the region and use an
ExpiringCache to cache status if the avatar is not in the region. The
30 second delay now applies to scripted objects ony and only when the owner
is not present.
2012-04-05 00:45:58 +01:00
Snoopy Pfeffer 36c8fa16c0 Implements group based access restrictions for parcels of land. Because of caching there can be a delay of up to 30 seconds until the access rights are effectively changed for a user. 2012-04-05 00:53:40 +02:00
BlueWall 4fa5fa5e08 Remove some old work + add to config/init 2012-04-04 15:07:19 -04:00
BlueWall d2cd39d0d8 Adding configuration management to plugins 2012-04-04 14:15:52 -04:00
BlueWall a4cb9639cc Merge branch 'master' of /home/opensim/var/repo/opensim 2012-04-04 09:26:29 -04:00
Garmin Kawaguichi 9a9923405a terrain save-tile extensions Signed-off-by: Garmin Kawaguichi <garmin.kawaguichi@magalaxie.com>
Signed-off-by: Melanie <melanie@t-data.com>
2012-04-03 20:06:03 +01:00
BlueWall 639c6bdd62 Add a delay to let regions load before calling PostInit
Something is letting PostInit fire before the regions are loaded. This small delay "fixes" it. Will continue to look for a way to make sure they are loaded first.
2012-04-03 14:50:26 -04:00
Justin Clark-Casey (justincc) 633f4bb3d8 remove possible PhysActor unexpectedly null race conditions when changing prim collision status
factor out common SOP physics scene adding code into a common SOP.AddToPhysics() that is the counterpart to the existing RemoveFromPhysics()
2012-04-03 09:28:17 +01:00
Justin Clark-Casey (justincc) e480e25d8b Fix more SOP.PhysActor race conditions in LSL_Api 2012-04-03 06:01:05 +01:00
Justin Clark-Casey (justincc) 7468299673 Eliminate race condition where many callers would check SOP.PhysicsActor != null then assume it was still not null in later code.
Another thread could come and turn off physics for a part (null PhysicsActor) at any point.
Had to turn off localCopy on warp3D CoreModules section in prebuild.xml since on current nant this copies all DLLs in bin/ which can be a very large number with compiled DLLs
No obvious reason for doing that copy - nothing else does it.
2012-04-03 05:51:38 +01:00
BlueWall b3ecf935cd Update mono-addins 2012-04-02 22:50:13 -04:00
BlueWall 4c5b3adb96 Do some work on the plugin registry locations and configuration manager 2012-04-02 17:06:31 -04:00
BlueWall 335d167ead Added some logging 2012-04-02 00:48:36 -04:00
BlueWall 36daea4480 Added some utilities and copyright/license 2012-04-01 23:15:38 -04:00
BlueWall 5c92aa262a Pass server up to IntegrationService to allow pluggins to register their handlers 2012-04-01 15:58:26 -04:00
BlueWall 445caca18b Merge branch 'master' of /home/opensim/var/repo/opensim 2012-04-01 11:10:21 -04:00
BlueWall 4b90dcfb73 Missed these files 2012-04-01 11:05:05 -04:00
BlueWall ade1acc9d4 Making IntegrationService pluggable
First steps to making a pluggable IntegrationService.
2012-04-01 09:38:59 -04:00
BlueWall e8eb9b7e84 Add Integration Service
Adding an integration service to provide base services at endpoints for external application integration. So far, landtool.php is converted to use the IntegrationService. Others will follow to provide coverage for the base helperuri applications needed in OpenSim.
2012-03-31 17:57:58 -04:00
Melanie 6e7f13a72d Implement bulk inventory update over CAPS (not recursive by design,
do NOT CHANGE THIS, needed for HG 2.0)
2012-03-31 02:32:47 +01:00
Justin Clark-Casey (justincc) 32a953fed7 refactor: Rename SOG.GetChildPart() to GetPart() since it can also return the 'root' part. 2012-03-31 01:52:06 +01:00
Justin Clark-Casey (justincc) f0406f9fe2 Rename SOG.HasChildPrim(uint) to SOG.ContainsPart(uint) to match existing ContainsPart method and remove method duplication.
HasChildPrim is also misleading since the 'root' prim can also be returned.
2012-03-31 01:45:37 +01:00
Justin Clark-Casey (justincc) 387d7fdad5 Allow llRegionSayTo() to work on the PUBLIC_CHANNEL, as per http://wiki.secondlife.com/wiki/LlRegionSayTo
Addresses http://opensimulator.org/mantis/view.php?id=5950
2012-03-31 01:29:13 +01:00
Justin Clark-Casey (justincc) 38d241a317 Add MSSQL login processing fix for servers run on different locales.
This may no longer be an issue with better locale enforcement in OpenSimulator but it doesn't hurt to have this patch.
http://opensimulator.org/mantis/view.php?id=4680
Thanks to controlbreak for this
2012-03-31 01:12:04 +01:00
Justin Clark-Casey (justincc) 69fc8c4985 minor: small message adjustment and unnecessary code elimination when notifying client of no build permission 2012-03-31 01:07:14 +01:00
Justin Clark-Casey (justincc) c2b98cfd4e Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-31 01:04:38 +01:00
PixelTomsen 874140f950 fix Infinite loading on No Rez http://opensimulator.org/mantis/view.php?id=5932 2012-03-31 01:01:59 +01:00
Diva Canto 5a8ed50639 Added missing dependency for MS 2008. I hope. (I don't have 2008 to test this) mantis #5949 2012-03-30 12:39:45 -07:00
Justin Clark-Casey (justincc) e5343bccdf Add Extended flavour option to opensim version information.
This flavour is for changes in addition to the 0.7.3-post-fixes branch that are too large to be considered fixes but should be reasonably stable.
This flavour will almost certainly never see a formal release.
2012-03-30 02:11:32 +01:00
Justin Clark-Casey (justincc) 269e479cdc minor: remove some now unneeded code from FriendsCommandsModule 2012-03-30 02:00:01 +01:00
Justin Clark-Casey (justincc) 3525c876c8 Make default "show friends" console command show friends fetched from the friends service.
There is no a --cache option which will show friends from the local cache if available.
2012-03-30 01:57:38 +01:00
Justin Clark-Casey (justincc) 1ef62ca75e Lock NullFriendsData.m_Data for consistency and against concurrent read/write 2012-03-30 01:23:34 +01:00
Justin Clark-Casey (justincc) bce7964ac2 refactor: Move "friends show cache" console command out into separate FriendsCommandsModule.
Expose required methods on IFriendsModule.  Rename GetFriends() -> GetFriendsFromCache() for self-documentation
2012-03-30 01:05:29 +01:00
Justin Clark-Casey (justincc) 59157d9d63 Add simple login test with online friends. Add IFriendsModule.GrantRights() for granting rights via a module call.
Rename IFriendsModule.GetFriendPerms() -> GetRightsGrantedByFriend() to be more self-documenting and consistent with friends module terminology.
Add some method doc.
2012-03-30 00:42:55 +01:00
Justin Clark-Casey (justincc) b8d383da0a Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-30 00:38:23 +01:00
Diva Canto 30db0ac5e2 Finish up the SuitcaseInventory service. 2012-03-29 16:25:55 -07:00
Justin Clark-Casey (justincc) bf09d6a22b refactor: Stop passing both IClientAPI and agentID to friend event listeners, these are redundant. Replace a few magic numbers with FriendRights enum already used elsewhere. 2012-03-29 18:31:57 +01:00
Justin Clark-Casey (justincc) 012b01f224 Add simple regression test for logging in with offline friends. Don't expect to receive any in this instance. 2012-03-29 03:19:45 +01:00
Justin Clark-Casey (justincc) cd3f3cbdde Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-29 01:29:00 +01:00
Justin Clark-Casey (justincc) 22a85b947a Add back parts of reverted changes that were not concerned with child agent caching.
This adds ScenePresence to IClientAPI.SceneAgent earlier on in the add client process so that its information is available to EventManager.OnNewClient() and OnClientLogin()
Also add a code comment as to why we're caching friend information for child agents.
2012-03-29 01:26:30 +01:00
Melanie 62b1c807c2 Also add OSS header to interface 2012-03-29 01:14:50 +01:00
Melanie bd83676d6c Change namespace on CallingCardModule and correct interface file placemant. Also ass OpenSource header 2012-03-29 01:13:08 +01:00
Justin Clark-Casey (justincc) 93ac47f0d3 Revert "Simplify friends caching by only doing this for root agents - no functions require caching for child agents."
We need to cache child agents so that friends object edit/delete permissions will work across boarders on regions hosted by different simulators.

This reverts commit d9f7b8549b.
2012-03-29 01:08:47 +01:00
Justin Clark-Casey (justincc) a1de9bc33f Revert "Add comment about setting client.SceneAgent in AddNewClient()"
This reverts commit 964cae4f37.
2012-03-29 01:08:37 +01:00
Melanie c52ff5cf7b Committing the Avination calling card module 2012-03-29 00:47:09 +01:00
Melanie 5a82d939e6 Adding the Avination calling card interface 2012-03-29 00:34:28 +01:00
Melanie 532e3dad26 Pushing the Avination Calling card hooks. Module to follow. 2012-03-29 00:31:11 +01:00
Justin Clark-Casey (justincc) 964cae4f37 Add comment about setting client.SceneAgent in AddNewClient() 2012-03-29 00:21:14 +01:00
Justin Clark-Casey (justincc) d9f7b8549b Simplify friends caching by only doing this for root agents - no functions require caching for child agents.
This allows us to avoid unnecessary multiple calls to the friends service.
All friends functions originate from the root agent and only go to other root agents in existing code.
This also allows us to eliminate complex ref counting.
2012-03-28 23:40:25 +01:00
Justin Clark-Casey (justincc) 7aa0c05fba Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-28 23:38:04 +01:00
Justin Clark-Casey (justincc) 33df0c2efd Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-28 23:36:30 +01:00
Robert Adams 4138880464 BulletSim: update 64 bit libraries and change Linux configuration to use the files in the lib32 and lib64 directories as needed. 2012-03-28 15:36:20 -07:00
Diva Canto 6bf4d88397 HG 2.0 Suitcase inventory: proof of concept now working properly with the heavy SendBulkInventoryUpdate message. Waiting for Melanie to finish the light-weight version of that message. 2012-03-28 15:32:19 -07:00
Justin Clark-Casey (justincc) 874bf1f8e5 Enable voice by default on parcels to weaken effects of viewer 2/3 ParcelVoiceInfoRequest bug
Viewer 2/3 contains a bug where the viewer will constantly retry ParcelVoiceInfoRequest requests on voice-disabled parcels where voice is otherwise available.
Attempts to fix this server-side have not been successful - sending a non-OK http code (e.g. a 404) just makes the viewer request again immediately.
Dropping the request entirely is a bit better but the viewer still retries after a minute.
Estate settings already enabled voice by default so doing the same for parcels.  This only has an effect if you have any voice system active at all.
Ultimately, the re-request bug needs to be fixed viewer-side (LL suffers from the same issue!) but it might be worth implementing the drop request hack.
2012-03-28 23:30:28 +01:00
Diva Canto 51dc1e709c HG 2.0: added the beginning of HGSuitcaseInventoryService. Plus moved the hack away from ScenePresence. This is better but it still doesn't restore the inventory upon arrival. 2012-03-28 15:01:37 -07:00
Diva Canto 03766c010f Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-27 20:38:02 -07:00
Diva Canto af96b99356 More on switching the root folder from under the viewer. More experiments. 2012-03-27 20:36:54 -07:00
Melanie 614c404923 Typo fix 2012-03-28 03:45:52 +01:00
Diva Canto 4007f62158 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-27 19:09:03 -07:00
Diva Canto 300968e933 HG: Switch root folders from under the viewer. Towards HG 2.0. This is guarded by an obscure config that no one but me should be using at this point. 2012-03-27 19:08:29 -07:00
Melanie b24605d526 Fix typos 2012-03-28 02:55:29 +01:00
Justin Clark-Casey (justincc) 514a9fdf8e Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-28 02:52:11 +01:00
Justin Clark-Casey (justincc) 12d3ea3029 Add "friends show cache <first-name> <last-name>" command for debugging purposes.
This adds a reverse lookup (name -> ID) to IUserManagement instead of hitting the UserAccountService directly.
2012-03-28 02:51:34 +01:00
Melanie a43e804e59 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-03-28 02:46:31 +01:00
Melanie 0463a00d34 Start on Bulk inventory update via CAPS. Not functional yet. HG v2 2012-03-28 02:45:50 +01:00
Melanie 8c0f1e9058 Add a corresponding method for items. HG v2 2012-03-28 02:10:07 +01:00
Melanie 710c14fb57 Add SendRemoveInventoryFolders which allows to remove one or more
folders from the viewer's inventory view. For HG v2.0. More to come
2012-03-28 01:49:06 +01:00
Justin Clark-Casey (justincc) 445e8bc560 minor: Add some documentation to OnNewClient and OnClientClosed events 2012-03-28 01:08:56 +01:00
Justin Clark-Casey (justincc) cb41fb64be Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-28 01:06:18 +01:00
Melanie 37603ca6da Reverse a conditional in XInventory that made updating system folder evrsion numbers impossible 2012-03-27 23:11:06 +01:00
Diva Canto db5f46fa23 Let grided simulators retrieve the user's inventory skeleton 2012-03-27 15:24:55 -07:00
Justin Clark-Casey (justincc) b74a89bc12 minor: clean up some code formatting in VivoxVoiceModule.cs 2012-03-27 22:33:42 +01:00
Diva Canto 5e07336672 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-27 14:25:36 -07:00
Diva Canto 91950b3147 Amend to previous commit regarding the config name. Bugs bite. 2012-03-27 14:24:59 -07:00
Snoopy Pfeffer 19837ff4dd Two new scripting functions osInviteToGroup(userID) and osEjectFromGroup(userID) that invite/eject users to/from groups the object containing the script is set to. These functions also work for closed groups. 2012-03-27 22:30:02 +02:00
Snoopy Pfeffer 5d37a31436 Merge branch 'master' of ssh://snoopy@opensimulator.org/var/git/opensim 2012-03-27 22:16:25 +02:00
Snoopy Pfeffer 7223b63563 User level based restrictions for HyperGrid teleports, asset uploads, group creations and getting contacted from other grids. Incoming HyperGrid teleports can also be restricted to local users. 2012-03-27 22:09:58 +02:00
Dan Lake 971d32fda3 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-27 12:51:58 -07:00
Dan Lake 0247d738e2 When loading objects from DB, first add to scene, then call TriggerOnSceneObjectLoaded. 2012-03-27 12:50:58 -07:00
Diva Canto de242a29ca HG: beginning of a more restrictive inventory access procedure (optional). Experimental: we'll try switching the root folder from under the viewer. 2012-03-27 11:54:13 -07:00
Diva Canto 2e2634896d Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-27 10:09:08 -07:00
Diva Canto 8131a24cde Send the config section name up to the service classes themselves (XInventory and Assets). 2012-03-27 10:08:13 -07:00
Justin Clark-Casey (justincc) b78224176e Add Garmin Kawaguichi to CONTRIBUTORS.txt 2012-03-27 02:10:39 +01:00
Justin Clark-Casey (justincc) 09c85a6a6c Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-27 02:10:02 +01:00
Garmin Kawaguichi 1aa1a9eb3d In TerrainModule.cs, the command terrain save-tile is modified to remove an unnecessary double argument "minimum Y tile" 2012-03-27 02:05:57 +01:00
Robert Adams 872d513daa BulletSim: make avatar animations update properly.
It seems that ODE calls the avatar collision handling routine even
if there are no collisions. This causes the animation to be updated.
So, for instance, going from HOVER to FLY is caused by the physics engine
calling the collision routine each frame with 0 collisions.
2012-03-26 17:36:33 -07:00
Robert Adams 84c9bd52d3 BulletSim: update BulletSim binaries and configuration fixing a crash which happens when there are more than a few hundred physical objects. 2012-03-26 13:48:15 -07:00
Melanie ad865ab4fc Add some more overloads to allow registering overloaded methods and lists
of methods.
2012-03-26 16:46:07 +01:00
Robert Adams 2fcdecf090 BulletSim: fix typo introducted by previous checkins (git merge sometimes makes mistakes) 2012-03-26 08:57:40 -07:00
Robert Adams f8879e06d2 Merge branch 'bulletsim1' 2012-03-26 08:49:12 -07:00
Robert Adams 3691e39178 BulletSim: update BulletSim.dll and libBulletSim.so with latest versions 2012-03-26 08:48:51 -07:00
Melanie 3810e98474 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim
Conflicts:
	OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
2012-03-26 14:21:15 +01:00
Melanie 7e0936e4b6 Add a hust UUID to the script invocations 2012-03-26 14:19:55 +01:00
Mic Bowman 055269805d Fix compile error in ScriptModuelComms and add some debugging into the modInvoke
routines to simplify finding method registration issues.
2012-03-25 22:59:06 -07:00
Melanie 98a6c78943 Fix the omission on the interface declaration 2012-03-26 03:33:39 +01:00
Melanie c9c01d5226 Further simplify ScriptComms 2012-03-26 03:20:40 +01:00
Melanie ac0f1ff0a6 Dynamically create the delegate type to reduce complexity in the caller 2012-03-26 01:47:20 +01:00
Melanie d7cc194e83 Correct the design error I introduced into ScriptComms. Untested but about to
be.
2012-03-26 01:47:14 +01:00
Melanie cb44808504 Simplify the module invocation registration. The types and method name
can be pulled fromt he delegate so we don't need to pass them explicitly
2012-03-25 19:52:38 +01:00
Mic Bowman a07fa0395f Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-24 22:45:17 -07:00
Mic Bowman a14437ad5a Add support for key, vector, rotation and list types for both
arguments and return values to the modInvoke family of functions.

See http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke
2012-03-24 22:43:42 -07:00
Justin Clark-Casey (justincc) 4f17537555 Allow the user to enter help topics in upper or lowercase.
Forcing uppercase (e.g. help Assets) is too annoying.
Thanks to WhiteStar for pointing this out.
2012-03-24 03:07:01 +00:00
Justin Clark-Casey (justincc) f03c3c062e Hack example on to "terrain save-tile" extended help.
Thanks to Garmin Kawaguichi for the initially suggested text.
2012-03-24 02:41:45 +00:00
Justin Clark-Casey (justincc) f53c6b2594 Use system provided temporary file in "terrain save-tile" to avoid problems with drive letters on windows
Thanks to Garmin Kawaguichi for picking up on this and providing an initial solution (which I adapted).
2012-03-24 02:30:43 +00:00
Justin Clark-Casey (justincc) cf61c74e90 Give feedback when "terrain save-tile" is not successfully invoked. 2012-03-24 02:16:44 +00:00
Robert Adams 07388071d4 Merge branch 'bulletsim1' of ssh://island.sciencesim.com/home/sceneapi/radams1/bs-opensim into bulletsim1
Conflicts:
	OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
2012-03-23 16:20:53 -07:00
Robert Adams ff54b3c366 BulletSim: change default of shouldDisableContactPoolDynamicAllocation from False to True. It seems that collisions don't happen well when it is False (things fall through terrain). 2012-03-23 15:50:32 -07:00
Robert Adams 3f53b7bc91 BulletSim: Add new configuration parameters to get and set console commands 2012-03-23 13:15:24 -07:00
Robert Adams 142de1d02f BulletSim: add a bunch of internal Bullet configuration parameters to OpenSimDefaults.ini and the code. 2012-03-23 13:15:23 -07:00
Robert Adams 1273f259e4 BulletSim: remove confusion between angularVelocity and rotationalVelocity (there is still confusion in the rest of OpenSim). Enhance some debug statements to include the object ID. 2012-03-23 13:15:22 -07:00
Robert Adams 2f6e8564fe BulletSim: add updated (but not working) BulletSim dlls 2012-03-23 13:15:20 -07:00
Robert Adams 1a738caeca BulletSim: update TODO list. Rearrange code for readability. Add per object friction and restitution runtime settable parameters. 2012-03-23 13:15:18 -07:00
Robert Adams de24feb275 BulletSim: Add AvatarRestitution parameter. Centralize computation of buoyancy for flying. Tweek avatar default friction and resititution 2012-03-23 13:15:17 -07:00
Robert Adams 6ecdadb329 BulletSim: set buoyancy in only one place 2012-03-23 13:15:16 -07:00
Robert Adams b22d040169 BulletSim: add some new runtime setable parameters to match the dll. 2012-03-23 13:15:14 -07:00
Robert Adams 6c50442625 BulletSim: update BulletSim.dll to Bullet 2.80 and add libBulletSim.so to the new lib32 and lib64 binary directories 2012-03-23 13:15:13 -07:00
Robert Adams 975184b3f9 BulletSim: Update list of TODO tasks 2012-03-23 13:15:11 -07:00
Robert Adams 164706043d Have the PhysicsParameters module output console command responses
directly to the console rather than logging at INFO (which doesn't
output anything for WARN).

There should really be a WriteLine method on ICommandConsole so all
of the different commands don't have to figure out where the command
output should go.
2012-03-23 13:11:58 -07:00
nebadon 6b87a29c86 fix yield prolog so it compiles with mono 2.11 there has been a bugzilla
report files with mono project in regards to this change, this simply
lets us move forward with using mono 2.11 for now :
https://bugzilla.xamarin.com/show_bug.cgi?id=4052
2012-03-23 02:22:57 -07:00
Justin Clark-Casey (justincc) d4beb2f5bc Comment out log message about sending periodic appearance updates. 2012-03-23 03:39:39 +00:00
Justin Clark-Casey (justincc) e5b182fb41 Add information about SendPeriodicAppearanceUpdates to OpenSimDefaults.ini for now.
Default remains false.
2012-03-23 03:38:33 +00:00
Justin Clark-Casey (justincc) 54887bf386 Add experimental SendPeriodicAppearanceUpdates = true/false setting to [Startup] in OpenSim.ini
On osgrid and other places, I have observed that manually sending appearance updates from the console often relieves grey avatar syndrome.
Despite hunting high and low, I haven't been able to find where this packet is sometimes being lost - it might be a persistent viewer bug for all I know.
Therefore, this experimental setting resends appearance data for everybody in the scene every 60 seconds.  These packets are small and the viewer only fetches texture
data if it doesn't already have it.
Default is false.
2012-03-23 03:33:07 +00:00
Justin Clark-Casey (justincc) 4ed833bc9d Add a scene maintenance thread in parallel to the heartbeat thread. The maintenance thread will end up running regular jobs that don't need to be in the main scene loop.
The idea is to make the critical main scene loop as skinny as possible - it doesn't need to run things that aren't time critical and don't depend on update ordering.
This will be done gradually over time to try and uncover any issues.  Many non-criticial scene loop activities are being launched on separate threadpool threads anyway.
This may also allow modules to register their own maintenance jobs without having to maintain their own timers and threads.
Currently the maintenance loop runs once a second, as opposed to the 89ms scene loop.
2012-03-23 02:49:29 +00:00
Justin Clark-Casey (justincc) 349454ca27 Remove unnecessary shutting down check in Scene.Heartbeat(). Add some method doc. Rename HeartbeatThread, shuttingdown to conform to code standards. 2012-03-23 01:46:11 +00:00
BlueWall c0672cb7db Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-22 21:27:03 -04:00
BlueWall 176bba4f67 Merge branch 'master' of /home/opensim/src/opensim 2012-03-22 21:26:30 -04:00
Justin Clark-Casey (justincc) 18b3f1132e Rename Scene.StartTimer() to Start() - this method no longer uses a timer. Comment out more effectively unused old heartbeat code. 2012-03-23 01:21:43 +00:00
Justin Clark-Casey (justincc) 4ee8b3e23e Fix build break 2012-03-23 01:11:43 +00:00
Justin Clark-Casey (justincc) a9995ede65 Fix bug in ScenePresenceAnimator.RemoveAnimation() introduced in commit 1a8769e
Forgot to uppercase the animation name for default animations, since for some reason we store and use them in upper rather than lowercase.
2012-03-23 01:08:13 +00:00
Justin Clark-Casey (justincc) bc2963d42a Comment out unused scene loop restart code.
This has actually been unused since at least 0.7.2 due to earlier changes.
2012-03-23 01:03:10 +00:00
Justin Clark-Casey (justincc) 08b8ebcc7e Use m_lastFrameTick instead of m_lastUpdate in Scene.GetHealth(). m_lastUpdate is no longer properly updated and is redundant anyway. 2012-03-23 00:55:11 +00:00
BlueWall c903813e00 RegionReady logging
Some maintenance to clean up logging messages
2012-03-22 20:49:45 -04:00
Justin Clark-Casey (justincc) 40b9b519b8 Add commented out section on collisions switch in Scene.SetSceneCoreDebug().
This was not implemented before the recent changes but should be at some point.
2012-03-23 00:12:14 +00:00
Robert Adams efe61b2481 BulletSim: remove confusion between angularVelocity and rotationalVelocity (there is still confusion in the rest of OpenSim). Enhance some debug statements to include the object ID. 2012-03-22 17:04:06 -07:00
Justin Clark-Casey (justincc) 15c2499ccd Comment out login parameters debug output accidentally included with c4b2d24 2012-03-22 23:31:41 +00:00
Justin Clark-Casey (justincc) c1d064e1ca Comment out a terrain save-tile debugging message that accidentally crept in with c4b2d24 2012-03-22 23:16:52 +00:00
Justin Clark-Casey (justincc) 5bf45b9b98 refactor: simplify code for checks when part.OwnerID != destPart.OwnerID in MoveTaskInventoryItem() 2012-03-22 22:40:38 +00:00
Justin Clark-Casey (justincc) 760010d6fb Fix llGiveInventory() so that it checks the destination part for AllowInventoryDrop, not the source.
This allows llAllowInventoryDrop() to work.
Regression test added for this case.
2012-03-22 22:33:37 +00:00
Justin Clark-Casey (justincc) 3bcf71c647 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-22 22:33:16 +00:00
Justin Clark-Casey (justincc) c4b2d24f33 Add llGiveInventory() test from object to object where both objects are owned by the same user. 2012-03-22 22:17:07 +00:00
Diva Canto df624c13c9 HG Friends: don't notify if the server isn't there. 2012-03-22 15:08:57 -07:00
Diva Canto 25e5b6a76c Added new simple_build_permissions config to the .ini and .example files. 2012-03-22 14:21:07 -07:00
Melanie 6bc1ccf234 Change a false false to be truly true - or is this statement false?
Fixes perms boo-boo
2012-03-22 20:39:18 +00:00
Melanie b5d0bc2488 Rework Diva's patch to simplify it 2012-03-22 20:25:20 +00:00
Melanie 45b588cf00 Revert "Simple build permissions feature. NOTE: EXPERIMENTAL, DISABLED BY DEFAULT. Turns out that this can't be expressed by cascading Permission modules, so I did it as per this patch."
This reverts commit 6146e7ef25.
2012-03-22 20:10:38 +00:00
Diva Canto 6146e7ef25 Simple build permissions feature. NOTE: EXPERIMENTAL, DISABLED BY DEFAULT. Turns out that this can't be expressed by cascading Permission modules, so I did it as per this patch. 2012-03-22 12:57:12 -07:00
Justin Clark-Casey (justincc) a8c87bab64 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-22 01:56:07 +00:00
BlueWall c98e3a6422 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-21 20:34:51 -04:00
BlueWall 06c81a2afe Fix typo
Add enclosing " to urls
2012-03-21 20:33:45 -04:00
Robert Adams 4bfd9e28ca BulletSim: add updated (but not working) BulletSim dlls 2012-03-21 17:24:17 -07:00
Justin Clark-Casey (justincc) 9949ac2f9f refactor: Rename AvatarAnimations -> DefaultAvatarAnimations for code clarity since non-default animations are handled completely separately from this class 2012-03-22 00:10:41 +00:00
Justin Clark-Casey (justincc) 71ec84d77f Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-22 00:00:05 +00:00
Justin Clark-Casey (justincc) 1a8769e6ef Instead of loading default avatar animations in both SLUtil and AvatarAnimations, load just in AvatarAnimations instead.
This lets us remove the dependency of OpenSim.Framework.dll on data/avataranimations.xml, which is not necessary for ROBUST.
This commit also takes care of the odd situation where animations are stored and used internally with uppercase names (e.g. "STAND")
but scripts refer to them with lowercase names (e.g. "sit").
2012-03-21 23:57:39 +00:00
Robert Adams 7783c93802 BulletSim: update TODO list. Rearrange code for readability. Add per object friction and restitution runtime settable parameters. 2012-03-21 16:16:47 -07:00
Robert Adams cb2727cf6e BulletSim: Add AvatarRestitution parameter. Centralize computation of buoyancy for flying. Tweek avatar default friction and resititution 2012-03-21 16:16:46 -07:00
Robert Adams 6c55fd93a3 BulletSim: set buoyancy in only one place 2012-03-21 16:16:45 -07:00
Robert Adams 898a16802b BulletSim: add some new runtime setable parameters to match the dll. 2012-03-21 16:16:44 -07:00
Robert Adams 3e7e166124 BulletSim: update BulletSim.dll to Bullet 2.80 and add libBulletSim.so to the new lib32 and lib64 binary directories 2012-03-21 16:16:42 -07:00
Robert Adams eafc3d6c47 BulletSim: Update list of TODO tasks 2012-03-21 16:16:41 -07:00
Diva Canto 5170cd7577 Updated the UserAccountsClient a little bit, plus some more sanity checks on the service connector. 2012-03-21 11:22:39 -07:00
Diva Canto 4a9ca3ca8f HG Friends: reroute the status notifications to the HGFriends service, so that they can scale better. They were previously being handled by the UAS; that is still there, but it's now obsolete and will be removed in a future release. 2012-03-21 10:35:06 -07:00
Diva Canto d8bcb78b10 HG Friends: pulled sim-bound notification code to HGStatusNotifier, so that we can better manage this traffic. 2012-03-21 09:14:17 -07:00
Diva Canto 8ad426f329 Removed extraneous debug message 2012-03-21 08:08:43 -07:00
Diva Canto 1089e9b842 Removed extraneous debug message 2012-03-21 08:08:12 -07:00
Diva Canto 5abe1b4fce Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-20 21:36:46 -07:00
Diva Canto 91cc09b7bf HG Friends config for Robust.HG.ini.example 2012-03-20 21:36:24 -07:00
Diva Canto d49dd5573b Removed extraneous debug messages. Added a check for UUID.Zero. 2012-03-20 21:36:02 -07:00
Justin Clark-Casey (justincc) 54a8a5baba If "debug scene updates true" then print out to log when a garbage collection occurs. 2012-03-21 02:02:14 +00:00
Justin Clark-Casey (justincc) de53aa32e0 Add Scene.DebugUpdates switch which, if turned on, will print out a warning when a frame updates takes longer than twice the desired time
This is controlled via "debug scene updates true|false" on the region console.
Also fix an oversight with "debug scene teleport true|false"
2012-03-21 01:27:09 +00:00
Justin Clark-Casey (justincc) ab243f4a57 Incorporate scene teleporting debugging into "debug scene teleport true|false" command 2012-03-21 01:13:44 +00:00
Justin Clark-Casey (justincc) 9671e43497 Replace "scene debug true false true" console command with "scene debug scripting true" or other parameters as appropriate.
This is to allow individual switching of scene debug settings and to provide flexibiltiy for additional settings.
2012-03-21 01:02:58 +00:00
Melanie 7a0d7be44c Refix the fixed fix! 2012-03-21 00:17:58 +00:00
Diva Canto 69a9a6993e Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-20 17:33:26 -07:00
Justin Clark-Casey (justincc) 91a001d3cf fix compile error from last commit 2012-03-21 00:31:31 +00:00
Diva Canto 9e8b194356 Fixed borkness with map search introduce by my last changes to it. 2012-03-20 17:29:34 -07:00
Diva Canto 742acc0a3c Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-20 17:26:18 -07:00
Diva Canto f7c61790b7 Fixed borkness with previous merge. 2012-03-20 17:25:52 -07:00
Justin Clark-Casey (justincc) 022366a074 refactor: simplify EstateManagementModule.handleEstateDebugRegionRequest() 2012-03-21 00:23:46 +00:00
Diva Canto 841b4232f6 Line endings 2012-03-20 17:19:55 -07:00
Diva Canto 3fa51f66ec Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Conflicts:
	OpenSim/Framework/Util.cs
2012-03-20 17:19:14 -07:00
Diva Canto d08ad6459a HG Friends: allow the establishment of HG friendships without requiring co-presence in the same sim. Using avatar picker, users can now search for names such as "first.last@grid.com:9000", find them, and request friendship. Friendship requests are stored if target user is offline. TESTED ON STANDALONE ONLY. 2012-03-20 17:14:19 -07:00
Justin Clark-Casey (justincc) 7bf628ab31 Add ability to log warn if a frame takes longer than twice the expected time. Currently commented out. 2012-03-21 00:02:08 +00:00
Justin Clark-Casey (justincc) 4c41b53a4b Add prim name to "[MESH]: No recognized physics mesh..." log message 2012-03-20 23:35:50 +00:00
Justin Clark-Casey (justincc) 02f9caf6ce remove some mono compiler warnings 2012-03-20 23:34:10 +00:00
Justin Clark-Casey (justincc) 3701f893d3 remove unnecessary tmpFrameMS, use maintc instead for frame time calculation 2012-03-20 23:31:57 +00:00
Justin Clark-Casey (justincc) c39fba8f9d minor: remove some mono compiler warnings 2012-03-20 23:19:11 +00:00
Justin Clark-Casey (justincc) 8bdd38b804 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-20 23:14:15 +00:00
Justin Clark-Casey (justincc) 30b2a8c778 Move frame loop entirely within Scene.Update() for better future performance analysis and stat accuracy.
Update() now accepts a frames parameter which can control the number of frames updated.
-1 will update until shutdown.
The watchdog updating moves above the maintc recalculation for any required sleep since it should be accounted for within the frame.
2012-03-20 23:12:21 +00:00
nebadon bd1f848bf6 slight increase in jump power to make running jump slightly better. 2012-03-20 14:17:15 -07:00
nebadon 9ed3532c1b reduce avatar verticle jump from the absurd 5 meter jump to a less
absurd 3m vertical jump to better match what you would see in Second
Life and be more in line with what users would expect.
2012-03-20 13:45:38 -07:00
Justin Clark-Casey (justincc) 86bd287b53 refactor: precalculate the fixed movement factor for avatar tilting (sqrt(2)) rather than doing it multiple times on every move. 2012-03-20 20:39:33 +00:00
Justin Clark-Casey (justincc) 5f2a65c976 refactor: Eliminate unnecessary duplicate avCapsuleTilted 2012-03-20 20:28:58 +00:00
Justin Clark-Casey (justincc) a3abd65e3d Remove pointless ThreadAbortException catching in a test that isn't run anyway. 2012-03-20 01:41:32 +00:00
Justin Clark-Casey (justincc) 8c911ddaf0 Remove some pointless catching/throwing in the scene loop. 2012-03-20 01:39:19 +00:00
Justin Clark-Casey (justincc) 4cbaf053cf Fix small typo 2012-03-20 00:53:33 +00:00
Justin Clark-Casey (justincc) 1c0f3a1f21 Fix crash where two scene loop threads could changes m_MeshToTriMeshMap at the same time.
Have to lock m_MeshToTriMeshMap as property is static and with more than one region two scene loops could try to manipulate at the same time.
2012-03-20 00:40:03 +00:00
Justin Clark-Casey (justincc) e9271ec653 Add some doc about the EventManager.OnLoginsEnabled event. 2012-03-19 22:48:26 +00:00
Justin Clark-Casey (justincc) e2b1c569da Fix a bug where logins to standalones would fail if the RegionReady module was not active
Unfortunately, the OnLoginsEnabled event is currently only guaranteed to fire if the RegionReady module is active.
However, we can instantiate the AuthorizationService in the module RegionLoaded method since by this time all other modules will have been loaded
2012-03-19 22:45:03 +00:00
Justin Clark-Casey (justincc) 437f18bc41 Stop console command "xengine status" throwing an exception if there are no scripts in a region.
Addresses http://opensimulator.org/mantis/view.php?id=5940
2012-03-19 21:43:23 +00:00
Justin Clark-Casey (justincc) 4972491efb Move startup/shutdown command .txt files to .txt.example files to avoid clobbering on updates.
Thanks to Whitestar in http://opensimulator.org/mantis/view.php?id=5938 for pointing out this problem.
2012-03-19 00:29:02 +00:00
Justin Clark-Casey (justincc) ab54ce1907 Fix configuration problems where XAssetDatabasePlugin was picked up accidentally.
The asset data plugin now implements IXAssetData rather than IAssetData so the ordinary AssetService should no longer pick it up.
This replaces the changes in 92b1ade.  There is no longer any need to adjust your StandaloneCommon.ini/Robust.ini/Robust.HG.ini files.
This may explain very recent issues in the last few weeks where textures have been disappearing or turning white (as they were going to different places).
Unfortunately, you will need to rollback to an earlier database backup or reupload the textures.
2012-03-19 00:18:04 +00:00
Diva Canto d1256536b5 Added GetUUID(first, last) on UserAgentsService so that we can finally make direct user connections. 2012-03-17 21:27:28 -07:00
Diva Canto 441ef301a3 Amend to previous commit: normalize strings ToLower. 2012-03-17 19:41:47 -07:00
Diva Canto 7dfa0309c6 More on HG access control. This commit splits the UserManagementModule into the Basic one and the HG one, so that we can do everything that needs to be done for HG ACLs to work without interfering with the vanilla opensim. For the moment, it finds foreign users who have left a trace in the region, e.g. an object. This makes it possible to ban/IM/etc these users using the regular avatar picker. TODO: contact the UAS directly given a name of the form First.Last @foo.com. 2012-03-17 15:36:20 -07:00
Diva Canto 92b1ade78e BAD JUSTIN!
People using standalone in master, please update your StandaloneCommon.ini according to this change.
People using robust in master, please update your Robust.HG.ini.example[.HG].ini according to this change.
2012-03-17 15:01:10 -07:00
Diva Canto 1a4fdd2666 Moved HandleAvatarPickerRequest from the generic Scene.PacketHandlers to the UserManagementModule where it belongs. No functional changes. 2012-03-17 10:48:22 -07:00
Diva Canto d87a5758fb Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-17 10:00:43 -07:00
Diva Canto 33c14cb107 Region access control! Region operators can now specify things like DisallowForeigners (means what it says) and DisallowResidents (means that only admins and managers can get into the region). This puts the never-completed AuthorizationService to good use. Note that I didn't implement a grid-wide Authorization service; this service implementation is done entirely locally on the simulator. This can be changed as usual by pluging in a different AuthorizationServicesConnector. 2012-03-17 10:00:11 -07:00
Justin Clark-Casey (justincc) 4a57112f19 Add osGetInventoryDesc() as per http://opensimulator.org/mantis/view.php?id=5927
This allows one to get description data for a given prim inventory item.
Thanks MarcelEdward and GuduleLapointe!
2012-03-17 04:02:23 +00:00
Justin Clark-Casey (justincc) 1e4180fc93 Clean up "save iar" help 2012-03-17 02:54:19 +00:00
Diva Canto a4dca88a57 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-16 13:08:27 -07:00
Diva Canto a2009ffe2e Terrain: added [Terrain] section with an option to load an initial flat terrain. Default is still pinhead island. I much rather have a flat land in the beginning. 2012-03-16 13:08:05 -07:00
Justin Clark-Casey (justincc) 59b6f6a6e0 minor: reuse threadpool count we just fetched instead of fetching it again 2012-03-16 03:56:56 +00:00
Justin Clark-Casey (justincc) bece2023e7 Add total scripts count to "show threads"
However, this returns 0 on Mono (at least on 2.6.7)!  So not showing if it is zero.
2012-03-16 03:52:13 +00:00
Justin Clark-Casey (justincc) 9497a7c7bd refactor: separate out console and status report generation parts of XEngine 2012-03-16 03:32:14 +00:00
Justin Clark-Casey (justincc) 922d8c9312 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-16 03:28:17 +00:00
Justin Clark-Casey (justincc) 6e8f80f1ab Improve threadpool reporting to "show threads" console command (also gets printed out periodically) 2012-03-16 03:26:47 +00:00
Diva Canto 05bb2e4275 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-15 20:22:59 -07:00
Diva Canto 05a1493fff More on map search: send extra messages to the user regarding the region being found or not, because the UI is horribly confusing -- places profile is always "loading..." whether the region exists or not. 2012-03-15 20:22:26 -07:00
Justin Clark-Casey (justincc) 421b562a04 Add process working memory to "show stats" memory statistics.
This shows the actual amount of RAM being taken up by OpenSimulator (objects + vm overhead)
2012-03-16 02:43:33 +00:00
Justin Clark-Casey (justincc) 78e992dbd0 Move startup_commands.txt.example to startup_commands.txt for consistency with the existing shutdown_commands.txt.
Add comments to both files saying what they are (files that can contain console commands to execute on sim startup/shutdown) with an example.
2012-03-16 02:13:45 +00:00
Justin Clark-Casey (justincc) b19be657b6 Remove unnecessary "backup" command in shutdown_commands.txt
The simulator is already doing this internally.
2012-03-16 02:10:59 +00:00
Justin Clark-Casey (justincc) aa881e8065 Allow comments to appear in command scripts (e.g. shutdown_commands.txt).
These can start with ; # or //
2012-03-16 02:07:26 +00:00
Justin Clark-Casey (justincc) 34f6f87b6c Remove unused bin/ScriptEngines/Default.lsl
It would certainly be nice to change the default script on disk, but this is currently unused and isn't a suitable default.
At this location it would also stop an easy manual deletion of script engine compiles and state.
2012-03-16 01:51:16 +00:00
Justin Clark-Casey (justincc) 8550a4a07e In Top Scripts report, don't show scripts with no or less than 1 microsecond of execution time.
This is to make the report clearer and less confusing.
2012-03-16 01:46:21 +00:00
Justin Clark-Casey (justincc) c386b68373 Aggregate script execution times by linksets rather than individual prims.
This is for the top scripts report.
2012-03-16 01:31:53 +00:00
Justin Clark-Casey (justincc) 7df4a544fe Fix owner name display in "Top Colliders" and "Top Script" region reports. 2012-03-16 00:53:36 +00:00
Justin Clark-Casey (justincc) a4b01ef38a Replace script-lines-per-second with the script execution time scaled by its measurement period and an idealised frame time.
The previous lines-per-second measurement used for top scripts report was inaccurate, since lines executed does not reflect time taken to execute.
Also, every fetch of the report would reset all the numbers limiting its usefulness and we weren't even guaranteed to see the top 100.
The actual measurement value should be script execution time per frame but XEngine does not work this way.
Therefore, we use actual script execution time scaled by the measurement period and an idealised frame time.
This is still not ideal but gives reasonable results and allows scripts to be compared.
This commit moves script execution time calculations from SceneGraph into IScriptModule implementations.
2012-03-16 00:34:30 +00:00
Diva Canto 0548eeb571 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-15 16:03:33 -07:00
Diva Canto 18d1d6d3b4 More on SLURLs and V3. This is hacky, but it works. Basically, we have to redefine the encoding of HG URLs because the viewer messes them up. Examples of what works and doesn't work:
- secondlife://ucigrid00.nacs.uci.edu|8002/128/128 <-- works throughout the viewer
- secondlife://http|!!ucigrid00.nacs.uci.edu|8002+Test+Zone+1/128/128 <-- works throughout the viewer
- secondlife://http|!!grid.sciencesim.com!grid!hypergrid.php+Yellowstone01+74/128/128 <-- works throughout
- secondlife://http%3A%2F%2Fucigrid00.nacs.uci.edu%3A8002%20UCI%20Central%201/128/128 <-- works in chat, but not as URLs in the webkit
2012-03-15 16:03:09 -07:00
Diva Canto df144eb9e2 Revert "Revert "More hacking around viewer bug""
This reverts commit e5612553ce.
2012-03-15 14:55:25 -07:00
Diva Canto f52917288a These SLURLs are very confusing! -- reverting the revert. Hack is, indeed, needed.
Revert "Revert "Hack around https://jira.secondlife.com/browse/VWR-28570""

This reverts commit 5a9560db28.
2012-03-15 14:54:25 -07:00
Diva Canto 5a9560db28 Revert "Hack around https://jira.secondlife.com/browse/VWR-28570"
This reverts commit 697ac7fd9d.
2012-03-15 14:36:48 -07:00
Diva Canto e5612553ce Revert "More hacking around viewer bug"
This reverts commit 10731732b4.
2012-03-15 14:36:29 -07:00
Mic Bowman 8b5298a62e Protect the scriptmodulecomms interface. 2012-03-15 13:37:43 -07:00
Mic Bowman 402ff75d78 Adds a new script command 'modInvoke' to invoke registered functions
from region modules. The LSL translator is extended to generate the
modInvoke format of commands for directly inlined function calls.

A region module can register a function Test() with the name "Test".
LSL code can call that function as "Test()". The compiler will translate
that invocation into modInvoke("Test", ...)
2012-03-15 13:16:02 -07:00
Diva Canto fd4ad82367 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-15 11:06:08 -07:00
Diva Canto 10731732b4 More hacking around viewer bug 2012-03-15 11:05:43 -07:00
Diva Canto 697ac7fd9d Hack around https://jira.secondlife.com/browse/VWR-28570 2012-03-15 10:17:02 -07:00
Justin Clark-Casey (justincc) acb1355ff2 Remove property/field duplication in ScriptInstance where it's unnecessary. 2012-03-15 02:02:31 +00:00
Justin Clark-Casey (justincc) 2d32401e23 Simplify some logic in the ScriptInstance constructor - running is set to false in both if/else branches 2012-03-15 01:32:16 +00:00
Justin Clark-Casey (justincc) f0c1746063 minor: correct indentation levels 2012-03-15 01:26:38 +00:00
Justin Clark-Casey (justincc) 5ddda89238 Remove duplication of m_RunEvents and Running 2012-03-15 00:48:44 +00:00
Justin Clark-Casey (justincc) 2f81e53f63 Fix a problem where multiple near simultaneous calls to llDie() from multiple scripts in the same linkset can cause unnecessary thread aborts.
The first llDie() could lock Scene.m_deleting_scene_object.
The second llDie() would then wait at this lock.
The first llDie() would go on to remove the second script but always abort it since the second script's WorkItem would not go away.
Easiest solution here is to remove the m_deleting_scene_object since it's no longer justified - we no longer lock m_parts but take a copy instead.
This also requires an adjustment in XEngine.OnRemoveScript not to use instance.ObjectID instead when firing the OnObjectRemoved event.
2012-03-15 00:20:47 +00:00
Justin Clark-Casey (justincc) 12cebb12d5 Alleviate an issue where calling Thread.Abort() on script WorkItems can fail to release locks, resulting in a crippled simulator.
This seems to be a particular problem with ReaderWriterLockSlim, though other locks can be affected as well.
It has been seen to happen when llDie() is called in a linkset running more than one script.
Alleviation here means supplying a ScriptInstance.Stop() timeout of 1000ms rather than 0ms, to give events a chance to complete.
Also, we check the IsRunning status at the top of the ScriptInstance.EventProcessor() so that another event doesn't start in the mean time.
Ultimately, a better solution may have to be found since a long-running event would still exceed the timeout and be aborted.
2012-03-15 00:06:52 +00:00
Diva Canto d6dd3c42d1 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-13 20:16:19 -07:00
Diva Canto 479dd65a63 Teleports: bounce off repeated requests of teleporting the same agent. Some scripts do that, and that fails the whole thing. 2012-03-13 20:15:38 -07:00
Diva Canto 5a09572393 Minor sanity check on simulation agent handler (content type) 2012-03-13 20:14:51 -07:00
Justin Clark-Casey (justincc) 95ec96bf86 refactor: rename ScriptInstance.m_CurrentResult to m_CurrentWorkItem to make it more understandable as to what it is and what it does (hold a thread pool work item for a waiting of in-progress event)
Also add other various illustrative comments
2012-03-14 00:29:36 +00:00
Diva Canto 37828c9b9a Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-13 08:07:11 -07:00
Diva Canto 4eb2605c79 Datasnapshot: added "secret" to the registration/deregistration query so that data providers can verify authenticity if they want. 2012-03-13 08:06:30 -07:00
Justin Clark-Casey (justincc) 25592bbd85 Add max thread and min thread information to "xengine status" region console command 2012-03-12 21:16:05 +00:00
Robert Adams e0dd38f672 Rename the stream extension method WebUtil.CopyTo() to WebUtil.CopyStream().
.NET 4.0 added the method Stream.CopyTo(stream, bufferSize). For .NET 3.5
and before, WebUtil defined an extension method for Stream with the signature
Stream.CopyTo(stream, maxBytesToCopy). The meaning of the second parameter
is different in the two forms and depending on which compiler and/or
runtime you use, you could get one form or the other. Crashes ensue.
This change renames the WebUtil stream copy method to something that
cannot be confused with the new CopyTo method defined in .NET 4.0.
2012-03-12 10:07:04 -07:00
Melanie 1547fe959e Change OpenSim.ini.example to reflect how to actually enable prim limits,
as opposed to how it was first designed.
2012-03-12 16:06:35 +00:00
Diva Canto 13fb582c12 DataSnapshot: renamed gridserverURL to gatekeeperURL, and normalimzed the capitalization of 'name' to lower case, also in the same <grid> section. 2012-03-12 07:55:17 -07:00
Diva Canto 824eb7ed20 Added osGetGridGatekeeperURI() 2012-03-10 19:51:28 -08:00
Diva Canto 291dc39691 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-10 08:09:43 -08:00
Justin Clark-Casey (justincc) 05e821c444 Fix TestSaveOarNoAssets() by not launch a no-assets request on a separate thread.
This was previous behaviour anyway.
2012-03-10 03:11:28 +00:00
Justin Clark-Casey (justincc) 6e26f17923 minor: In IAR save, log when we start adding the control file rather than saying afterwards that we added it. 2012-03-10 02:13:17 +00:00
Justin Clark-Casey (justincc) 5507752dc5 minor: rearrange some save oar messages so they say what they're about to do rather than what they've just done. 2012-03-10 02:11:30 +00:00
Justin Clark-Casey (justincc) 1693799623 On OAR saving, try fetch assets serially rather than firing all the requests at the asset service at once.
This may (or may not) improve reliability for http://opensimulator.org/mantis/view.php?id=5898
Quick tests show that save time is the same.
2012-03-10 02:03:07 +00:00
Justin Clark-Casey (justincc) 3a5928f813 Add satguru and Fernando to contributors 2012-03-10 01:31:27 +00:00
Justin Clark-Casey (justincc) d6ebf2d6ca Add ability to specify a default estate to be used when creating regions.
This is configured in the new [Estates] section of OpenSim.ini.
If a default estate is configured then all new regions are automatically joined to it instead of asking the user.
If the default estate does not already exist then it is created.
Current default behaviour remains the same - the user is asked for estate details when necessary.
Thanks to Frenando Oliveira for the patch which I adapated further.
2012-03-10 01:27:05 +00:00
Mic Bowman 7b8e9d88e3 Serialize all web requests to a particular host:port pair; only applied to the PostToService variants. 2012-03-09 16:53:51 -08:00
Justin Clark-Casey (justincc) bdc968f1fc Factor out common default animations code into SLUtil. LLClientView now makes use of the SLUtil copy via a method rather than each LLClientView loading a separate copy.
As per opensim-users mailing list discussion.
2012-03-09 23:57:24 +00:00
Melanie 5c5a493791 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-03-09 22:59:23 +00:00
satguru srivastava 35f2479858 fix for NPC not playing internal animations 2012-03-09 22:58:59 +00:00
Diva Canto a58152bd2a More on inventory transfer hold ups:
- Added an inventory cache for caching root and system folders
- Synchronized the remote inventory connector, so that all the remote inventory calls are serialized
This will not make much difference in the hold ups. We'd have to move the FireAndForget high up to AddInventoryItem, but that opens up a can of worms regarding the notification of the recipient... the recipient would be notified of the offer before the items are effectively in his inventory, which could lead to surprises.
2012-03-09 12:59:24 -08:00
Diva Canto 81869c4a3f More on HG inventory transfers. Move the FireAndForget higher up. 2012-03-09 09:48:12 -08:00
Diva Canto f545d669de Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-08 19:32:21 -08:00
Diva Canto 7db5ba7702 More on the freeze on HG inventory transfers: spawn a threadlet on the functional asset posts so that the client threads doesn't freeze (but the network posts are serialized). 2012-03-08 19:31:53 -08:00
Justin Clark-Casey (justincc) 06dda14505 Simplify minimap coarse location code by just reference SP.AbsolutePosition
This is rather than checking whether the avatar is sitting and doing its own calculation.
2012-03-09 02:50:57 +00:00
Justin Clark-Casey (justincc) 205c36d3a4 Get rid of unnecessary ParentID == 0 check on SP.Get_AbsolutePosition since this is handled by the necessary ParentPart check 2012-03-09 02:44:08 +00:00
Justin Clark-Casey (justincc) 94e58ff6b9 Use SP.ParentPart instead of ParentID in places where it's more efficient (saving extra null checks, etc.)
However, it looks like we should retain SP.ParentID since it's much easier to use that in places where another thread could change ParentPart to null.
Otherwise one has to clumsily put ParentPart in a reference, etc. to avoid a race.
2012-03-09 02:38:11 +00:00
Justin Clark-Casey (justincc) b454326273 refactor: cleanup SP.HandleAgentSit so that everything is done within one if (part != null), rather than having unnecessary multiple checks 2012-03-09 02:33:48 +00:00
Diva Canto c22446ede0 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-08 18:29:08 -08:00
Diva Canto 8a34d1b710 HG inventory/asset transfers: serialize asset posts. I'm using the same pattern as suggested in the patch mantis #5921. Testing it in this smaller context to see how it works. 2012-03-08 18:28:46 -08:00
Justin Clark-Casey (justincc) 73c47f7205 Remove a race condition from SP.Set_AbsolutePosition where we assume the ParentPart is still not null if the ParentID != 0
Another thread could come in and stand the avatar between those two instructions.
2012-03-09 02:22:22 +00:00
Melanie 42a7a85062 FireAndForget scripted rez - port from Avination 2012-03-09 00:57:49 +00:00
Justin Clark-Casey (justincc) df4b06aed1 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-09 00:20:10 +00:00
Justin Clark-Casey (justincc) 034c9d6bcc Merge branch 'xassetservice' 2012-03-09 00:19:42 +00:00
Justin Clark-Casey (justincc) 3c5bd7c35a minor: move some compression related var setup inside compression if/then switch 2012-03-09 00:16:49 +00:00
Justin Clark-Casey (justincc) 0cbdf9dad2 Put big fat EXPERIMENTAL warning in xassetservice database plugin
This should not currently be used in any circumstances except for experimentation.
Database tables used by this plugin can still change at any time with no migration path.
2012-03-09 00:05:34 +00:00
Diva Canto 9c8ef96301 Fixes mantis #5923 2012-03-08 15:55:43 -08:00
Melanie 675d40357c Hold a ref to the prim we're sat on rather than querying scene each time
the check for significant is carried out. Prevents a deadlock condition.
2012-03-08 19:14:34 +00:00
Justin Clark-Casey (justincc) fa2a64564a Move "change region" command into general category 2012-03-08 02:24:37 +00:00
Justin Clark-Casey (justincc) dfdb0e140c Uses shorter AddCommand form for "show estates" 2012-03-08 02:23:52 +00:00
Justin Clark-Casey (justincc) 650d761c06 Display help commander topics in capitalized form - the commands themselves are still lowercase.
Also convert the estate commands to simply AddCommand() calls so that commands from two different modules can be placed in the same category
2012-03-08 02:17:45 +00:00
Justin Clark-Casey (justincc) 430304c176 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-08 01:59:00 +00:00
Justin Clark-Casey (justincc) 749c3fef8a Change "help" to display categories/module list then "help <category/module>" to display commands in a category.
This is to deal with the hundred lines of command splurge when one previously typed "help"
Modelled somewhat on the mysql console
One can still type help <command> to get per command help at any point.
Categories capitalized to avoid conflict with the all-lowercase commands (except for commander system, as of yet).
Does not affect command parsing or any other aspects of the console apart from the help system.
Backwards compatible with existing modules.
2012-03-08 01:51:37 +00:00
Justin Clark-Casey (justincc) 6bdea15ecf minor: make NPC tests run in a given order, comment out log lines in mock region data plugins, null out scene in script and npc torture tests, add other doc comments to torture tests 2012-03-07 01:11:37 +00:00
Melanie a1b28a61a6 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-03-07 01:04:09 +00:00
Melanie 7769362687 Always zero the PhysActor on dupes to prevent side effects on the orignal prim 2012-03-07 01:03:26 +00:00
Justin Clark-Casey (justincc) f3678d217f Stop individually deleting objects at the end of each ObjectTortureTest.
We can now do this since the entire scene and all objects within it are now successfully gc'd at the end of these tests.
This greatly improves the time taken to run each test (by reducing teardown time, not the time to actually do the test work that we're interested in).
Slightly simplifies config read in Scene constructor to help facilitate this.
2012-03-07 00:31:18 +00:00
Justin Clark-Casey (justincc) 23aba007dd Add documentation to make more explicit the difference between OnRezScript and OnNewScript in the event manager
OnNewScript fires when a script is added to a scene
OnRezScript fires when the script actually runs (i.e. after permission checks, state retrieval, etc.)
2012-03-07 00:04:24 +00:00
Justin Clark-Casey (justincc) 3376979923 Remove static m_MainInstance in LocalGridServiceConnector.
I believe this was originally required back when there could be two LocalGridServiceConnectors but this is no longer the case.
Having such statics makes performance testing much more difficult since they prevent GC of objects unless static references are explicitly nulled.
2012-03-06 23:51:50 +00:00
Justin Clark-Casey (justincc) 98251cdab3 Add sensor, dataserver requests, timer and listener counts to "xengine status" command.
This is for diagnostic purposes.
2012-03-06 23:21:17 +00:00
Justin Clark-Casey (justincc) e9d8eb5a27 Remove unnecessary explicit ElapsedEventHandler in SimReporter 2012-03-06 22:31:25 +00:00
Justin Clark-Casey (justincc) 0f4cdc0c5b Explictly close down the StatsReporter so that we can shutdown its timer
This is another step necessary for the scene to be garbage collected between performance tests
2012-03-06 19:05:32 +00:00
Justin Clark-Casey (justincc) b3449e998a Fix TestSyntaxError() and TestSyntaxErrorDeclaringVariableInForLoop()
They were all failing assertions but the exceptions these threw were caught as expected Exceptions.
I don't think we can easily distinguish these from the Exceptions that we're expecting.
So for now we'll do some messy manually checking with boolean setting instead.
This patch also corrects the assertions themselves.
2012-03-06 02:30:22 +00:00
Justin Clark-Casey (justincc) a92153ed88 Get all test methods in OpenSim.Region.ScriptEngine.Tests.dll to report that they're running 2012-03-06 02:21:19 +00:00
Justin Clark-Casey (justincc) 85198a45cb Fix off by one error in script error reporting. 2012-03-06 02:01:47 +00:00
Justin Clark-Casey (justincc) 1dc03e5c4f Simplify NPCModuleTests code by putting the NPCModule in an instance variable rather than making each test fetch it seperately.
Also rename instance variables in the test to conform to naming standards and for understandability
2012-03-06 01:47:43 +00:00
Justin Clark-Casey (justincc) d44b7c486a Go back to setting appearance directly in NPCModule.SetAppearance() to fix mantis 5914
The part reverted is from commit 2ebb421.
Unfortunately, IAvatarFactoryModule.SetAppearance() does not transfer attachments.
I'm not sure how to do this separately, unfortunately I'll need to leave it to Dan :)
Regression test added for this case.
Mantis ref: http://opensimulator.org/mantis/view.php?id=5914
2012-03-06 01:27:30 +00:00
Chris Hart 413bc1e77e Updates to MSSQL store for 0.7.3 to include:
* Telehub support
* Bugfix to Friends lookups
* Updates to Creator fields to store up to 255 characters for HG item creator storage
2012-03-06 00:27:49 +00:00
Justin Clark-Casey (justincc) 441449e240 Switch to sha256 from sha1 in order to avoid future asset hash collisions.
Some successful collision attacks have been carried out on sha1 with speculation that more are possible.
http://en.wikipedia.org/wiki/Cryptographic_hash_function#Cryptographic_hash_algorithms
No successful attacks have been shown on sha256, which makes it less likely that anybody will be able to engineer an asset hash collision in the future.
Tradeoff is more storage required for hashes, and more cpu to hash, though this is neglible compared to db operations and network access.
2012-03-06 00:14:21 +00:00
Justin Clark-Casey (justincc) fd2b285b1b remove unnecessary hash local variable 2012-03-05 23:50:41 +00:00
BlueWall ac934e2dbb Add WebProfiles config to other config example 2012-03-04 11:11:01 -05:00
BlueWall 33a154e446 Merge branch 'master' of /home/opensim/var/repo/opensim into v3_support 2012-03-04 10:42:37 -05:00
Justin Clark-Casey (justincc) 3780df8a32 Make asset compression optional. Currently set to false and not configurable from outside MySQLXAssetData. 2012-03-03 01:43:36 +00:00
Justin Clark-Casey (justincc) 75dc8b1aed Implement basic gzip compression for xassetdata
Whether this is worthwhile is debatable since here we are not transmitting data over a network
In addition, jpeg2000 (the biggest data hog) is already a compressed image format.
May not remain.
2012-03-03 01:28:58 +00:00
Justin Clark-Casey (justincc) 2535a4cafc If asset data already exists with the required hash then don't rewrite it 2012-03-03 00:05:02 +00:00
Justin Clark-Casey (justincc) 94b323d1d8 Perform asset storage transactionally 2012-03-02 23:41:54 +00:00
Justin Clark-Casey (justincc) 7113b44bdd Merge branch 'master' into xassetservice 2012-03-02 23:30:19 +00:00
Justin Clark-Casey (justincc) 98ad6ed255 comment out "[CAPS]: ScriptTaskInventory Request" log spam 2012-03-02 23:29:35 +00:00
Justin Clark-Casey (justincc) e81b3502ef Make xassetservice execute one query to retrieve the asset, not two 2012-03-02 23:26:03 +00:00
Justin Clark-Casey (justincc) c2c102d33e Remove outdated comment about checking attachment prims in Scene.PipeEventsForScript() 2012-03-02 22:52:26 +00:00
Justin Clark-Casey (justincc) 089fd61a3b Allow a script to receive events if its root prim is in an area where it's allowed to run rather than checking its own prim.
This allows scripts to run in child prims that are outside region boundaries.
This is an interim patch applied from http://opensimulator.org/mantis/view.php?id=5899 though it does not resolve that bug
Thanks tglion!
2012-03-02 22:43:24 +00:00
BlueWall d242d47e5c OpenID auth needs hashing before authenticating 2012-03-02 15:05:06 -05:00
BlueWall 6fc350725d Merge branch 'master' into v3_support 2012-03-02 15:02:09 -05:00
Dan Lake 64a036b4cf Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-03-02 09:19:35 -08:00
Dan Lake 8d249f8456 ScenePresence line endings and fix AllowMovement default to true. 2012-03-02 09:19:13 -08:00
Justin Clark-Casey (justincc) 6e3523e25e minor: remove mono compiler warning 2012-03-02 04:08:07 +00:00
Justin Clark-Casey (justincc) 2a2656f629 Merge branch 'master' into xassetservice 2012-03-02 04:01:53 +00:00
Justin Clark-Casey (justincc) be4199c3bc Make XAssetService a de-duplicating asset service.
This is an extremely crude implemenation which almost works by accident.  Nevertheless it does work.
It can be tested with the instructions at http://opensimulator.org/wiki/Feature_Proposals/Deduplicating_Asset_Service#Testing
It does not interact at all with the existing asset service or any data stored there.
This code is subject to change without notice and should not be used for anything other than gawking.
2012-03-02 03:57:55 +00:00
Diva Canto 8fccd2b555 Send the right name and creation date on the BasicProfileModule. 2012-03-01 19:55:51 -08:00
Dan Lake e8779cd9e5 In ScenePresence, removed several private variables used to store public parameters. They were only used by the get/set and make code harder to refactor. 2012-03-01 19:22:05 -08:00
Justin Clark-Casey (justincc) dd63cd1656 Start by adding XAssetService as a copy of the existing AssetService.
This is the start of exploring the creation of a bundled OpenSimulator asset service that does de-duplication and possibly file storage of assets.
Along the lines of coyled's SRAS, but not intended to replace, merely to act as a more performant bundled default.
Might end up nicking stuff from kcozen's patch at http://opensimulator.org/mantis/view.php?id=5429
More details at http://opensimulator.org/wiki/Feature_Proposals/Deduplicating_Asset_Service
Feedback and discussion welcome as commits are made.
2012-03-02 02:23:35 +00:00
Justin Clark-Casey (justincc) ec48a2f32b minor: Rename pCampbot console prompt to "pCampbot" rather than "Region" 2012-03-02 01:54:48 +00:00
Justin Clark-Casey (justincc) 94971bf3b9 Provide feedback on bot login states in pCampbot 2012-03-02 01:31:28 +00:00
Justin Clark-Casey (justincc) d8c4985527 Move SenseRepeaters.Count check inside the SenseRepeatListLock.
No methods in the List class are thread safe in the MS specification/documentation
2012-03-02 00:28:37 +00:00
Justin Clark-Casey (justincc) dcfd05c8ea lock SenseRepeatListLock when added a new sensor during script reconstitution.
This is already being done in the other place where a sensor is added.
Adding a sensor whilst another thread is iterating over the sensor list can cause a concurrency exception.
2012-03-02 00:22:23 +00:00
Mic Bowman 8a375f3c30 Adds an OSSL command for regular expression-based string replacement. Parameters
are osReplaceString(string source, string patter, string replace, integer count, integer start)
The count parameter specifies the total number of replacements to make, -1 makes
all replacements.
2012-03-01 14:49:49 -08:00
BlueWall 7a88d21e59 Merge branch 'master' of /home/opensim/src/opensim 2012-03-01 14:20:46 -05:00
BlueWall a2b0ed537e Fix indexing on string trim
Thanks to zadark for pointing this out,
	smxy for deciphering the ?: operator and
	Plugh for the fix \o/ yay for IRC
2012-03-01 14:18:48 -05:00
Justin Clark-Casey (justincc) 0007711eb5 Use a fully stubbed out MockConsole for unit tests rather than inheriting from CommandConsole.
This is so that the static MainConsole.Instance doesn't retain references to methods registered by scene and other modules to service commands.
This prevents the scene from being garbage collected at the end of a test.
This is not the final thing preventing GC - next up is the timer started by SimStatsReporter that holds a reference to Scene that prevents end of test gc.
2012-03-01 03:23:10 +00:00
Justin Clark-Casey (justincc) 255afbf08a Remove more now unused third party libraries. 2012-03-01 02:11:15 +00:00
Justin Clark-Casey (justincc) aabbbb32ff Flick master up to 0.7.4 2012-02-29 23:45:14 +00:00
Justin Clark-Casey (justincc) 1e95b01f13 Extend distsrc target to cleanup the files generated by running prebuild 2012-02-29 21:51:46 +00:00
BlueWall 69c999033b Revert "Fix authentication for OpenID provider"
This reverts commit 9f597c2d42. Fixing OpenID causes issues with other parts of the code.
2012-02-29 15:52:15 -05:00
BlueWall 1a54e76948 Trigger a build 2012-02-29 14:54:06 -05:00
BlueWall df75f5ae37 Merge branch 'master' of /home/opensim/src/opensim 2012-02-29 14:42:36 -05:00
BlueWall afc9a7d3f9 Merge branch 'master' of /home/opensim/src/opensim into v3_support 2012-02-29 14:39:51 -05:00
BlueWall 9f597c2d42 Fix authentication for OpenID provider 2012-02-29 14:39:07 -05:00
Justin Clark-Casey (justincc) a181fae722 Don't start pCampbot if the user doesn't supply bot firstname, lastname stub and password 2012-02-29 03:00:56 +00:00
Justin Clark-Casey (justincc) 40c838896c Use correct casing of RegionSettings.Sandbox in the various database modules.
MySQL and MSSQL have it as Sandbox, sqlite as sandbox.
In various different places in every plugin the wrong casing is used...
Consistency, who needs it?  Or one day sqlite can change to Sandbox.
2012-02-29 00:33:17 +00:00
Justin Clark-Casey (justincc) 670c7842a4 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-02-29 00:03:55 +00:00
Justin Clark-Casey (justincc) 2fce7dd593 Call Dispose() via using() on SqliteCommands in WebStatsModule after use. 2012-02-28 22:54:21 +00:00
Kevin Cozens a813e7ffdd Fixed two typos. White space cleanups.
Signed-off-by: nebadon <michael@osgrid.org>
2012-02-28 14:12:39 -07:00
Mic Bowman 4268427ac3 Some clean up in WebUtil, remove unused ServiceRequest function. 2012-02-27 15:15:03 -08:00
Diva Canto 142f8a4aec HG: Remove async in posting assets to foreign grid. Mono hates concurrency there. 2012-02-25 21:00:19 -08:00
BlueWall 4177571a78 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim into v3_support 2012-02-25 14:33:56 -05:00
PixelTomsen 01f454242d PRIM_SCULPT_FLAG_INVERT, PRIM_SCULPT_FLAG_MIRROR implemented
http://opensimulator.org/mantis/view.php?id=5763
2012-02-25 15:33:33 +00:00
Justin Clark-Casey (justincc) 4a5f9fe6a2 Move libopenjpeg native libraries into lib32 and lib64 as appropriate. 2012-02-25 04:26:32 +00:00
Justin Clark-Casey (justincc) 6159110258 Remove some more unused Bullet libraries. 2012-02-25 04:22:59 +00:00
Justin Clark-Casey (justincc) ca19b9078f Remove old libbulletnet native libraries. These are not used in the current generation bullet physics plugin. 2012-02-25 03:36:43 +00:00
Justin Clark-Casey (justincc) 6138662716 Move other sqlite and ode 32-bit and 64-bit libraries into lib32 or lib64 as appropriate. 2012-02-25 03:25:56 +00:00
Justin Clark-Casey (justincc) 3fbcd21916 Remove xunit.dll, Fadd.Globalization.Yaml.dll and Fadd.dll. It looks like these were once connected with HttpServer.dll but are now unused. 2012-02-25 03:12:41 +00:00
BlueWall af377470e1 Merge branch 'master' into v3_support 2012-02-22 22:29:30 -05:00
BlueWall 165ae251ec V3 Support
The V3 webapps need SSO capability and use OpenID. We need to send both our OpenID server url and a token for the user in the login response.
2012-02-22 16:36:28 -05:00
BlueWall 67bea681e2 Add web profile url setting to ini 2012-02-21 23:04:49 -05:00
BlueWall 7cf970fb27 V3 Support:
This starts V3 support by adding a profile server url to the login response. This requires viewer support - which is also being worked on.
2012-02-21 14:21:03 -05:00
304 changed files with 12075 additions and 3363 deletions
+18
View File
@@ -8,6 +8,24 @@
<copy file="bin/OpenSim.ini.example" tofile="bin/OpenSim.ini"/>
<copy file="bin/config-include/StandaloneCommon.ini.example" tofile="bin/config-include/StandaloneCommon.ini"/>
<copy file="bin/config-include/FlotsamCache.ini.example" tofile="bin/config-include/FlotsamCache.ini"/>
<!-- delete files generated by runprebuild.sh which had to be run in order to generate the build file for this target-->
<delete>
<fileset basedir="OpenSim">
<include name="**/*.build"/>
<include name="**/*.csproj*"/>
<include name="**/*.dll.build"/>
<include name="**/*.pidb"/>
<exclude name="Tools/OpenSim.32BitLaunch/**"/>
<exclude name="Tools/Robust.32BitLaunch/**"/>
<exclude name="Tools/LaunchSLClient/**"/>
</fileset>
</delete>
<delete>
<fileset>
<include name="OpenSim.build"/>
<include name="OpenSim.sln"/>
</fileset>
</delete>
</target>
<property name="distbindir" value="distbin" />
+6 -1
View File
@@ -1,4 +1,4 @@
The following people have contributed to OpenSim (Thank you
<<<>>>>The following people have contributed to OpenSim (Thank you
for your effort!)
= Current OpenSim Developers (in very rough order of appearance) =
@@ -71,6 +71,7 @@ what it is today.
* CharlieO
* ChrisDown
* Chris Yeoh (IBM)
* controlbreak
* coyled
* Daedius
* Dong Jun Lan (IBM)
@@ -86,8 +87,10 @@ what it is today.
* Grumly57
* GuduleLapointe
* Ewe Loon
* Fernando Oliveira
* Fly-Man
* Flyte Xevious
* Garmin Kawaguichi
* Imaze Rhiano
* Intimidated
* Jeremy Bongio (IBM)
@@ -106,6 +109,7 @@ what it is today.
* M.Igarashi
* maimedleech
* Mana Janus
* MarcelEdward
* Mic Bowman
* Michelle Argus
* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
@@ -135,6 +139,7 @@ what it is today.
* Ruud Lathorp
* SachaMagne
* Salahzar Stenvaag
* satguru p srivastava
* sempuki
* SignpostMarv
* SpotOn3D
@@ -135,7 +135,11 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
}
}
}
//[TODO]: Temporary fix for an issue after the mono-addis upgrade
// PostInilise can fire before the region is loaded, so need to
// track down the cause of that
Thread.Sleep(300);
m_openSim.ModuleLoader.PostInitialise();
m_openSim.ModuleLoader.ClearCache();
}
@@ -162,7 +162,7 @@ namespace OpenSim.Capabilities.Handlers
invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version);
if (inv.Folders != null)
if (inv != null && inv.Folders != null)
{
foreach (InventoryFolderBase invFolder in inv.Folders)
{
@@ -170,7 +170,7 @@ namespace OpenSim.Capabilities.Handlers
}
}
if (inv.Items != null)
if (inv != null && inv.Items != null)
{
foreach (InventoryItemBase invItem in inv.Items)
{
+1
View File
@@ -49,6 +49,7 @@ namespace OpenSim.Data
bool Store(PresenceData data);
PresenceData Get(UUID sessionID);
PresenceData Verify(UUID s_sessionID);
void LogoutRegionAgents(UUID regionID);
bool ReportAgent(UUID sessionID, UUID regionID);
PresenceData[] Get(string field, string data);
+47
View File
@@ -0,0 +1,47 @@
/*
* 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.Collections.Generic;
using OpenMetaverse;
using OpenSim.Framework;
namespace OpenSim.Data
{
/// <summary>
/// This interface exists to distinguish between the normal IAssetDataPlugin and the one used by XAssetService
/// for now.
/// </summary>
public interface IXAssetDataPlugin : IPlugin
{
AssetBase GetAsset(UUID uuid);
void StoreAsset(AssetBase asset);
bool ExistsAsset(UUID uuid);
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
void Initialise(string connect);
bool Delete(string id);
}
}
+6
View File
@@ -89,5 +89,11 @@ namespace OpenSim.Data.MSSQL
return DoQuery(cmd);
}
}
public FriendsData[] GetFriends(Guid principalID)
{
return GetFriends(principalID.ToString());
}
}
}
+1 -1
View File
@@ -813,7 +813,7 @@ namespace OpenSim.Data.MSSQL
{
try
{
using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID", connection))
using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID and type=-1", connection))
{
command.Parameters.Add(database.CreateParameter("folderID", folderID));
+5
View File
@@ -104,6 +104,11 @@ namespace OpenSim.Data.MSSQL
{
return SqlDbType.BigInt;
}
if (type == typeof(DateTime))
{
return SqlDbType.DateTime;
}
return SqlDbType.VarChar;
}
+11
View File
@@ -61,6 +61,17 @@ namespace OpenSim.Data.MSSQL
return ret[0];
}
public PresenceData Verify(UUID s_sessionID)
{
PresenceData[] ret = Get("SecureSessionID",
s_sessionID.ToString());
if (ret.Length == 0)
return null;
return ret[0];
}
public void LogoutRegionAgents(UUID regionID)
{
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
+80 -7
View File
@@ -675,7 +675,7 @@ VALUES
cmd.ExecuteNonQuery();
}
sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags]) VALUES (@LandUUID,@AccessUUID,@Flags)";
sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags],[Expires]) VALUES (@LandUUID,@AccessUUID,@Flags,@Expires)";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
@@ -1215,6 +1215,8 @@ VALUES
//Store new values
StoreNewRegionSettings(regionSettings);
LoadSpawnPoints(regionSettings);
return regionSettings;
}
@@ -1252,7 +1254,7 @@ VALUES
,[elevation_1_ne] = @elevation_1_ne ,[elevation_2_ne] = @elevation_2_ne ,[elevation_1_se] = @elevation_1_se ,[elevation_2_se] = @elevation_2_se
,[elevation_1_sw] = @elevation_1_sw ,[elevation_2_sw] = @elevation_2_sw ,[water_height] = @water_height ,[terrain_raise_limit] = @terrain_raise_limit
,[terrain_lower_limit] = @terrain_lower_limit ,[use_estate_sun] = @use_estate_sun ,[fixed_sun] = @fixed_sun ,[sun_position] = @sun_position
,[covenant] = @covenant ,[covenant_datetime] = @covenant_datetime, [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id
,[covenant] = @covenant ,[covenant_datetime] = @covenant_datetime, [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id, [map_tile_id] = @TerrainImageID, [telehubobject] = @telehubobject, [parcel_tile_id] = @ParcelImageID
WHERE [regionUUID] = @regionUUID";
using (SqlConnection conn = new SqlConnection(m_connectionString))
@@ -1263,6 +1265,7 @@ VALUES
cmd.ExecuteNonQuery();
}
}
SaveSpawnPoints(regionSettings);
}
public void Shutdown()
@@ -1367,7 +1370,7 @@ VALUES
newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]);
newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]);
newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]);
newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]);
newSettings.Sandbox = Convert.ToBoolean(row["Sandbox"]);
newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]);
newSettings.SunPosition = Convert.ToDouble(row["sun_position"]);
newSettings.SunVector = new Vector3(
@@ -1383,6 +1386,11 @@ VALUES
newSettings.LoadedCreationID = "";
else
newSettings.LoadedCreationID = (String)row["loaded_creation_id"];
newSettings.TerrainImageID = new UUID((string)row["map_tile_ID"]);
newSettings.ParcelImageID = new UUID((Guid)row["parcel_tile_ID"]);
newSettings.TelehubObject = new UUID((Guid)row["TelehubObject"]);
return newSettings;
}
@@ -1454,6 +1462,13 @@ VALUES
}
newData.ParcelAccessList = new List<LandAccessEntry>();
newData.MediaDescription = (string)row["MediaDescription"];
newData.MediaType = (string)row["MediaType"];
newData.MediaWidth = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[0]);
newData.MediaHeight = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[1]);
newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]);
newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]);
newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]);
return newData;
}
@@ -1468,7 +1483,7 @@ VALUES
LandAccessEntry entry = new LandAccessEntry();
entry.AgentID = new UUID((Guid)row["AccessUUID"]);
entry.Flags = (AccessList)Convert.ToInt32(row["Flags"]);
entry.Expires = 0;
entry.Expires = Convert.ToInt32(row["Expires"]);
return entry;
}
@@ -1497,7 +1512,8 @@ VALUES
prim.TouchName = (string)primRow["TouchName"];
// permissions
prim.Flags = (PrimFlags)Convert.ToUInt32(primRow["ObjectFlags"]);
prim.CreatorID = new UUID((Guid)primRow["CreatorID"]);
//prim.CreatorID = new UUID((Guid)primRow["CreatorID"]);
prim.CreatorIdentification = (string)primRow["CreatorID"];
prim.OwnerID = new UUID((Guid)primRow["OwnerID"]);
prim.GroupID = new UUID((Guid)primRow["GroupID"]);
prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]);
@@ -1691,7 +1707,8 @@ VALUES
taskItem.Name = (string)inventoryRow["name"];
taskItem.Description = (string)inventoryRow["description"];
taskItem.CreationDate = Convert.ToUInt32(inventoryRow["creationDate"]);
taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]);
//taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]);
taskItem.CreatorIdentification = (string)inventoryRow["creatorID"];
taskItem.OwnerID = new UUID((Guid)inventoryRow["ownerID"]);
taskItem.LastOwnerID = new UUID((Guid)inventoryRow["lastOwnerID"]);
taskItem.GroupID = new UUID((Guid)inventoryRow["groupID"]);
@@ -1782,7 +1799,7 @@ VALUES
parameters.Add(_Database.CreateParameter("terrain_raise_limit", settings.TerrainRaiseLimit));
parameters.Add(_Database.CreateParameter("terrain_lower_limit", settings.TerrainLowerLimit));
parameters.Add(_Database.CreateParameter("use_estate_sun", settings.UseEstateSun));
parameters.Add(_Database.CreateParameter("sandbox", settings.Sandbox));
parameters.Add(_Database.CreateParameter("Sandbox", settings.Sandbox));
parameters.Add(_Database.CreateParameter("fixed_sun", settings.FixedSun));
parameters.Add(_Database.CreateParameter("sun_position", settings.SunPosition));
parameters.Add(_Database.CreateParameter("sunvectorx", settings.SunVector.X));
@@ -1792,6 +1809,9 @@ VALUES
parameters.Add(_Database.CreateParameter("covenant_datetime", settings.CovenantChangedDateTime));
parameters.Add(_Database.CreateParameter("Loaded_Creation_DateTime", settings.LoadedCreationDateTime));
parameters.Add(_Database.CreateParameter("Loaded_Creation_ID", settings.LoadedCreationID));
parameters.Add(_Database.CreateParameter("TerrainImageID", settings.TerrainImageID));
parameters.Add(_Database.CreateParameter("ParcelImageID", settings.ParcelImageID));
parameters.Add(_Database.CreateParameter("TelehubObject", settings.TelehubObject));
return parameters.ToArray();
}
@@ -1859,6 +1879,7 @@ VALUES
parameters.Add(_Database.CreateParameter("LandUUID", parcelID));
parameters.Add(_Database.CreateParameter("AccessUUID", parcelAccessEntry.AgentID));
parameters.Add(_Database.CreateParameter("Flags", parcelAccessEntry.Flags));
parameters.Add(_Database.CreateParameter("Expires", parcelAccessEntry.Expires));
return parameters.ToArray();
}
@@ -2063,5 +2084,57 @@ VALUES
#endregion
#endregion
private void LoadSpawnPoints(RegionSettings rs)
{
rs.ClearSpawnPoints();
string sql = "SELECT Yaw, Pitch, Distance FROM spawn_points WHERE RegionUUID = @RegionUUID";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID.ToString()));
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
SpawnPoint sp = new SpawnPoint();
sp.Yaw = (float)reader["Yaw"];
sp.Pitch = (float)reader["Pitch"];
sp.Distance = (float)reader["Distance"];
rs.AddSpawnPoint(sp);
}
}
}
}
private void SaveSpawnPoints(RegionSettings rs)
{
string sql = "DELETE FROM spawn_points WHERE RegionUUID = @RegionUUID";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID));
conn.Open();
cmd.ExecuteNonQuery();
}
foreach (SpawnPoint p in rs.SpawnPoints())
{
sql = "INSERT INTO spawn_points (RegionUUID, Yaw, Pitch, Distance) VALUES (@RegionUUID, @Yaw, @Pitch, @Distance)";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID));
cmd.Parameters.Add(_Database.CreateParameter("@Yaw", p.Yaw));
cmd.Parameters.Add(_Database.CreateParameter("@Pitch", p.Pitch));
cmd.Parameters.Add(_Database.CreateParameter("@Distance", p.Distance));
conn.Open();
cmd.ExecuteNonQuery();
}
}
}
}
}
@@ -1044,10 +1044,93 @@ ALTER TABLE primitems ALTER COLUMN CreatorID uniqueidentifier NOT NULL
COMMIT
:VERSION 29 #---------------------
:VERSION 29 #----------------- Region Covenant changed time
BEGIN TRANSACTION
ALTER TABLE regionsettings ADD covenant_datetime int NOT NULL default 0
COMMIT
:VERSION 30 #------------------Migrate creatorID storage to varchars instead of UUIDs for HG support
BEGIN TRANSACTION
EXECUTE sp_rename N'dbo.prims.creatorid', N'creatoridold', 'COLUMN'
EXECUTE sp_rename N'dbo.primitems.creatorid', N'creatoridold', 'COLUMN'
COMMIT
:VERSION 31 #---------------------
BEGIN TRANSACTION
ALTER TABLE prims ADD CreatorID varchar(255)
ALTER TABLE primitems ADD CreatorID varchar(255)
COMMIT
:VERSION 32 #---------------------
BEGIN TRANSACTION
UPDATE prims SET prims.CreatorID = CONVERT(varchar(255), creatoridold)
UPDATE primitems SET primitems.CreatorID = CONVERT(varchar(255), creatoridold)
COMMIT
:VERSION 33 #---------------------
BEGIN TRANSACTION
ALTER TABLE prims
ADD CONSTRAINT DF_prims_CreatorIDNew
DEFAULT '00000000-0000-0000-0000-000000000000'
FOR CreatorID
ALTER TABLE prims ALTER COLUMN CreatorID varchar(255) NOT NULL
ALTER TABLE primitems
ADD CONSTRAINT DF_primitems_CreatorIDNew
DEFAULT '00000000-0000-0000-0000-000000000000'
FOR CreatorID
ALTER TABLE primitems ALTER COLUMN CreatorID varchar(255) NOT NULL
COMMIT
:VERSION 34 #--------------- Telehub support
BEGIN TRANSACTION
CREATE TABLE [dbo].[Spawn_Points](
[RegionUUID] [uniqueidentifier] NOT NULL,
[Yaw] [float] NOT NULL,
[Pitch] [float] NOT NULL,
[Distance] [float] NOT NULL,
PRIMARY KEY CLUSTERED
(
[RegionUUID] ASC
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE regionsettings ADD TelehubObject uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
COMMIT
:VERSION 35 #---------------- Parcels for sale
BEGIN TRANSACTION
ALTER TABLE regionsettings ADD parcel_tile_ID uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
COMMIT
:VERSION 36 #---------------- Timed bans/access
BEGIN TRANSACTION
ALTER TABLE landaccesslist ADD Expires integer NOT NULL DEFAULT 0;
COMMIT
+11
View File
@@ -61,6 +61,17 @@ namespace OpenSim.Data.MySQL
return ret[0];
}
public PresenceData Verify(UUID s_sessionID)
{
PresenceData[] ret = Get("SecureSessionID",
s_sessionID.ToString());
if (ret.Length == 0)
return null;
return ret[0];
}
public void LogoutRegionAgents(UUID regionID)
{
MySqlCommand cmd = new MySqlCommand();
+1 -1
View File
@@ -1283,7 +1283,7 @@ namespace OpenSim.Data.MySQL
newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]);
newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]);
newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]);
newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]);
newSettings.Sandbox = Convert.ToBoolean(row["Sandbox"]);
newSettings.SunVector = new Vector3 (
Convert.ToSingle(row["sunvectorx"]),
Convert.ToSingle(row["sunvectory"]),
+500
View File
@@ -0,0 +1,500 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using log4net;
using MySql.Data.MySqlClient;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Data;
namespace OpenSim.Data.MySQL
{
public class MySQLXAssetData : IXAssetDataPlugin
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected virtual Assembly Assembly
{
get { return GetType().Assembly; }
}
private bool m_enableCompression = false;
private string m_connectionString;
private object m_dbLock = new object();
/// <summary>
/// We can reuse this for all hashing since all methods are single-threaded through m_dbBLock
/// </summary>
private HashAlgorithm hasher = new SHA256CryptoServiceProvider();
#region IPlugin Members
public string Version { get { return "1.0.0.0"; } }
/// <summary>
/// <para>Initialises Asset interface</para>
/// <para>
/// <list type="bullet">
/// <item>Loads and initialises the MySQL storage plugin.</item>
/// <item>Warns and uses the obsolete mysql_connection.ini if connect string is empty.</item>
/// <item>Check for migration</item>
/// </list>
/// </para>
/// </summary>
/// <param name="connect">connect string</param>
public void Initialise(string connect)
{
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
m_log.ErrorFormat("[MYSQL XASSETDATA]: THIS PLUGIN IS STRICTLY EXPERIMENTAL.");
m_log.ErrorFormat("[MYSQL XASSETDATA]: DO NOT USE FOR ANY DATA THAT YOU DO NOT MIND LOSING.");
m_log.ErrorFormat("[MYSQL XASSETDATA]: DATABASE TABLES CAN CHANGE AT ANY TIME, CAUSING EXISTING DATA TO BE LOST.");
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
m_connectionString = connect;
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
Migration m = new Migration(dbcon, Assembly, "XAssetStore");
m.Update();
}
}
public void Initialise()
{
throw new NotImplementedException();
}
public void Dispose() { }
/// <summary>
/// The name of this DB provider
/// </summary>
public string Name
{
get { return "MySQL XAsset storage engine"; }
}
#endregion
#region IAssetDataPlugin Members
/// <summary>
/// Fetch Asset <paramref name="assetID"/> from database
/// </summary>
/// <param name="assetID">Asset UUID to fetch</param>
/// <returns>Return the asset</returns>
/// <remarks>On failure : throw an exception and attempt to reconnect to database</remarks>
public AssetBase GetAsset(UUID assetID)
{
// m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID);
AssetBase asset = null;
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(
"SELECT name, description, asset_type, local, temporary, asset_flags, creator_id, data FROM xassetsmeta JOIN xassetsdata ON xassetsmeta.hash = xassetsdata.hash WHERE id=?id",
dbcon))
{
cmd.Parameters.AddWithValue("?id", assetID.ToString());
try
{
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (dbReader.Read())
{
asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["asset_type"], dbReader["creator_id"].ToString());
asset.Data = (byte[])dbReader["data"];
asset.Description = (string)dbReader["description"];
string local = dbReader["local"].ToString();
if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
asset.Local = true;
else
asset.Local = false;
asset.Temporary = Convert.ToBoolean(dbReader["temporary"]);
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
if (m_enableCompression)
{
using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress))
{
MemoryStream outputStream = new MemoryStream();
WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue);
// int compressedLength = asset.Data.Length;
asset.Data = outputStream.ToArray();
// m_log.DebugFormat(
// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}",
// asset.ID, asset.Name, asset.Data.Length, compressedLength);
}
}
}
}
}
catch (Exception e)
{
m_log.Error("[MYSQL XASSET DATA]: MySql failure fetching asset " + assetID + ": " + e.Message);
}
}
}
}
return asset;
}
/// <summary>
/// Create an asset in database, or update it if existing.
/// </summary>
/// <param name="asset">Asset UUID to create</param>
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
public void StoreAsset(AssetBase asset)
{
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlTransaction transaction = dbcon.BeginTransaction())
{
string assetName = asset.Name;
if (asset.Name.Length > 64)
{
assetName = asset.Name.Substring(0, 64);
m_log.Warn("[XASSET DB]: Name field truncated from " + asset.Name.Length + " to " + assetName.Length + " characters on add");
}
string assetDescription = asset.Description;
if (asset.Description.Length > 64)
{
assetDescription = asset.Description.Substring(0, 64);
m_log.Warn("[XASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add");
}
if (m_enableCompression)
{
MemoryStream outputStream = new MemoryStream();
using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress, false))
{
// Console.WriteLine(WebUtil.CopyTo(new MemoryStream(asset.Data), compressionStream, int.MaxValue));
// We have to close the compression stream in order to make sure it writes everything out to the underlying memory output stream.
compressionStream.Close();
byte[] compressedData = outputStream.ToArray();
asset.Data = compressedData;
}
}
byte[] hash = hasher.ComputeHash(asset.Data);
// m_log.DebugFormat(
// "[XASSET DB]: Compressed data size for {0} {1}, hash {2} is {3}",
// asset.ID, asset.Name, hash, compressedData.Length);
try
{
using (MySqlCommand cmd =
new MySqlCommand(
"replace INTO xassetsmeta(id, hash, name, description, asset_type, local, temporary, create_time, access_time, asset_flags, creator_id)" +
"VALUES(?id, ?hash, ?name, ?description, ?asset_type, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?creator_id)",
dbcon))
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?hash", hash);
cmd.Parameters.AddWithValue("?name", assetName);
cmd.Parameters.AddWithValue("?description", assetDescription);
cmd.Parameters.AddWithValue("?asset_type", asset.Type);
cmd.Parameters.AddWithValue("?local", asset.Local);
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
cmd.Parameters.AddWithValue("?create_time", now);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.Parameters.AddWithValue("?creator_id", asset.Metadata.CreatorID);
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset metadata {0} with name \"{1}\". Error: {2}",
asset.FullID, asset.Name, e.Message);
transaction.Rollback();
return;
}
if (!ExistsData(dbcon, transaction, hash))
{
try
{
using (MySqlCommand cmd =
new MySqlCommand(
"INSERT INTO xassetsdata(hash, data) VALUES(?hash, ?data)",
dbcon))
{
cmd.Parameters.AddWithValue("?hash", hash);
cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.ErrorFormat("[XASSET DB]: MySQL failure creating asset data {0} with name \"{1}\". Error: {2}",
asset.FullID, asset.Name, e.Message);
transaction.Rollback();
return;
}
}
transaction.Commit();
}
}
}
}
// private void UpdateAccessTime(AssetBase asset)
// {
// lock (m_dbLock)
// {
// using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
// {
// dbcon.Open();
// MySqlCommand cmd =
// new MySqlCommand("update assets set access_time=?access_time where id=?id",
// dbcon);
//
// // need to ensure we dispose
// try
// {
// using (cmd)
// {
// // create unix epoch time
// int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
// cmd.Parameters.AddWithValue("?id", asset.ID);
// cmd.Parameters.AddWithValue("?access_time", now);
// cmd.ExecuteNonQuery();
// cmd.Dispose();
// }
// }
// catch (Exception e)
// {
// m_log.ErrorFormat(
// "[ASSETS DB]: " +
// "MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString()
// + Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name);
// }
// }
// }
//
// }
/// <summary>
/// We assume we already have the m_dbLock.
/// </summary>
/// TODO: need to actually use the transaction.
/// <param name="dbcon"></param>
/// <param name="transaction"></param>
/// <param name="hash"></param>
/// <returns></returns>
private bool ExistsData(MySqlConnection dbcon, MySqlTransaction transaction, byte[] hash)
{
// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
bool exists = false;
using (MySqlCommand cmd = new MySqlCommand("SELECT hash FROM xassetsdata WHERE hash=?hash", dbcon))
{
cmd.Parameters.AddWithValue("?hash", hash);
try
{
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (dbReader.Read())
{
// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
exists = true;
}
}
}
catch (Exception e)
{
m_log.ErrorFormat(
"[XASSETS DB]: MySql failure in ExistsData fetching hash {0}. Exception {1}{2}",
hash, e.Message, e.StackTrace);
}
}
return exists;
}
/// <summary>
/// Check if the asset exists in the database
/// </summary>
/// <param name="uuid">The asset UUID</param>
/// <returns>true if it exists, false otherwise.</returns>
public bool ExistsAsset(UUID uuid)
{
// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
bool assetExists = false;
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))
{
cmd.Parameters.AddWithValue("?id", uuid.ToString());
try
{
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (dbReader.Read())
{
// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
assetExists = true;
}
}
}
catch (Exception e)
{
m_log.ErrorFormat(
"[XASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString(), uuid);
}
}
}
}
return assetExists;
}
/// <summary>
/// Returns a list of AssetMetadata objects. The list is a subset of
/// the entire data set offset by <paramref name="start" /> containing
/// <paramref name="count" /> elements.
/// </summary>
/// <param name="start">The number of results to discard from the total data set.</param>
/// <param name="count">The number of rows the returned list should contain.</param>
/// <returns>A list of AssetMetadata objects.</returns>
public List<AssetMetadata> FetchAssetMetadataSet(int start, int count)
{
List<AssetMetadata> retList = new List<AssetMetadata>(count);
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand("SELECT name,description,asset_type,temporary,id,asset_flags,creator_id FROM xassetsmeta LIMIT ?start, ?count", dbcon);
cmd.Parameters.AddWithValue("?start", start);
cmd.Parameters.AddWithValue("?count", count);
try
{
using (MySqlDataReader dbReader = cmd.ExecuteReader())
{
while (dbReader.Read())
{
AssetMetadata metadata = new AssetMetadata();
metadata.Name = (string)dbReader["name"];
metadata.Description = (string)dbReader["description"];
metadata.Type = (sbyte)dbReader["asset_type"];
metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct.
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
metadata.FullID = DBGuid.FromDB(dbReader["id"]);
metadata.CreatorID = dbReader["creator_id"].ToString();
// We'll ignore this for now - it appears unused!
// metadata.SHA1 = dbReader["hash"]);
retList.Add(metadata);
}
}
}
catch (Exception e)
{
m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
}
}
}
return retList;
}
public bool Delete(string id)
{
// m_log.DebugFormat("[XASSETS DB]: Deleting asset {0}", id);
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand("delete from xassetsmeta where id=?id", dbcon))
{
cmd.Parameters.AddWithValue("?id", id);
cmd.ExecuteNonQuery();
}
// TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we
// keep a reference count (?)
}
}
return true;
}
#endregion
}
}
@@ -0,0 +1,27 @@
# -----------------
:VERSION 1
BEGIN;
CREATE TABLE `xassetsmeta` (
`id` char(36) NOT NULL,
`hash` binary(32) NOT NULL,
`name` varchar(64) NOT NULL,
`description` varchar(64) NOT NULL,
`asset_type` tinyint(4) NOT NULL,
`local` tinyint(1) NOT NULL,
`temporary` tinyint(1) NOT NULL,
`create_time` int(11) NOT NULL,
`access_time` int(11) NOT NULL,
`asset_flags` int(11) NOT NULL,
`creator_id` varchar(128) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Version 1';
CREATE TABLE `xassetsdata` (
`hash` binary(32) NOT NULL,
`data` longblob NOT NULL,
PRIMARY KEY (`hash`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Version 1';
COMMIT;
+56 -18
View File
@@ -28,6 +28,9 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Data;
@@ -36,12 +39,26 @@ namespace OpenSim.Data.Null
{
public class NullFriendsData : IFriendsData
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static List<FriendsData> m_Data = new List<FriendsData>();
public NullFriendsData(string connectionString, string realm)
{
}
/// <summary>
/// Clear all friends data
/// </summary>
/// <remarks>
/// This is required by unit tests to clear the static data between test runs.
/// </remarks>
public static void Clear()
{
lock (m_Data)
m_Data.Clear();
}
public FriendsData[] GetFriends(UUID principalID)
{
return GetFriends(principalID.ToString());
@@ -56,20 +73,30 @@ namespace OpenSim.Data.Null
/// <returns></returns>
public FriendsData[] GetFriends(string userID)
{
List<FriendsData> lst = m_Data.FindAll(fdata =>
lock (m_Data)
{
return fdata.PrincipalID == userID.ToString();
});
if (lst != null)
{
lst.ForEach(f =>
List<FriendsData> lst = m_Data.FindAll(fdata =>
{
FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID);
if (f2 != null) { f.Data["TheirFlags"] = f2.Data["Flags"]; }
return fdata.PrincipalID == userID.ToString();
});
return lst.ToArray();
if (lst != null)
{
lst.ForEach(f =>
{
FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID);
if (f2 != null)
f.Data["TheirFlags"] = f2.Data["Flags"];
// m_log.DebugFormat(
// "[NULL FRIENDS DATA]: Got {0} {1} {2} for {3}",
// f.Friend, f.Data["Flags"], f2 != null ? f.Data["TheirFlags"] : "not found!", f.PrincipalID);
});
// m_log.DebugFormat("[NULL FRIENDS DATA]: Got {0} friends for {1}", lst.Count, userID);
return lst.ToArray();
}
}
return new FriendsData[0];
@@ -80,7 +107,11 @@ namespace OpenSim.Data.Null
if (data == null)
return false;
m_Data.Add(data);
// m_log.DebugFormat(
// "[NULL FRIENDS DATA]: Storing {0} {1} {2}", data.PrincipalID, data.Friend, data.Data["Flags"]);
lock (m_Data)
m_Data.Add(data);
return true;
}
@@ -92,14 +123,21 @@ namespace OpenSim.Data.Null
public bool Delete(string userID, string friendID)
{
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
if (lst != null)
lock (m_Data)
{
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
if (friendID != null)
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
if (lst != null)
{
m_Data.Remove(friend);
return true;
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
if (friendID != null)
{
// m_log.DebugFormat(
// "[NULL FRIENDS DATA]: Deleting friend {0} {1} for {2}",
// friend.Friend, friend.Data["Flags"], friend.PrincipalID);
m_Data.Remove(friend);
return true;
}
}
}
+13 -1
View File
@@ -79,6 +79,19 @@ namespace OpenSim.Data.Null
return null;
}
public PresenceData Verify(UUID s_sessionID)
{
if (Instance != this)
return Instance.Verify(s_sessionID);
if (m_presenceData.ContainsKey(s_sessionID))
{
return m_presenceData[s_sessionID];
}
return null;
}
public void LogoutRegionAgents(UUID regionID)
{
if (Instance != this)
@@ -110,7 +123,6 @@ namespace OpenSim.Data.Null
return false;
}
public PresenceData[] Get(string field, string data)
{
if (Instance != this)
+1 -1
View File
@@ -2157,7 +2157,7 @@ namespace OpenSim.Data.SQLite
row["terrain_raise_limit"] = settings.TerrainRaiseLimit;
row["terrain_lower_limit"] = settings.TerrainLowerLimit;
row["use_estate_sun"] = settings.UseEstateSun;
row["Sandbox"] = settings.Sandbox; // database uses upper case S for sandbox
row["sandbox"] = settings.Sandbox; // unlike other database modules, sqlite uses a lower case s for sandbox!
row["sunvectorx"] = settings.SunVector.X;
row["sunvectory"] = settings.SunVector.Y;
row["sunvectorz"] = settings.SunVector.Z;
+4 -4
View File
@@ -244,10 +244,10 @@ namespace OpenSim.Data.Tests
SceneObjectPart[] newparts = newsog.Parts;
Assert.That(newparts.Length,Is.EqualTo(4), "Assert.That(newparts.Length,Is.EqualTo(4))");
Assert.That(newsog.HasChildPrim(tmp0), "Assert.That(newsog.HasChildPrim(tmp0))");
Assert.That(newsog.HasChildPrim(tmp1), "Assert.That(newsog.HasChildPrim(tmp1))");
Assert.That(newsog.HasChildPrim(tmp2), "Assert.That(newsog.HasChildPrim(tmp2))");
Assert.That(newsog.HasChildPrim(tmp3), "Assert.That(newsog.HasChildPrim(tmp3))");
Assert.That(newsog.ContainsPart(tmp0), "Assert.That(newsog.ContainsPart(tmp0))");
Assert.That(newsog.ContainsPart(tmp1), "Assert.That(newsog.ContainsPart(tmp1))");
Assert.That(newsog.ContainsPart(tmp2), "Assert.That(newsog.ContainsPart(tmp2))");
Assert.That(newsog.ContainsPart(tmp3), "Assert.That(newsog.ContainsPart(tmp3))");
}
[Test]
@@ -0,0 +1,40 @@
/*
* 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 OpenMetaverse;
using OpenSim.Framework;
namespace OpenSim.Framework.Client
{
public interface IClientInventory
{
void SendRemoveInventoryFolders(UUID[] folders);
void SendRemoveInventoryItems(UUID[] folders);
void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items);
}
}
+97 -25
View File
@@ -29,6 +29,7 @@ using System;
using System.Xml;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
@@ -40,6 +41,8 @@ namespace OpenSim.Framework.Console
{
public class Commands : ICommands
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Encapsulates a command that can be invoked from the console
/// </summary>
@@ -76,12 +79,19 @@ namespace OpenSim.Framework.Console
public List<CommandDelegate> fn;
}
public const string GeneralHelpText = "For more information, type 'help <item>' where <item> is one of the following categories:";
/// <value>
/// Commands organized by keyword in a tree
/// </value>
private Dictionary<string, object> tree =
new Dictionary<string, object>();
/// <summary>
/// Commands organized by module
/// </summary>
private Dictionary<string, List<CommandInfo>> m_modulesCommands = new Dictionary<string, List<CommandInfo>>();
/// <summary>
/// Get help for the given help string
/// </summary>
@@ -98,8 +108,8 @@ namespace OpenSim.Framework.Console
// General help
if (helpParts.Count == 0)
{
help.AddRange(CollectHelp(tree));
help.Sort();
help.Add(GeneralHelpText);
help.AddRange(CollectModulesHelp(tree));
}
else
{
@@ -118,6 +128,13 @@ namespace OpenSim.Framework.Console
{
string originalHelpRequest = string.Join(" ", helpParts.ToArray());
List<string> help = new List<string>();
// Check modules first to see if we just need to display a list of those commands
if (TryCollectModuleHelp(originalHelpRequest, help))
{
help.Insert(0, GeneralHelpText);
return help;
}
Dictionary<string, object> dict = tree;
while (helpParts.Count > 0)
@@ -161,25 +178,63 @@ namespace OpenSim.Framework.Console
return help;
}
private List<string> CollectHelp(Dictionary<string, object> dict)
/// <summary>
/// Try to collect help for the given module if that module exists.
/// </summary>
/// <param name="moduleName"></param>
/// <param name="helpText">/param>
/// <returns>true if there was the module existed, false otherwise.</returns>
private bool TryCollectModuleHelp(string moduleName, List<string> helpText)
{
List<string> result = new List<string>();
foreach (KeyValuePair<string, object> kvp in dict)
lock (m_modulesCommands)
{
if (kvp.Value is Dictionary<string, Object>)
foreach (string key in m_modulesCommands.Keys)
{
result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value));
}
else
{
if (((CommandInfo)kvp.Value).long_help != String.Empty)
result.Add(((CommandInfo)kvp.Value).help_text+" - "+
((CommandInfo)kvp.Value).long_help);
// Allow topic help requests to succeed whether they are upper or lowercase.
if (moduleName.ToLower() == key.ToLower())
{
List<CommandInfo> commands = m_modulesCommands[key];
var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help));
ourHelpText.Sort();
helpText.AddRange(ourHelpText);
return true;
}
}
return false;
}
return result;
}
private List<string> CollectModulesHelp(Dictionary<string, object> dict)
{
lock (m_modulesCommands)
{
List<string> helpText = new List<string>(m_modulesCommands.Keys);
helpText.Sort();
return helpText;
}
}
// private List<string> CollectHelp(Dictionary<string, object> dict)
// {
// List<string> result = new List<string>();
//
// foreach (KeyValuePair<string, object> kvp in dict)
// {
// if (kvp.Value is Dictionary<string, Object>)
// {
// result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value));
// }
// else
// {
// if (((CommandInfo)kvp.Value).long_help != String.Empty)
// result.Add(((CommandInfo)kvp.Value).help_text+" - "+
// ((CommandInfo)kvp.Value).long_help);
// }
// }
// return result;
// }
/// <summary>
/// Add a command to those which can be invoked from the console.
@@ -212,21 +267,19 @@ namespace OpenSim.Framework.Console
Dictionary<string, Object> current = tree;
foreach (string s in parts)
foreach (string part in parts)
{
if (current.ContainsKey(s))
if (current.ContainsKey(part))
{
if (current[s] is Dictionary<string, Object>)
{
current = (Dictionary<string, Object>)current[s];
}
if (current[part] is Dictionary<string, Object>)
current = (Dictionary<string, Object>)current[part];
else
return;
}
else
{
current[s] = new Dictionary<string, Object>();
current = (Dictionary<string, Object>)current[s];
current[part] = new Dictionary<string, Object>();
current = (Dictionary<string, Object>)current[part];
}
}
@@ -250,6 +303,24 @@ namespace OpenSim.Framework.Console
info.fn = new List<CommandDelegate>();
info.fn.Add(fn);
current[String.Empty] = info;
// Now add command to modules dictionary
lock (m_modulesCommands)
{
List<CommandInfo> commands;
if (m_modulesCommands.ContainsKey(module))
{
commands = m_modulesCommands[module];
}
else
{
commands = new List<CommandInfo>();
m_modulesCommands[module] = commands;
}
// m_log.DebugFormat("[COMMAND CONSOLE]: Adding to category {0} command {1}", module, command);
commands.Add(info);
}
}
public string[] FindNextOption(string[] cmd, bool term)
@@ -607,8 +678,9 @@ namespace OpenSim.Framework.Console
{
Commands = new Commands();
Commands.AddCommand("console", false, "help", "help [<command>]",
"Get general command list or more detailed help on a specific command", Help);
Commands.AddCommand(
"Help", false, "help", "help [<item>]",
"Display help on a particular command or on a list of commands in a category", Help);
}
private void Help(string module, string[] cmd)
+37 -22
View File
@@ -29,6 +29,7 @@ using System;
using System.Threading;
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace OpenSim.Framework.Console
{
@@ -37,28 +38,42 @@ namespace OpenSim.Framework.Console
/// Don't use this except for Unit Testing or you're in for a world of hurt when the
/// sim gets to ReadLine
/// </summary>
public class MockConsole : CommandConsole
public class MockConsole : ICommandConsole
{
public MockConsole(string defaultPrompt) : base(defaultPrompt)
{
}
public override void Output(string text)
{
}
public override void Output(string text, string level)
{
}
private MockCommands m_commands = new MockCommands();
public override string ReadLine(string p, bool isCommand, bool e)
{
//Thread.CurrentThread.Join(1000);
return string.Empty;
}
public override void UnlockOutput()
{
}
public override void LockOutput()
{
}
public ICommands Commands { get { return m_commands; } }
public void Prompt() {}
public void RunCommand(string cmd) {}
public string ReadLine(string p, bool isCommand, bool e) { return ""; }
public object ConsoleScene { get { return null; } }
public void Output(string text, string level) {}
public void Output(string text) {}
public void OutputFormat(string format, params object[] components) {}
public string CmdPrompt(string p) { return ""; }
public string CmdPrompt(string p, string def) { return ""; }
public string CmdPrompt(string p, List<char> excludedCharacters) { return ""; }
public string CmdPrompt(string p, string def, List<char> excludedCharacters) { return ""; }
public string CmdPrompt(string prompt, string defaultresponse, List<string> options) { return ""; }
public string PasswdPrompt(string p) { return ""; }
}
}
public class MockCommands : ICommands
{
public void FromXml(XmlElement root, CommandDelegate fn) {}
public List<string> GetHelp(string[] cmd) { return null; }
public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn) {}
public void AddCommand(string module, bool shared, string command, string help, string longhelp, string descriptivehelp, CommandDelegate fn) {}
public string[] FindNextOption(string[] cmd, bool term) { return null; }
public string[] Resolve(string[] cmd) { return null; }
public XmlElement GetXml(XmlDocument doc) { return null; }
}
}
+62
View File
@@ -0,0 +1,62 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using log4net;
public class GcNotify
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public static bool Enabled
{
get { return s_initialized; }
set
{
if (!s_initialized && value)
new GcNotify();
s_initialized = value;
}
}
private static bool s_initialized = false;
private GcNotify() {}
~GcNotify()
{
if (!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload())
{
m_log.DebugFormat("[GC NOTIFY]: Garbage collection triggered.");
if (Enabled)
new GcNotify();
}
}
}
+5 -6
View File
@@ -296,9 +296,9 @@ namespace OpenSim.Framework
public delegate void ConfirmXfer(IClientAPI remoteClient, ulong xferID, uint packetID);
public delegate void FriendActionDelegate(
IClientAPI remoteClient, UUID agentID, UUID transactionID, List<UUID> callingCardFolders);
IClientAPI remoteClient, UUID transactionID, List<UUID> callingCardFolders);
public delegate void FriendshipTermination(IClientAPI remoteClient, UUID agentID, UUID ExID);
public delegate void FriendshipTermination(IClientAPI remoteClient, UUID ExID);
public delegate void MoneyTransferRequest(
UUID sourceID, UUID destID, int amount, int transactionType, string description);
@@ -458,7 +458,7 @@ namespace OpenSim.Framework
public delegate void AvatarNotesUpdate(IClientAPI client, UUID targetID, string notes);
public delegate void MuteListRequest(IClientAPI client, uint muteCRC);
public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages);
public delegate void GrantUserFriendRights(IClientAPI client, UUID requester, UUID target, int rights);
public delegate void GrantUserFriendRights(IClientAPI client, UUID target, int rights);
public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client);
public delegate void AgentFOV(IClientAPI client, float verticalAngle);
@@ -710,7 +710,7 @@ namespace OpenSim.Framework
/// The scene agent for this client. This will only be set if the client has an agent in a scene (i.e. if it
/// is connected).
/// </summary>
ISceneAgent SceneAgent { get; }
ISceneAgent SceneAgent { get; set; }
UUID SessionId { get; }
@@ -1215,10 +1215,9 @@ namespace OpenSim.Framework
/// <param name="OrbitalPosition">The orbital position is given in radians, and must be "adjusted" for the linden client, see LLClientView</param>
void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear,
float OrbitalPosition);
void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks);
void SendViewerTime(int phase);
UUID GetDefaultAnimation(string name);
void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember, string flAbout,
uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID);
+1 -1
View File
@@ -40,7 +40,7 @@ namespace OpenSim.Framework
/// <summary>
/// Get help for the given help string
/// </summary>
/// <param name="helpParts">Parsed parts of the help string. If empty then general help is returned.</param>
/// <param name="cmd">Parsed parts of the help string. If empty then general help is returned.</param>
/// <returns></returns>
List<string> GetHelp(string[] cmd);
+1
View File
@@ -71,6 +71,7 @@ namespace OpenSim.Framework
bool IsEitherBannedOrRestricted(UUID avatar);
bool IsBannedFromLand(UUID avatar);
bool IsRestrictedFromLand(UUID avatar);
bool IsInLandAccessList(UUID avatar);
void SendLandUpdateToClient(IClientAPI remote_client);
void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client);
List<LandAccessEntry> CreateAccessListArrayByFlag(AccessList flag);
+1 -1
View File
@@ -69,7 +69,7 @@ namespace OpenSim.Framework
(uint) ParcelFlags.AllowAPrimitiveEntry |
(uint) ParcelFlags.AllowDeedToGroup | (uint) ParcelFlags.AllowTerraform |
(uint) ParcelFlags.CreateObjects | (uint) ParcelFlags.AllowOtherScripts |
(uint) ParcelFlags.SoundLocal;
(uint) ParcelFlags.SoundLocal | (uint) ParcelFlags.AllowVoiceChat;
private byte _landingType = 0;
private string _name = "Your Parcel";
+1 -1
View File
@@ -119,7 +119,7 @@ namespace OpenSim.Framework
// Copy the temporary stream to the network stream
formDataStream.Seek(0, SeekOrigin.Begin);
using (Stream requestStream = request.GetRequestStream())
formDataStream.CopyTo(requestStream, (int)formDataStream.Length);
formDataStream.CopyStream(requestStream, (int)formDataStream.Length);
}
#endregion Stream Writing
+6
View File
@@ -421,12 +421,18 @@ namespace OpenSim.Framework
set { m_internalEndPoint = value; }
}
/// <summary>
/// The x co-ordinate of this region in map tiles (e.g. 1000).
/// </summary>
public uint RegionLocX
{
get { return m_regionLocX.Value; }
set { m_regionLocX = value; }
}
/// <summary>
/// The y co-ordinate of this region in map tiles (e.g. 1000).
/// </summary>
public uint RegionLocY
{
get { return m_regionLocY.Value; }
+3 -1
View File
@@ -27,7 +27,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Xml;
using log4net;
using OpenMetaverse;
@@ -375,4 +377,4 @@ namespace OpenSim.Framework
return output;
}
}
}
}
+20 -16
View File
@@ -161,43 +161,43 @@ namespace OpenSim.Framework.Servers
Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
}
m_console.Commands.AddCommand("base", false, "quit",
m_console.Commands.AddCommand("General", false, "quit",
"quit",
"Quit the application", HandleQuit);
m_console.Commands.AddCommand("base", false, "shutdown",
m_console.Commands.AddCommand("General", false, "shutdown",
"shutdown",
"Quit the application", HandleQuit);
m_console.Commands.AddCommand("base", false, "set log level",
m_console.Commands.AddCommand("General", false, "set log level",
"set log level <level>",
"Set the console logging level", HandleLogLevel);
m_console.Commands.AddCommand("base", false, "show info",
m_console.Commands.AddCommand("General", false, "show info",
"show info",
"Show general information about the server", HandleShow);
m_console.Commands.AddCommand("base", false, "show stats",
m_console.Commands.AddCommand("General", false, "show stats",
"show stats",
"Show statistics", HandleShow);
m_console.Commands.AddCommand("base", false, "show threads",
m_console.Commands.AddCommand("General", false, "show threads",
"show threads",
"Show thread status", HandleShow);
m_console.Commands.AddCommand("base", false, "show uptime",
m_console.Commands.AddCommand("General", false, "show uptime",
"show uptime",
"Show server uptime", HandleShow);
m_console.Commands.AddCommand("base", false, "show version",
m_console.Commands.AddCommand("General", false, "show version",
"show version",
"Show server version", HandleShow);
m_console.Commands.AddCommand("base", false, "threads abort",
m_console.Commands.AddCommand("General", false, "threads abort",
"threads abort <thread-id>",
"Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
m_console.Commands.AddCommand("base", false, "threads show",
m_console.Commands.AddCommand("General", false, "threads show",
"threads show",
"Show thread status. Synonym for \"show threads\"",
(string module, string[] args) => Notice(GetThreadsReport()));
@@ -269,15 +269,19 @@ namespace OpenSim.Framework.Servers
t.Priority,
t.ThreadState);
sb.Append(Environment.NewLine);
sb.Append("\n");
}
int workers = 0, ports = 0, maxWorkers = 0, maxPorts = 0;
ThreadPool.GetAvailableThreads(out workers, out ports);
ThreadPool.GetMaxThreads(out maxWorkers, out maxPorts);
sb.Append("\n");
sb.Append(Environment.NewLine + "*** ThreadPool threads ***" + Environment.NewLine);
sb.Append("workers: " + (maxWorkers - workers) + " (" + maxWorkers + "); ports: " + (maxPorts - ports) + " (" + maxPorts + ")" + Environment.NewLine);
// For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting
// zero active threads.
int totalThreads = Process.GetCurrentProcess().Threads.Count;
if (totalThreads > 0)
sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
sb.Append("Main threadpool (excluding script engine pools)\n");
sb.Append(Util.GetThreadPoolReport());
return sb.ToString();
}
@@ -662,11 +662,11 @@ namespace OpenSim.Framework.Servers.HttpServer
}
catch (IOException e)
{
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw ", e);
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e);
}
catch (Exception e)
{
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw " + e.ToString());
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e.StackTrace);
SendHTML500(response);
}
finally
+3 -2
View File
@@ -29,7 +29,7 @@ namespace OpenSim
{
public class VersionInfo
{
private const string VERSION_NUMBER = "0.7.3";
private const string VERSION_NUMBER = "0.7.4";
private const Flavour VERSION_FLAVOUR = Flavour.Dev;
public enum Flavour
@@ -39,7 +39,8 @@ namespace OpenSim
RC1,
RC2,
Release,
Post_Fixes
Post_Fixes,
Extended
}
public static string Version
@@ -26,8 +26,8 @@
*/
using System;
using System.Diagnostics;
using System.Text;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
@@ -46,8 +46,12 @@ namespace OpenSim.Framework.Statistics
sb.Append(Environment.NewLine);
sb.Append(
string.Format(
"Allocated to OpenSim : {0} MB" + Environment.NewLine,
"Allocated to OpenSim objects: {0} MB\n",
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)));
sb.Append(
string.Format(
"Process memory : {0} MB\n",
Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0)));
return sb.ToString();
}
+168 -64
View File
@@ -35,7 +35,7 @@ using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
@@ -81,12 +81,15 @@ namespace OpenSim.Framework
private static uint nextXferID = 5000;
private static Random randomClass = new Random();
// Get a list of invalid file characters (OS dependent)
private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]";
private static object XferLock = new object();
/// <summary>Thread pool used for Util.FireAndForget if
/// FireAndForgetMethod.SmartThreadPool is used</summary>
/// <summary>
/// Thread pool used for Util.FireAndForget if FireAndForgetMethod.SmartThreadPool is used
/// </summary>
private static SmartThreadPool m_ThreadPool;
// 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.
@@ -144,7 +147,6 @@ namespace OpenSim.Framework
return lerp(y, lerp(x, a, b), lerp(x, c, d));
}
public static Encoding UTF8 = Encoding.UTF8;
/// <value>
@@ -376,20 +378,20 @@ namespace OpenSim.Framework
}
return sb.ToString();
}
/// <summary>
/// Is the platform Windows?
/// </summary>
/// <returns>true if so, false otherwise</returns>
public static bool IsWindows()
{
PlatformID platformId = Environment.OSVersion.Platform;
return (platformId == PlatformID.Win32NT
|| platformId == PlatformID.Win32S
|| platformId == PlatformID.Win32Windows
|| platformId == PlatformID.WinCE);
}
/// <summary>
/// Is the platform Windows?
/// </summary>
/// <returns>true if so, false otherwise</returns>
public static bool IsWindows()
{
PlatformID platformId = Environment.OSVersion.Platform;
return (platformId == PlatformID.Win32NT
|| platformId == PlatformID.Win32S
|| platformId == PlatformID.Win32Windows
|| platformId == PlatformID.WinCE);
}
public static bool LoadArchSpecificWindowsDll(string libraryName)
@@ -1502,27 +1504,27 @@ namespace OpenSim.Framework
}
return data;
}
/// <summary>
/// Used to trigger an early library load on Windows systems.
/// </summary>
/// <remarks>
/// Required to get 32-bit and 64-bit processes to automatically use the
/// appropriate native library.
/// </remarks>
/// <param name="dllToLoad"></param>
/// <returns></returns>
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
/// <summary>
/// Determine whether the current process is 64 bit
/// </summary>
/// <returns>true if so, false if not</returns>
public static bool Is64BitProcess()
{
return IntPtr.Size == 8;
}
/// <summary>
/// Used to trigger an early library load on Windows systems.
/// </summary>
/// <remarks>
/// Required to get 32-bit and 64-bit processes to automatically use the
/// appropriate native library.
/// </remarks>
/// <param name="dllToLoad"></param>
/// <returns></returns>
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
/// <summary>
/// Determine whether the current process is 64 bit
/// </summary>
/// <returns>true if so, false if not</returns>
public static bool Is64BitProcess()
{
return IntPtr.Size == 8;
}
#region FireAndForget Threading Pattern
@@ -1671,6 +1673,61 @@ namespace OpenSim.Framework
}
}
/// <summary>
/// Get a thread pool report.
/// </summary>
/// <returns></returns>
public static string GetThreadPoolReport()
{
string threadPoolUsed = null;
int maxThreads = 0;
int minThreads = 0;
int allocatedThreads = 0;
int inUseThreads = 0;
int waitingCallbacks = 0;
int completionPortThreads = 0;
StringBuilder sb = new StringBuilder();
if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
{
threadPoolUsed = "SmartThreadPool";
maxThreads = m_ThreadPool.MaxThreads;
minThreads = m_ThreadPool.MinThreads;
inUseThreads = m_ThreadPool.InUseThreads;
allocatedThreads = m_ThreadPool.ActiveThreads;
waitingCallbacks = m_ThreadPool.WaitingCallbacks;
}
else if (
FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem
|| FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
{
threadPoolUsed = "BuiltInThreadPool";
ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
int availableThreads;
ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
inUseThreads = maxThreads - availableThreads;
allocatedThreads = -1;
waitingCallbacks = -1;
}
if (threadPoolUsed != null)
{
sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
sb.AppendFormat("Max threads : {0}\n", maxThreads);
sb.AppendFormat("Min threads : {0}\n", minThreads);
sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString());
sb.AppendFormat("In use threads : {0}\n", inUseThreads);
sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString());
}
else
{
sb.AppendFormat("Thread pool not used\n");
}
return sb.ToString();
}
private static object SmartThreadPoolCallback(object o)
{
object[] array = (object[])o;
@@ -1696,6 +1753,20 @@ namespace OpenSim.Framework
}
const Int32 EnvironmentTickCountMask = 0x3fffffff;
/// <summary>
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
/// and negative every 24.9 days. Subtracts the passed value (previously fetched by
/// 'EnvironmentTickCount()') and accounts for any wrapping.
/// </summary>
/// <param name="newValue"></param>
/// <param name="prevValue"></param>
/// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
public static Int32 EnvironmentTickCountSubtract(Int32 newValue, Int32 prevValue)
{
Int32 diff = newValue - prevValue;
return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
}
/// <summary>
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
/// and negative every 24.9 days. Subtracts the passed value (previously fetched by
@@ -1704,8 +1775,7 @@ namespace OpenSim.Framework
/// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
public static Int32 EnvironmentTickCountSubtract(Int32 prevValue)
{
Int32 diff = EnvironmentTickCount() - prevValue;
return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
return EnvironmentTickCountSubtract(EnvironmentTickCount(), prevValue);
}
// Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount
@@ -1870,11 +1940,12 @@ namespace OpenSim.Framework
#region Universal User Identifiers
/// <summary>
/// </summary>
/// <param name="value">uuid[;endpoint[;name]]</param>
/// <param name="uuid"></param>
/// <param name="url"></param>
/// <param name="firstname"></param>
/// <param name="lastname"></param>
/// <param name="value">uuid[;endpoint[;first last[;secret]]]</param>
/// <param name="uuid">the uuid part</param>
/// <param name="url">the endpoint part (e.g. http://foo.com)</param>
/// <param name="firstname">the first name part (e.g. Test)</param>
/// <param name="lastname">the last name part (e.g User)</param>
/// <param name="secret">the secret part</param>
public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
{
uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty;
@@ -1903,31 +1974,64 @@ namespace OpenSim.Framework
}
/// <summary>
///
/// Produces a universal (HG) system-facing identifier given the information
/// </summary>
/// <param name="acircuit"></param>
/// <returns>uuid[;endpoint[;name]]</returns>
/// <returns>uuid[;homeURI[;first last]]</returns>
public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit)
{
if (acircuit.ServiceURLs.ContainsKey("HomeURI"))
{
string agentsURI = acircuit.ServiceURLs["HomeURI"].ToString();
if (!agentsURI.EndsWith("/"))
agentsURI += "/";
// This is ugly, but there's no other way, given that the name is changed
// in the agent circuit data for foreigners
if (acircuit.lastname.Contains("@"))
{
string[] parts = acircuit.firstname.Split(new char[] { '.' });
if (parts.Length == 2)
return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
}
return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + acircuit.firstname + " " + acircuit.lastname;
}
return UniversalIdentifier(acircuit.AgentID, acircuit.firstname, acircuit.lastname, acircuit.ServiceURLs["HomeURI"].ToString());
else
return acircuit.AgentID.ToString();
}
}
/// <summary>
/// Produces a universal (HG) system-facing identifier given the information
/// </summary>
/// <param name="id">UUID of the user</param>
/// <param name="firstName">first name (e.g Test)</param>
/// <param name="lastName">last name (e.g. User)</param>
/// <param name="homeURI">homeURI (e.g. http://foo.com)</param>
/// <returns>a string of the form uuid[;homeURI[;first last]]</returns>
public static string UniversalIdentifier(UUID id, String firstName, String lastName, String homeURI)
{
string agentsURI = homeURI;
if (!agentsURI.EndsWith("/"))
agentsURI += "/";
// This is ugly, but there's no other way, given that the name is changed
// in the agent circuit data for foreigners
if (lastName.Contains("@"))
{
string[] parts = firstName.Split(new char[] { '.' });
if (parts.Length == 2)
return id.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
}
return id.ToString() + ";" + agentsURI + ";" + firstName + " " + lastName;
}
/// <summary>
/// Produces a universal (HG) user-facing name given the information
/// </summary>
/// <param name="firstName"></param>
/// <param name="lastName"></param>
/// <param name="homeURI"></param>
/// <returns>string of the form first.last @foo.com or first last</returns>
public static string UniversalName(String firstName, String lastName, String homeURI)
{
Uri uri = null;
try
{
uri = new Uri(homeURI);
}
catch (UriFormatException)
{
return firstName + " " + lastName;
}
return firstName + "." + lastName + " " + "@" + uri.Authority;
}
#endregion
}
}
+45 -63
View File
@@ -63,77 +63,32 @@ namespace OpenSim.Framework
// a "long" call for warning & debugging purposes
public const int LongCallTime = 500;
// /// <summary>
// /// Send LLSD to an HTTP client in application/llsd+json form
// /// </summary>
// /// <param name="response">HTTP response to send the data in</param>
// /// <param name="body">LLSD to send to the client</param>
// public static void SendJSONResponse(OSHttpResponse response, OSDMap body)
// {
// byte[] responseData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(body));
//
// response.ContentEncoding = Encoding.UTF8;
// response.ContentLength = responseData.Length;
// response.ContentType = "application/llsd+json";
// response.Body.Write(responseData, 0, responseData.Length);
// }
//
// /// <summary>
// /// Send LLSD to an HTTP client in application/llsd+xml form
// /// </summary>
// /// <param name="response">HTTP response to send the data in</param>
// /// <param name="body">LLSD to send to the client</param>
// public static void SendXMLResponse(OSHttpResponse response, OSDMap body)
// {
// byte[] responseData = OSDParser.SerializeLLSDXmlBytes(body);
//
// response.ContentEncoding = Encoding.UTF8;
// response.ContentLength = responseData.Length;
// response.ContentType = "application/llsd+xml";
// response.Body.Write(responseData, 0, responseData.Length);
// }
// dictionary of end points
private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>();
/// <summary>
/// Make a GET or GET-like request to a web service that returns LLSD
/// or JSON data
/// </summary>
public static OSDMap ServiceRequest(string url, string httpVerb)
private static object EndPointLock(string url)
{
string errorMessage;
System.Uri uri = new System.Uri(url);
string endpoint = string.Format("{0}:{1}",uri.Host,uri.Port);
try
lock (m_endpointSerializer)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = httpVerb;
object eplock = null;
using (WebResponse response = request.GetResponse())
if (! m_endpointSerializer.TryGetValue(endpoint,out eplock))
{
using (Stream responseStream = response.GetResponseStream())
{
try
{
string responseStr = responseStream.GetStreamString();
OSD responseOSD = OSDParser.Deserialize(responseStr);
if (responseOSD.Type == OSDType.Map)
return (OSDMap)responseOSD;
else
errorMessage = "Response format was invalid.";
}
catch
{
errorMessage = "Failed to parse the response.";
}
}
eplock = new object();
m_endpointSerializer.Add(endpoint,eplock);
// m_log.WarnFormat("[WEB UTIL] add a new host to end point serializer {0}",endpoint);
}
}
catch (Exception ex)
{
m_log.Warn(httpVerb + " on URL " + url + " failed: " + ex.Message);
errorMessage = ex.Message;
}
return new OSDMap { { "Message", OSD.FromString("Service request failed. " + errorMessage) } };
return eplock;
}
}
#region JSONRequest
/// <summary>
/// PUT JSON-encoded data to a web service that returns LLSD or
@@ -165,6 +120,14 @@ namespace OpenSim.Framework
}
public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed)
{
lock (EndPointLock(url))
{
return ServiceOSDRequestWorker(url,data,method,timeout,compressed);
}
}
private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed)
{
int reqnum = m_requestNumber++;
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
@@ -303,6 +266,10 @@ namespace OpenSim.Framework
return result;
}
#endregion JSONRequest
#region FormRequest
/// <summary>
/// POST URL-encoded form data to a web service that returns LLSD or
/// JSON data
@@ -313,6 +280,14 @@ namespace OpenSim.Framework
}
public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout)
{
lock (EndPointLock(url))
{
return ServiceFormRequestWorker(url,data,timeout);
}
}
private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout)
{
int reqnum = m_requestNumber++;
string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown";
@@ -397,6 +372,8 @@ namespace OpenSim.Framework
result["Message"] = OSD.FromString("Service request failed: " + msg);
return result;
}
#endregion FormRequest
#region Uri
@@ -533,8 +510,13 @@ namespace OpenSim.Framework
/// <remarks>
/// Copying begins at the streams' current positions. The positions are
/// NOT reset after copying is complete.
/// NOTE!! .NET 4.0 adds the method 'Stream.CopyTo(stream, bufferSize)'.
/// This function could be replaced with that method once we move
/// totally to .NET 4.0. For versions before, this routine exists.
/// This routine used to be named 'CopyTo' but the int parameter has
/// a different meaning so this method was renamed to avoid any confusion.
/// </remarks>
public static int CopyTo(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy)
public static int CopyStream(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy)
{
byte[] buffer = new byte[4096];
int readBytes;
+49 -76
View File
@@ -225,12 +225,12 @@ namespace OpenSim
/// </summary>
private void RegisterConsoleCommands()
{
m_console.Commands.AddCommand("region", false, "force update",
m_console.Commands.AddCommand("Regions", false, "force update",
"force update",
"Force the update of all objects on clients",
HandleForceUpdate);
m_console.Commands.AddCommand("region", false, "debug packet",
m_console.Commands.AddCommand("Comms", false, "debug packet",
"debug packet <level> [<avatar-first-name> <avatar-last-name>]",
"Turn on packet debugging",
"If level > 255 then all incoming and outgoing packets are logged.\n"
@@ -242,7 +242,7 @@ namespace OpenSim
+ "If an avatar name is given then only packets from that avatar are logged",
Debug);
m_console.Commands.AddCommand("region", false, "debug http",
m_console.Commands.AddCommand("Comms", false, "debug http",
"debug http <level>",
"Turn on inbound http request debugging for everything except the event queue (see debug eq).",
"If level >= 2 then the handler used to service the request is logged.\n"
@@ -250,37 +250,37 @@ namespace OpenSim
+ "If level <= 0 then no extra http logging is done.\n",
Debug);
m_console.Commands.AddCommand("region", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
m_console.Commands.AddCommand("Comms", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
m_console.Commands.AddCommand("region", false, "debug scene",
m_console.Commands.AddCommand("Regions", false, "debug scene",
"debug scene <scripting> <collisions> <physics>",
"Turn on scene debugging", Debug);
m_console.Commands.AddCommand("region", false, "change region",
m_console.Commands.AddCommand("General", false, "change region",
"change region <region name>",
"Change current console region", ChangeSelectedRegion);
m_console.Commands.AddCommand("region", false, "save xml",
m_console.Commands.AddCommand("Archiving", false, "save xml",
"save xml",
"Save a region's data in XML format", SaveXml);
m_console.Commands.AddCommand("region", false, "save xml2",
m_console.Commands.AddCommand("Archiving", false, "save xml2",
"save xml2",
"Save a region's data in XML2 format", SaveXml2);
m_console.Commands.AddCommand("region", false, "load xml",
m_console.Commands.AddCommand("Archiving", false, "load xml",
"load xml [-newIDs [<x> <y> <z>]]",
"Load a region's data from XML format", LoadXml);
m_console.Commands.AddCommand("region", false, "load xml2",
m_console.Commands.AddCommand("Archiving", false, "load xml2",
"load xml2",
"Load a region's data from XML2 format", LoadXml2);
m_console.Commands.AddCommand("region", false, "save prims xml2",
m_console.Commands.AddCommand("Archiving", false, "save prims xml2",
"save prims xml2 [<prim name> <file name>]",
"Save named prim to XML2", SavePrimsXml2);
m_console.Commands.AddCommand("region", false, "load oar",
m_console.Commands.AddCommand("Archiving", false, "load oar",
"load oar [--merge] [--skip-assets] [<OAR path>]",
"Load a region's data from an OAR archive.",
"--merge will merge the OAR with the existing scene." + Environment.NewLine
@@ -289,7 +289,7 @@ namespace OpenSim
+ " If this is not given then the command looks for an OAR named region.oar in the current directory.",
LoadOar);
m_console.Commands.AddCommand("region", false, "save oar",
m_console.Commands.AddCommand("Archiving", false, "save oar",
//"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
"save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]",
"Save a region's data to an OAR archive.",
@@ -306,54 +306,54 @@ namespace OpenSim
+ " If this is not given then the oar is saved to region.oar in the current directory.",
SaveOar);
m_console.Commands.AddCommand("region", false, "edit scale",
m_console.Commands.AddCommand("Regions", false, "edit scale",
"edit scale <name> <x> <y> <z>",
"Change the scale of a named prim", HandleEditScale);
m_console.Commands.AddCommand("region", false, "kick user",
m_console.Commands.AddCommand("Users", false, "kick user",
"kick user <first> <last> [message]",
"Kick a user off the simulator", KickUserCommand);
m_console.Commands.AddCommand("region", false, "show users",
m_console.Commands.AddCommand("Users", false, "show users",
"show users [full]",
"Show user data for users currently on the region",
"Without the 'full' option, only users actually on the region are shown."
+ " With the 'full' option child agents of users in neighbouring regions are also shown.",
HandleShow);
m_console.Commands.AddCommand("region", false, "show connections",
m_console.Commands.AddCommand("Comms", false, "show connections",
"show connections",
"Show connection data", HandleShow);
m_console.Commands.AddCommand("region", false, "show circuits",
m_console.Commands.AddCommand("Comms", false, "show circuits",
"show circuits",
"Show agent circuit data", HandleShow);
m_console.Commands.AddCommand("region", false, "show http-handlers",
m_console.Commands.AddCommand("Comms", false, "show http-handlers",
"show http-handlers",
"Show all registered http handlers", HandleShow);
m_console.Commands.AddCommand("region", false, "show pending-objects",
m_console.Commands.AddCommand("Comms", false, "show pending-objects",
"show pending-objects",
"Show # of objects on the pending queues of all scene viewers", HandleShow);
m_console.Commands.AddCommand("region", false, "show modules",
m_console.Commands.AddCommand("General", false, "show modules",
"show modules",
"Show module data", HandleShow);
m_console.Commands.AddCommand("region", false, "show regions",
m_console.Commands.AddCommand("Regions", false, "show regions",
"show regions",
"Show region data", HandleShow);
m_console.Commands.AddCommand("region", false, "show ratings",
m_console.Commands.AddCommand("Regions", false, "show ratings",
"show ratings",
"Show rating data", HandleShow);
m_console.Commands.AddCommand("region", false, "backup",
m_console.Commands.AddCommand("Regions", false, "backup",
"backup",
"Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand);
m_console.Commands.AddCommand("region", false, "create region",
m_console.Commands.AddCommand("Regions", false, "create region",
"create region [\"region name\"] <region_file.ini>",
"Create a new region.",
"The settings for \"region name\" are read from <region_file.ini>. Paths specified with <region_file.ini> are relative to your Regions directory, unless an absolute path is given."
@@ -362,62 +362,57 @@ namespace OpenSim
+ "If <region_file.ini> does not exist, it will be created.",
HandleCreateRegion);
m_console.Commands.AddCommand("region", false, "restart",
m_console.Commands.AddCommand("Regions", false, "restart",
"restart",
"Restart all sims in this instance", RunCommand);
m_console.Commands.AddCommand("region", false, "config set",
m_console.Commands.AddCommand("General", false, "config set",
"config set <section> <key> <value>",
"Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig);
m_console.Commands.AddCommand("region", false, "config get",
m_console.Commands.AddCommand("General", false, "config get",
"config get [<section>] [<key>]",
"Synonym for config show",
HandleConfig);
m_console.Commands.AddCommand("region", false, "config show",
m_console.Commands.AddCommand("General", false, "config show",
"config show [<section>] [<key>]",
"Show config information",
"If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine
+ "If a section is given but not a field, then all fields in that section are printed.",
HandleConfig);
m_console.Commands.AddCommand("region", false, "config save",
m_console.Commands.AddCommand("General", false, "config save",
"config save <path>",
"Save current configuration to a file at the given path", HandleConfig);
m_console.Commands.AddCommand("region", false, "command-script",
m_console.Commands.AddCommand("General", false, "command-script",
"command-script <script>",
"Run a command script from file", RunCommand);
m_console.Commands.AddCommand("region", false, "remove-region",
m_console.Commands.AddCommand("Regions", false, "remove-region",
"remove-region <name>",
"Remove a region from this simulator", RunCommand);
m_console.Commands.AddCommand("region", false, "delete-region",
m_console.Commands.AddCommand("Regions", false, "delete-region",
"delete-region <name>",
"Delete a region from disk", RunCommand);
m_console.Commands.AddCommand("region", false, "modules list",
m_console.Commands.AddCommand("General", false, "modules list",
"modules list",
"List modules", HandleModules);
m_console.Commands.AddCommand("region", false, "modules load",
m_console.Commands.AddCommand("General", false, "modules load",
"modules load <name>",
"Load a module", HandleModules);
m_console.Commands.AddCommand("region", false, "modules unload",
m_console.Commands.AddCommand("General", false, "modules unload",
"modules unload <name>",
"Unload a module", HandleModules);
m_console.Commands.AddCommand("region", false, "Add-InventoryHost",
"Add-InventoryHost <host>",
String.Empty, RunCommand);
m_console.Commands.AddCommand("region", false, "kill uuid",
m_console.Commands.AddCommand("Regions", false, "kill uuid",
"kill uuid <UUID>",
"Kill an object by UUID", KillUUID);
}
public override void ShutdownSpecific()
@@ -508,7 +503,11 @@ namespace OpenSim
string currentCommand;
while ((currentCommand = readFile.ReadLine()) != null)
{
if (currentCommand != String.Empty)
currentCommand = currentCommand.Trim();
if (!(currentCommand == ""
|| currentCommand.StartsWith(";")
|| currentCommand.StartsWith("//")
|| currentCommand.StartsWith("#")))
{
m_log.Info("[COMMANDFILE]: Running '" + currentCommand + "'");
m_console.RunCommand(currentCommand);
@@ -829,14 +828,6 @@ namespace OpenSim
case "restart":
m_sceneManager.RestartCurrentScene();
break;
case "Add-InventoryHost":
if (cmdparams.Length > 0)
{
MainConsole.Instance.Output("Not implemented.");
}
break;
}
}
@@ -928,7 +919,7 @@ namespace OpenSim
break;
case "scene":
if (args.Length == 5)
if (args.Length == 4)
{
if (m_sceneManager.CurrentScene == null)
{
@@ -936,39 +927,21 @@ namespace OpenSim
}
else
{
bool scriptingOn = !Convert.ToBoolean(args[2]);
bool collisionsOn = !Convert.ToBoolean(args[3]);
bool physicsOn = !Convert.ToBoolean(args[4]);
m_sceneManager.CurrentScene.SetSceneCoreDebug(scriptingOn, collisionsOn, physicsOn);
string key = args[2];
string value = args[3];
m_sceneManager.CurrentScene.SetSceneCoreDebug(
new Dictionary<string, string>() { { key, value } });
MainConsole.Instance.Output(
String.Format(
"Set debug scene scripting = {0}, collisions = {1}, physics = {2}",
!scriptingOn, !collisionsOn, !physicsOn));
MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value);
}
}
else
{
MainConsole.Instance.Output("Usage: debug scene <scripting> <collisions> <physics> (where inside <> is true/false)");
MainConsole.Instance.Output("Usage: debug scene scripting|collisions|physics|teleport true|false");
}
break;
case "teleport":
foreach(Scene s in m_sceneManager.Scenes)
{
if (s.DEBUG)
{
s.DEBUG = false;
MainConsole.Instance.Output("Teleport debugging is disabled!");
}
else{
s.DEBUG = true;
MainConsole.Instance.Output("Teleport debugging is enabled!");
}
}
break;
default:
MainConsole.Instance.Output("Unknown debug command");
break;
+165 -74
View File
@@ -28,6 +28,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
@@ -67,6 +68,9 @@ namespace OpenSim
private const string PLUGIN_ASSET_CACHE = "/OpenSim/AssetCache";
private const string PLUGIN_ASSET_SERVER_CLIENT = "/OpenSim/AssetClient";
// OpenSim.ini Section name for ESTATES Settings
public const string ESTATE_SECTION_NAME = "Estates";
protected string proxyUrl;
protected int proxyOffset = 0;
@@ -242,15 +246,18 @@ namespace OpenSim
foreach (string topic in topics)
{
m_console.Commands.AddCommand("plugin", false, "help " + topic,
"help " + topic,
string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1);
// This is a hack to allow the user to enter the help command in upper or lowercase. This will go
// away at some point.
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
"help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'",
HandleCommanderHelp);
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
"help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'",
HandleCommanderHelp);
m_console.Commands.AddCommand("plugin", false, topic,
topic,
"Execute subcommand for plugin '" + topic + "'",
null);
ICommander commander = null;
@@ -267,7 +274,7 @@ namespace OpenSim
foreach (string command in commander.Commands.Keys)
{
m_console.Commands.AddCommand(topic, false,
m_console.Commands.AddCommand(capitalizedTopic, false,
topic + " " + command,
topic + " " + commander.Commands[command].ShortHelp(),
String.Empty, HandleCommanderCommand);
@@ -286,7 +293,7 @@ namespace OpenSim
// Only safe for the interactive console, since it won't
// let us come here unless both scene and commander exist
//
ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1]);
ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1].ToLower());
if (moduleCommander != null)
m_console.Output(moduleCommander.Help);
}
@@ -424,7 +431,7 @@ namespace OpenSim
mscene = scene;
scene.StartTimer();
scene.Start();
scene.StartScripts();
@@ -443,12 +450,42 @@ namespace OpenSim
{
RegionInfo regionInfo = scene.RegionInfo;
string estateOwnerFirstName = null;
string estateOwnerLastName = null;
string estateOwnerEMail = null;
string estateOwnerPassword = null;
string rawEstateOwnerUuid = null;
if (m_config.Source.Configs[ESTATE_SECTION_NAME] != null)
{
string defaultEstateOwnerName
= m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerName", "").Trim();
string[] ownerNames = defaultEstateOwnerName.Split(' ');
if (ownerNames.Length >= 2)
{
estateOwnerFirstName = ownerNames[0];
estateOwnerLastName = ownerNames[1];
}
// Info to be used only on Standalone Mode
rawEstateOwnerUuid = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerUUID", null);
estateOwnerEMail = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerEMail", null);
estateOwnerPassword = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerPassword", null);
}
MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", regionInfo.EstateSettings.EstateName);
List<char> excluded = new List<char>(new char[1]{' '});
string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
UserAccount account = scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, first, last);
if (estateOwnerFirstName == null || estateOwnerLastName == null)
{
estateOwnerFirstName = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
estateOwnerLastName = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
}
UserAccount account
= scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, estateOwnerFirstName, estateOwnerLastName);
if (account == null)
{
@@ -467,23 +504,35 @@ namespace OpenSim
if (scene.UserAccountService is UserAccountService)
{
string password = MainConsole.Instance.PasswdPrompt("Password");
string email = MainConsole.Instance.CmdPrompt("Email", "");
if (estateOwnerPassword == null)
estateOwnerPassword = MainConsole.Instance.PasswdPrompt("Password");
string rawPrincipalId = MainConsole.Instance.CmdPrompt("User ID", UUID.Random().ToString());
if (estateOwnerEMail == null)
estateOwnerEMail = MainConsole.Instance.CmdPrompt("Email");
if (rawEstateOwnerUuid == null)
rawEstateOwnerUuid = MainConsole.Instance.CmdPrompt("User ID", UUID.Random().ToString());
UUID principalId = UUID.Zero;
if (!UUID.TryParse(rawPrincipalId, out principalId))
UUID estateOwnerUuid = UUID.Zero;
if (!UUID.TryParse(rawEstateOwnerUuid, out estateOwnerUuid))
{
m_log.ErrorFormat("[OPENSIM]: ID {0} is not a valid UUID", rawPrincipalId);
m_log.ErrorFormat("[OPENSIM]: ID {0} is not a valid UUID", rawEstateOwnerUuid);
return;
}
// If we've been given a zero uuid then this signals that we should use a random user id
if (estateOwnerUuid == UUID.Zero)
estateOwnerUuid = UUID.Random();
account
= ((UserAccountService)scene.UserAccountService).CreateUser(
regionInfo.ScopeID, principalId, first, last, password, email);
regionInfo.ScopeID,
estateOwnerUuid,
estateOwnerFirstName,
estateOwnerLastName,
estateOwnerPassword,
estateOwnerEMail);
}
// }
}
if (account == null)
@@ -883,15 +932,21 @@ namespace OpenSim
/// This method doesn't allow an estate to be created with the same name as existing estates.
/// </remarks>
/// <param name="regInfo"></param>
/// <param name="existingName">A list of estate names that already exist.</param>
/// <param name="estatesByName">A list of estate names that already exist.</param>
/// <param name="estateName">Estate name to create if already known</param>
/// <returns>true if the estate was created, false otherwise</returns>
public bool CreateEstate(RegionInfo regInfo, List<string> existingNames)
public bool CreateEstate(RegionInfo regInfo, Dictionary<string, EstateSettings> estatesByName, string estateName)
{
// Create a new estate
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, true);
string newName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName);
if (existingNames.Contains(newName))
string newName;
if (estateName != null && estateName != "")
newName = estateName;
else
newName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName);
if (estatesByName.ContainsKey(newName))
{
MainConsole.Instance.OutputFormat("An estate named {0} already exists. Please try again.", newName);
return false;
@@ -918,66 +973,102 @@ namespace OpenSim
if (EstateDataService != null)
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false);
if (regInfo.EstateSettings.EstateID == 0) // No record at all
if (regInfo.EstateSettings.EstateID != 0)
return;
m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
Dictionary<string, EstateSettings> estatesByName = new Dictionary<string, EstateSettings>();
foreach (EstateSettings estate in estates)
estatesByName[estate.EstateName] = estate;
string defaultEstateName = null;
if (m_config.Source.Configs[ESTATE_SECTION_NAME] != null)
{
m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
List<string> estateNames = new List<string>();
foreach (EstateSettings estate in estates)
estateNames.Add(estate.EstateName);
while (true)
defaultEstateName = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateName", null);
if (defaultEstateName != null)
{
if (estates.Count == 0)
{
m_log.Info("[ESTATE] No existing estates found. You must create a new one.");
if (CreateEstate(regInfo, estateNames))
break;
EstateSettings defaultEstate;
bool defaultEstateJoined = false;
if (estatesByName.ContainsKey(defaultEstateName))
{
defaultEstate = estatesByName[defaultEstateName];
if (EstateDataService.LinkRegion(regInfo.RegionID, (int)defaultEstate.EstateID))
defaultEstateJoined = true;
}
else
{
if (CreateEstate(regInfo, estatesByName, defaultEstateName))
defaultEstateJoined = true;
}
if (defaultEstateJoined)
return;
else
m_log.ErrorFormat(
"[OPENSIM BASE]: Joining default estate {0} failed", defaultEstateName);
}
}
// If we have no default estate or creation of the default estate failed then ask the user.
while (true)
{
if (estates.Count == 0)
{
m_log.Info("[ESTATE]: No existing estates found. You must create a new one.");
if (CreateEstate(regInfo, estatesByName, null))
break;
else
continue;
}
else
{
string response
= MainConsole.Instance.CmdPrompt(
string.Format(
"Do you wish to join region {0} to an existing estate (yes/no)?", regInfo.RegionName),
"yes",
new List<string>() { "yes", "no" });
if (response == "no")
{
if (CreateEstate(regInfo, estatesByName, null))
break;
else
continue;
}
else
{
string response
string[] estateNames = estatesByName.Keys.ToArray();
response
= MainConsole.Instance.CmdPrompt(
string.Format(
"Do you wish to join region {0} to an existing estate (yes/no)?", regInfo.RegionName),
"yes",
new List<string>() { "yes", "no" });
if (response == "no")
"Name of estate to join. Existing estate names are ({0})",
string.Join(", ", estateNames)),
estateNames[0]);
List<int> estateIDs = EstateDataService.GetEstates(response);
if (estateIDs.Count < 1)
{
if (CreateEstate(regInfo, estateNames))
break;
else
continue;
}
else
{
response
= MainConsole.Instance.CmdPrompt(
string.Format(
"Name of estate to join. Existing estate names are ({0})", string.Join(", ", estateNames.ToArray())),
estateNames[0]);
List<int> estateIDs = EstateDataService.GetEstates(response);
if (estateIDs.Count < 1)
{
MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again.");
continue;
}
int estateID = estateIDs[0];
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(estateID);
if (EstateDataService.LinkRegion(regInfo.RegionID, estateID))
break;
MainConsole.Instance.Output("Joining the estate failed. Please try again.");
MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again.");
continue;
}
int estateID = estateIDs[0];
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(estateID);
if (EstateDataService.LinkRegion(regInfo.RegionID, estateID))
break;
MainConsole.Instance.Output("Joining the estate failed. Please try again.");
}
}
}
@@ -111,6 +111,7 @@ namespace OpenSim.Region.ClientStack.Linden
private IAssetService m_assetService;
private bool m_dumpAssetsToFile = false;
private string m_regionName;
private int m_levelUpload = 0;
public BunchOfCaps(Scene scene, Caps caps)
{
@@ -121,7 +122,10 @@ namespace OpenSim.Region.ClientStack.Linden
{
IConfig sconfig = config.Configs["Startup"];
if (sconfig != null)
{
m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
m_levelUpload = sconfig.GetInt("LevelUpload", 0);
}
}
m_assetService = m_Scene.AssetService;
@@ -262,7 +266,7 @@ namespace OpenSim.Region.ClientStack.Linden
{
try
{
m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName);
// m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName);
//m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
@@ -357,21 +361,37 @@ namespace OpenSim.Region.ClientStack.Linden
llsdRequest.asset_type == "animation" ||
llsdRequest.asset_type == "sound")
{
ScenePresence avatar = null;
IClientAPI client = null;
IScene scene = null;
if (GetClient != null)
{
client = GetClient(m_HostCapsObj.AgentID);
scene = client.Scene;
m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
IMoneyModule mm = scene.RequestModuleInterface<IMoneyModule>();
// check user level
if (avatar != null)
{
client = avatar.ControllingClient;
if (avatar.UserLevel < m_levelUpload)
{
if (client != null)
client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
errorResponse.uploader = "";
errorResponse.state = "error";
return errorResponse;
}
}
// check funds
if (client != null)
{
IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>();
if (mm != null)
{
if (!mm.UploadCovered(client.AgentId, mm.UploadCharge))
{
if (client != null)
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
errorResponse.uploader = "";
@@ -761,7 +781,7 @@ namespace OpenSim.Region.ClientStack.Linden
SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID);
if (part != null)
{
TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
// TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID))
{
return LLSDHelpers.SerialiseLLSDReply(response);
@@ -106,7 +106,7 @@ namespace OpenSim.Region.ClientStack.Linden
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
MainConsole.Instance.Commands.AddCommand(
"event queue",
"Comms",
false,
"debug eq",
"debug eq [0|1]",
@@ -56,6 +56,7 @@ namespace OpenSim.Region.ClientStack.Linden
// private IAssetService m_assetService;
private bool m_dumpAssetsToFile = false;
private bool m_enabled = true;
private int m_levelUpload = 0;
#region IRegionModuleBase Members
@@ -72,6 +73,7 @@ namespace OpenSim.Region.ClientStack.Linden
return;
m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
m_levelUpload = meshConfig.GetInt("LevelUpload", 0);
}
public void AddRegion(Scene pScene)
@@ -137,25 +139,41 @@ namespace OpenSim.Region.ClientStack.Linden
// llsdRequest.asset_type == "animation" ||
// llsdRequest.asset_type == "sound")
// {
// check user level
ScenePresence avatar = null;
IClientAPI client = null;
m_scene.TryGetScenePresence(agentID, out avatar);
if (avatar != null)
{
client = avatar.ControllingClient;
if (avatar.UserLevel < m_levelUpload)
{
if (client != null)
client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
errorResponse.rsvp = "";
errorResponse.state = "error";
return errorResponse;
}
}
// check funds
IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
if (mm != null)
{
if (m_scene.TryGetClient(agentID, out client))
if (!mm.UploadCovered(agentID, mm.UploadCharge))
{
if (!mm.UploadCovered(client.AgentId, mm.UploadCharge))
{
if (client != null)
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
if (client != null)
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
errorResponse.rsvp = "";
errorResponse.state = "error";
return errorResponse;
}
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
errorResponse.rsvp = "";
errorResponse.state = "error";
return errorResponse;
}
}
// }
@@ -59,7 +59,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Handles new client connections
/// Constructor takes a single Packet and authenticates everything
/// </summary>
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientIPEndpoint, IStatsCollector
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IClientIPEndpoint, IStatsCollector
{
/// <value>
/// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details.
@@ -317,7 +317,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected readonly UUID m_agentId;
private readonly uint m_circuitCode;
private readonly byte[] m_channelVersion = Utils.EmptyBytes;
private readonly Dictionary<string, UUID> m_defaultAnimations = new Dictionary<string, UUID>();
private readonly IGroupsModule m_GroupsModule;
private int m_cachedTextureSerial;
@@ -385,7 +384,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
set { m_startpos = value; }
}
public UUID AgentId { get { return m_agentId; } }
public ISceneAgent SceneAgent { get; private set; }
public ISceneAgent SceneAgent { get; set; }
public UUID ActiveGroupId { get { return m_activeGroupID; } }
public string ActiveGroupName { get { return m_activeGroupName; } }
public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } }
@@ -449,13 +448,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// DebugPacketLevel = 1;
RegisterInterface<IClientIM>(this);
RegisterInterface<IClientInventory>(this);
RegisterInterface<IClientChat>(this);
RegisterInterface<IClientIPEndpoint>(this);
InitDefaultAnimations();
m_scene = scene;
m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
m_entityProps = new PriorityQueue(m_scene.Entities.Count);
m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
@@ -698,7 +695,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public virtual void Start()
{
SceneAgent = m_scene.AddNewClient(this, PresenceType.User);
m_scene.AddNewClient(this, PresenceType.User);
RefreshGroupMembership();
}
@@ -1916,7 +1913,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
folderBlock.FolderID = folder.ID;
folderBlock.ParentID = folder.ParentID;
folderBlock.Type = -1;
//folderBlock.Type = -1;
folderBlock.Type = (sbyte)folder.Type;
folderBlock.Name = Util.StringToBytes256(folder.Name);
return folderBlock;
@@ -4273,7 +4271,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
block.OwnerID = sop.OwnerID;
block.ItemID = sop.FromUserInventoryItemID;
block.FolderID = UUID.Zero; // sop.FromFolderID ??
block.FolderID = UUID.Zero; // sog.FromFolderID ??
block.FromTaskID = UUID.Zero; // ???
block.InventorySerial = (short)sop.InventorySerial;
@@ -4959,7 +4957,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
if (data.ParentGroup.IsAttachment)
{
update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID);
update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.ParentGroup.FromItemID);
update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16));
}
else
@@ -5787,7 +5785,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// My guess is this is the folder to stick the calling card into
List<UUID> callingCardFolders = new List<UUID>();
UUID agentID = afriendpack.AgentData.AgentID;
UUID transactionID = afriendpack.TransactionBlock.TransactionID;
for (int fi = 0; fi < afriendpack.FolderData.Length; fi++)
@@ -5798,10 +5795,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
FriendActionDelegate handlerApproveFriendRequest = OnApproveFriendRequest;
if (handlerApproveFriendRequest != null)
{
handlerApproveFriendRequest(this, agentID, transactionID, callingCardFolders);
handlerApproveFriendRequest(this, transactionID, callingCardFolders);
}
return true;
return true;
}
private bool HandlerDeclineFriendship(IClientAPI sender, Packet Pack)
@@ -5820,7 +5817,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (OnDenyFriendRequest != null)
{
OnDenyFriendRequest(this,
dfriendpack.AgentData.AgentID,
dfriendpack.TransactionBlock.TransactionID,
null);
}
@@ -5840,14 +5836,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
#endregion
UUID listOwnerAgentID = tfriendpack.AgentData.AgentID;
UUID exFriendID = tfriendpack.ExBlock.OtherID;
FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship;
if (TerminateFriendshipHandler != null)
{
TerminateFriendshipHandler(this, listOwnerAgentID, exFriendID);
TerminateFriendshipHandler(this, exFriendID);
return true;
}
return false;
}
@@ -11165,12 +11161,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true;
}
#endregion
GrantUserFriendRights GrantUserRightsHandler = OnGrantUserRights;
if (GrantUserRightsHandler != null)
GrantUserRightsHandler(this,
GrantUserRights.AgentData.AgentID,
GrantUserRights.Rights[0].AgentRelated,
GrantUserRights.Rights[0].RelatedRights);
return true;
}
@@ -11206,36 +11203,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
scriptQuestion.Data.Questions = question;
scriptQuestion.Data.ObjectName = Util.StringToBytes256(taskName);
scriptQuestion.Data.ObjectOwner = Util.StringToBytes256(ownerName);
OutPacket(scriptQuestion, ThrottleOutPacketType.Task);
}
private void InitDefaultAnimations()
{
using (XmlTextReader reader = new XmlTextReader("data/avataranimations.xml"))
{
XmlDocument doc = new XmlDocument();
doc.Load(reader);
if (doc.DocumentElement != null)
foreach (XmlNode nod in doc.DocumentElement.ChildNodes)
{
if (nod.Attributes["name"] != null)
{
string name = nod.Attributes["name"].Value.ToLower();
string id = nod.InnerText;
m_defaultAnimations.Add(name, (UUID)id);
}
}
}
}
public UUID GetDefaultAnimation(string name)
{
if (m_defaultAnimations.ContainsKey(name))
return m_defaultAnimations[name];
return UUID.Zero;
}
/// <summary>
/// Handler called when we receive a logout packet.
/// </summary>
@@ -12292,5 +12263,175 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (reply != null)
OutPacket(reply, ThrottleOutPacketType.Task);
}
public void SendRemoveInventoryItems(UUID[] items)
{
IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
if (eq == null)
{
m_log.DebugFormat("[LLCLIENT]: Null event queue");
return;
}
OSDMap llsd = new OSDMap(3);
OSDMap AgentDataMap = new OSDMap(1);
AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
OSDArray AgentData = new OSDArray(1);
AgentData.Add(AgentDataMap);
llsd.Add("AgentData", AgentData);
OSDArray ItemData = new OSDArray();
foreach (UUID item in items)
{
OSDMap ItemDataMap = new OSDMap(2);
ItemDataMap.Add("ItemID", OSD.FromUUID(item));
ItemDataMap.Add("AgentID", OSD.FromUUID(AgentId));
ItemData.Add(ItemDataMap);
}
llsd.Add("InventoryData", ItemData);
eq.Enqueue(BuildEvent("RemoveInventoryItem",
llsd), AgentId);
}
public void SendRemoveInventoryFolders(UUID[] folders)
{
IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
if (eq == null)
{
m_log.DebugFormat("[LLCLIENT]: Null event queue");
return;
}
OSDMap llsd = new OSDMap(3);
OSDMap AgentDataMap = new OSDMap(1);
AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
OSDArray AgentData = new OSDArray(1);
AgentData.Add(AgentDataMap);
llsd.Add("AgentData", AgentData);
OSDArray FolderData = new OSDArray();
foreach (UUID folder in folders)
{
OSDMap FolderDataMap = new OSDMap(2);
FolderDataMap.Add("FolderID", OSD.FromUUID(folder));
FolderDataMap.Add("AgentID", OSD.FromUUID(AgentId));
FolderData.Add(FolderDataMap);
}
llsd.Add("FolderData", FolderData);
eq.Enqueue(BuildEvent("RemoveInventoryFolder",
llsd), AgentId);
}
private byte[] EncodeU32(uint val)
{
byte[] ret = BitConverter.GetBytes(val);
if (BitConverter.IsLittleEndian)
Array.Reverse(ret);
return ret;
}
public void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items)
{
IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
if (eq == null)
{
m_log.DebugFormat("[LLCLIENT]: Null event queue");
return;
}
OSDMap llsd = new OSDMap(3);
OSDMap AgentDataMap = new OSDMap(1);
AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
AgentDataMap.Add("TransactionID", OSD.FromUUID(UUID.Random()));
OSDArray AgentData = new OSDArray(1);
AgentData.Add(AgentDataMap);
llsd.Add("AgentData", AgentData);
OSDArray FolderData = new OSDArray();
foreach (InventoryFolderBase folder in folders)
{
OSDMap FolderDataMap = new OSDMap(5);
FolderDataMap.Add("FolderID", OSD.FromUUID(folder.ID));
FolderDataMap.Add("AgentID", OSD.FromUUID(AgentId));
FolderDataMap.Add("ParentID", OSD.FromUUID(folder.ParentID));
FolderDataMap.Add("Type", OSD.FromInteger(folder.Type));
FolderDataMap.Add("Name", OSD.FromString(folder.Name));
FolderData.Add(FolderDataMap);
}
llsd.Add("FolderData", FolderData);
OSDArray ItemData = new OSDArray();
foreach (InventoryItemBase item in items)
{
OSDMap ItemDataMap = new OSDMap();
ItemDataMap.Add("ItemID", OSD.FromUUID(item.ID));
ItemDataMap.Add("FolderID", OSD.FromUUID(item.Folder));
ItemDataMap.Add("CreatorID", OSD.FromUUID(item.CreatorIdAsUuid));
ItemDataMap.Add("OwnerID", OSD.FromUUID(item.Owner));
ItemDataMap.Add("GroupID", OSD.FromUUID(item.GroupID));
ItemDataMap.Add("BaseMask", OSD.FromBinary(EncodeU32((uint)item.BasePermissions)));
ItemDataMap.Add("OwnerMask", OSD.FromBinary(EncodeU32((uint)item.CurrentPermissions)));
ItemDataMap.Add("GroupMask", OSD.FromBinary(EncodeU32((uint)item.GroupPermissions)));
ItemDataMap.Add("EveryoneMask", OSD.FromBinary(EncodeU32((uint)item.EveryOnePermissions)));
ItemDataMap.Add("NextOwnerMask", OSD.FromBinary(EncodeU32((uint)item.NextPermissions)));
ItemDataMap.Add("GroupOwned", OSD.FromBoolean(item.GroupOwned));
ItemDataMap.Add("AssetID", OSD.FromUUID(item.AssetID));
ItemDataMap.Add("Type", OSD.FromInteger(item.AssetType));
ItemDataMap.Add("InvType", OSD.FromInteger(item.InvType));
ItemDataMap.Add("Flags", OSD.FromBinary(EncodeU32((uint)item.Flags)));
ItemDataMap.Add("SaleType", OSD.FromInteger((byte)item.SaleType));
ItemDataMap.Add("SalePrice", OSD.FromInteger(item.SalePrice));
ItemDataMap.Add("Name", OSD.FromString(item.Name));
ItemDataMap.Add("Description", OSD.FromString(item.Description));
ItemDataMap.Add("CreationDate", OSD.FromInteger(item.CreationDate));
ItemDataMap.Add("CRC", OSD.FromBinary(EncodeU32(
Helpers.InventoryCRC(1000, 0, (sbyte)item.InvType,
(sbyte)item.AssetType, item.AssetID,
item.GroupID, 100,
item.Owner, item.CreatorIdAsUuid,
item.ID, item.Folder,
(uint)PermissionMask.All, 1, (uint)PermissionMask.All, (uint)PermissionMask.All,
(uint)PermissionMask.All)
)));
ItemDataMap.Add("CallbackID", 0);
ItemData.Add(ItemDataMap);
}
llsd.Add("ItemData", ItemData);
eq.Enqueue(BuildEvent("BulkUpdateInventory",
llsd), AgentId);
}
}
}
@@ -50,7 +50,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
m_regStatus = RegionStatus.Up;
}
public override void Update() {}
public override void Update(int frames) {}
public override void LoadWorldMap() {}
public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
@@ -47,6 +47,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
protected Scene m_Scene;
private bool m_dumpAssetsToFile = false;
private int m_levelUpload = 0;
/// <summary>
/// Each agent has its own singleton collection of transactions
@@ -56,8 +57,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
#region IRegionModule Members
public void Initialise(IConfigSource config)
public void Initialise(IConfigSource source)
{
IConfig sconfig = source.Configs["Startup"];
if (sconfig != null)
{
m_levelUpload = sconfig.GetInt("LevelUpload", 0);
}
}
public void AddRegion(Scene scene)
@@ -241,7 +247,21 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
(AssetType)type == AssetType.Animation) &&
tempFile == false)
{
ScenePresence avatar = null;
Scene scene = (Scene)remoteClient.Scene;
scene.TryGetScenePresence(remoteClient.AgentId, out avatar);
// check user level
if (avatar != null)
{
if (avatar.UserLevel < m_levelUpload)
{
remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
return;
}
}
// check funds
IMoneyModule mm = scene.RequestModuleInterface<IMoneyModule>();
if (mm != null)
@@ -203,10 +203,10 @@ namespace Flotsam.RegionModules.AssetCache
m_CacheDirectoryTierLen = 4;
}
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
}
}
}
@@ -239,7 +239,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// At the moment we can only deal with a single attachment
if (attachments.Count != 0)
{
UUID oldAttachmentItemID = attachments[0].GetFromItemID();
UUID oldAttachmentItemID = attachments[0].FromItemID;
if (oldAttachmentItemID != UUID.Zero)
DetachSingleAttachmentToInvInternal(sp, oldAttachmentItemID);
@@ -250,7 +250,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
}
// Add the new attachment to inventory if we don't already have it.
UUID newAttachmentItemID = group.GetFromItemID();
UUID newAttachmentItemID = group.FromItemID;
if (newAttachmentItemID == UUID.Zero)
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
@@ -285,7 +285,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
List<SceneObjectGroup> existingAttachments = sp.GetAttachments();
foreach (SceneObjectGroup so in existingAttachments)
{
if (so.GetFromItemID() == itemID)
if (so.FromItemID == itemID)
{
alreadyOn = true;
break;
@@ -342,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
if (so.AttachedAvatar != sp.UUID)
return;
UUID inventoryID = so.GetFromItemID();
UUID inventoryID = so.FromItemID;
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
@@ -359,9 +359,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
sp.RemoveAttachment(so);
so.FromItemID = UUID.Zero;
SceneObjectPart rootPart = so.RootPart;
rootPart.FromItemID = UUID.Zero;
so.AbsolutePosition = sp.AbsolutePosition;
so.AttachedAvatar = UUID.Zero;
rootPart.SetParentLocalId(0);
@@ -475,7 +475,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), sp.UUID);
InventoryItemBase item = new InventoryItemBase(grp.FromItemID, sp.UUID);
item = m_scene.InventoryService.GetItem(item);
if (item != null)
@@ -647,7 +647,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
item.CreationDate = Util.UnixTimeSinceEpoch();
// sets itemID so client can show item as 'attached' in inventory
grp.SetFromItemID(item.ID);
grp.FromItemID = item.ID;
if (m_scene.AddInventoryItem(item))
{
@@ -683,7 +683,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
if (entity is SceneObjectGroup)
{
group = (SceneObjectGroup)entity;
if (group.GetFromItemID() == itemID)
if (group.FromItemID == itemID)
{
m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
sp.RemoveAttachment(group);
@@ -889,7 +889,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// Calls attach with a Zero position
if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
{
m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId);
// Save avatar attachment information
m_log.Debug(
@@ -912,7 +912,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
if (sp != null && group != null)
DetachSingleAttachmentToInv(sp, group.GetFromItemID());
DetachSingleAttachmentToInv(sp, group.FromItemID);
}
private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient)
@@ -120,8 +120,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
Assert.That(attSo.IsTemporary, Is.False);
// Check item status
Assert.That(m_presence.Appearance.GetAttachpoint(
attSo.GetFromItemID()), Is.EqualTo((int)AttachmentPoint.Chest));
Assert.That(
m_presence.Appearance.GetAttachpoint(attSo.FromItemID),
Is.EqualTo((int)AttachmentPoint.Chest));
}
[Test]
@@ -51,12 +51,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
m_scene.RegisterModuleInterface<IDialogModule>(this);
m_scene.AddCommand(
this, "alert", "alert <message>",
"Users", this, "alert", "alert <message>",
"Send an alert to everyone",
HandleAlertConsoleCommand);
m_scene.AddCommand(
this, "alert-user", "alert-user <first> <last> <message>",
"Users", this, "alert-user", "alert-user <first> <last> <message>",
"Send an alert to a user",
HandleAlertConsoleCommand);
}
@@ -0,0 +1,313 @@
/*
* 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.Reflection;
using log4net;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using Mono.Addins;
namespace OpenSim.Region.CoreModules.Avatar.Friends
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XCallingCard")]
public class CallingCardModule : ISharedRegionModule, ICallingCardModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected List<Scene> m_Scenes = new List<Scene>();
protected bool m_Enabled = true;
public void Initialise(IConfigSource source)
{
IConfig ccConfig = source.Configs["XCallingCard"];
if (ccConfig != null)
m_Enabled = ccConfig.GetBoolean("Enabled", true);
}
public void AddRegion(Scene scene)
{
if (!m_Enabled)
return;
m_Scenes.Add(scene);
scene.RegisterModuleInterface<ICallingCardModule>(this);
}
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
m_Scenes.Remove(scene);
scene.EventManager.OnNewClient -= OnNewClient;
scene.EventManager.OnIncomingInstantMessage +=
OnIncomingInstantMessage;
scene.UnregisterModuleInterface<ICallingCardModule>(this);
}
public void RegionLoaded(Scene scene)
{
if (!m_Enabled)
return;
scene.EventManager.OnNewClient += OnNewClient;
}
public void PostInitialise()
{
}
public void Close()
{
}
public Type ReplaceableInterface
{
get { return null; }
}
public string Name
{
get { return "XCallingCardModule"; }
}
private void OnNewClient(IClientAPI client)
{
client.OnOfferCallingCard += OnOfferCallingCard;
client.OnAcceptCallingCard += OnAcceptCallingCard;
client.OnDeclineCallingCard += OnDeclineCallingCard;
}
private void OnOfferCallingCard(IClientAPI client, UUID destID, UUID transactionID)
{
ScenePresence sp = GetClientPresence(client.AgentId);
if (sp != null)
{
// If we're in god mode, we reverse the meaning. Offer
// calling card becomes "Take a calling card" for that
// person, no matter if they agree or not.
if (sp.GodLevel >= 200)
{
CreateCallingCard(client.AgentId, destID, UUID.Zero, true);
return;
}
}
IClientAPI dest = FindClientObject(destID);
if (dest != null)
{
DoCallingCardOffer(dest, client.AgentId);
return;
}
IMessageTransferModule transferModule =
m_Scenes[0].RequestModuleInterface<IMessageTransferModule>();
if (transferModule != null)
{
transferModule.SendInstantMessage(new GridInstantMessage(
client.Scene, client.AgentId,
client.FirstName+" "+client.LastName,
destID, (byte)211, false,
String.Empty,
transactionID, false, new Vector3(), new byte[0]),
delegate(bool success) {} );
}
}
private void DoCallingCardOffer(IClientAPI dest, UUID from)
{
UUID itemID = CreateCallingCard(dest.AgentId, from, UUID.Zero, false);
dest.SendOfferCallingCard(from, itemID);
}
// Create a calling card in the user's inventory. This is called
// from direct calling card creation, when the offer is forwarded,
// and from the friends module when the friend is confirmed.
// Because of the latter, it will send a bulk inventory update
// if the receiving user is in the same simulator.
public UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID)
{
return CreateCallingCard(userID, creatorID, folderID, false);
}
private UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID, bool isGod)
{
IUserAccountService userv = m_Scenes[0].UserAccountService;
if (userv == null)
return UUID.Zero;
UserAccount info = userv.GetUserAccount(UUID.Zero, creatorID);
if (info == null)
return UUID.Zero;
IInventoryService inv = m_Scenes[0].InventoryService;
if (inv == null)
return UUID.Zero;
if (folderID == UUID.Zero)
{
InventoryFolderBase folder = inv.GetFolderForType(userID,
AssetType.CallingCard);
if (folder == null) // Nowhere to put it
return UUID.Zero;
folderID = folder.ID;
}
m_log.DebugFormat("[XCALLINGCARD]: Creating calling card for {0} in inventory of {1}", info.Name, userID);
InventoryItemBase item = new InventoryItemBase();
item.AssetID = UUID.Zero;
item.AssetType = (int)AssetType.CallingCard;
item.BasePermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify);
if (isGod)
item.BasePermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Move);
item.EveryOnePermissions = (uint)PermissionMask.None;
item.CurrentPermissions = item.BasePermissions;
item.NextPermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify);
item.ID = UUID.Random();
item.CreatorId = creatorID.ToString();
item.Owner = userID;
item.GroupID = UUID.Zero;
item.GroupOwned = false;
item.Folder = folderID;
item.CreationDate = Util.UnixTimeSinceEpoch();
item.InvType = (int)InventoryType.CallingCard;
item.Flags = 0;
item.Name = info.Name;
item.Description = "";
item.SalePrice = 10;
item.SaleType = (byte)SaleType.Not;
inv.AddItem(item);
IClientAPI client = FindClientObject(userID);
if (client != null)
client.SendBulkUpdateInventory(item);
return item.ID;
}
private void OnAcceptCallingCard(IClientAPI client, UUID transactionID, UUID folderID)
{
}
private void OnDeclineCallingCard(IClientAPI client, UUID transactionID)
{
IInventoryService invService = m_Scenes[0].InventoryService;
InventoryFolderBase trashFolder =
invService.GetFolderForType(client.AgentId, AssetType.TrashFolder);
InventoryItemBase item = new InventoryItemBase(transactionID, client.AgentId);
item = invService.GetItem(item);
if (item != null && trashFolder != null)
{
item.Folder = trashFolder.ID;
List<UUID> uuids = new List<UUID>();
uuids.Add(item.ID);
invService.DeleteItems(item.Owner, uuids);
m_Scenes[0].AddInventoryItem(client, item);
}
}
public IClientAPI FindClientObject(UUID agentID)
{
Scene scene = GetClientScene(agentID);
if (scene == null)
return null;
ScenePresence presence = scene.GetScenePresence(agentID);
if (presence == null)
return null;
return presence.ControllingClient;
}
private Scene GetClientScene(UUID agentId)
{
lock (m_Scenes)
{
foreach (Scene scene in m_Scenes)
{
ScenePresence presence = scene.GetScenePresence(agentId);
if (presence != null)
{
if (!presence.IsChildAgent)
return scene;
}
}
}
return null;
}
private ScenePresence GetClientPresence(UUID agentId)
{
lock (m_Scenes)
{
foreach (Scene scene in m_Scenes)
{
ScenePresence presence = scene.GetScenePresence(agentId);
if (presence != null)
{
if (!presence.IsChildAgent)
return presence;
}
}
}
return null;
}
private void OnIncomingInstantMessage(GridInstantMessage msg)
{
if (msg.dialog == (uint)211)
{
IClientAPI client = FindClientObject(new UUID(msg.toAgentID));
if (client == null)
return;
DoCallingCardOffer(client, new UUID(msg.fromAgentID));
}
}
}
}
@@ -51,6 +51,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
public class FriendsModule : ISharedRegionModule, IFriendsModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected bool m_Enabled = false;
protected class UserFriendData
@@ -72,7 +74,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected List<Scene> m_Scenes = new List<Scene>();
@@ -109,7 +110,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
protected IFriendsService FriendsService
public IFriendsService FriendsService
{
get
{
@@ -156,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
InitModule(config);
m_Enabled = true;
m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name);
m_log.DebugFormat("[FRIENDS MODULE]: {0} enabled.", Name);
}
}
}
@@ -201,7 +202,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (!m_Enabled)
return;
m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
// m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
m_Scenes.Add(scene);
scene.RegisterModuleInterface<IFriendsModule>(this);
@@ -212,9 +213,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
scene.EventManager.OnClientLogin += OnClientLogin;
}
public void RegionLoaded(Scene scene)
{
}
public virtual void RegionLoaded(Scene scene) {}
public void RemoveRegion(Scene scene)
{
@@ -236,13 +235,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#endregion
public virtual uint GetFriendPerms(UUID principalID, UUID friendID)
public virtual int GetRightsGrantedByFriend(UUID principalID, UUID friendID)
{
FriendInfo[] friends = GetFriends(principalID);
FriendInfo[] friends = GetFriendsFromCache(principalID);
FriendInfo finfo = GetFriend(friends, friendID);
if (finfo != null)
{
return (uint)finfo.TheirFlags;
return finfo.TheirFlags;
}
return 0;
@@ -253,9 +252,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
client.OnInstantMessage += OnInstantMessage;
client.OnApproveFriendRequest += OnApproveFriendRequest;
client.OnDenyFriendRequest += OnDenyFriendRequest;
client.OnTerminateFriendship += (thisClient, agentID, exfriendID) => RemoveFriendship(thisClient, exfriendID);
client.OnGrantUserRights += OnGrantUserRights;
client.OnTerminateFriendship += RemoveFriendship;
client.OnGrantUserRights += GrantRights;
// We need to cache information for child agents as well as root agents so that friend edit/move/delete
// permissions will work across borders where both regions are on different simulators.
//
// Do not do this asynchronously. If we do, then subsequent code can outrace CacheFriends() and
// return misleading results from the still empty friends cache.
// If we absolutely need to do this asynchronously, then a signalling mechanism is needed so that calls
@@ -328,7 +330,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
//m_log.DebugFormat("[XXX]: OnClientLogin!");
// Inform the friends that this user is online
StatusChange(agentID, true);
// Register that we need to send the list of online friends to this user
lock (m_NeedsListOfOnlineFriends)
m_NeedsListOfOnlineFriends.Add(agentID);
@@ -347,18 +349,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// Send the friends online
List<UUID> online = GetOnlineFriends(agentID);
if (online.Count > 0)
{
m_log.DebugFormat(
"[FRIENDS MODULE]: User {0} in region {1} has {2} friends online",
client.Name, client.Scene.RegionInfo.RegionName, online.Count);
if (online.Count > 0)
client.SendAgentOnline(online.ToArray());
}
// Send outstanding friendship offers
List<string> outstanding = new List<string>();
FriendInfo[] friends = GetFriends(agentID);
FriendInfo[] friends = GetFriendsFromCache(agentID);
foreach (FriendInfo fi in friends)
{
if (fi.TheirFlags == -1)
@@ -414,23 +411,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
List<UUID> GetOnlineFriends(UUID userID)
{
List<string> friendList = new List<string>();
List<UUID> online = new List<UUID>();
FriendInfo[] friends = GetFriends(userID);
FriendInfo[] friends = GetFriendsFromCache(userID);
foreach (FriendInfo fi in friends)
{
if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1))
if (((fi.TheirFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1))
friendList.Add(fi.Friend);
}
List<UUID> online = new List<UUID>();
if (friendList.Count > 0)
GetOnlineFriends(userID, friendList, online);
// m_log.DebugFormat(
// "[FRIENDS MODULE]: User {0} has {1} friends online", userID, online.Count);
return online;
}
protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
{
// m_log.DebugFormat(
// "[FRIENDS MODULE]: Looking for online presence of {0} users for {1}", friendList.Count, userID);
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
foreach (PresenceInfo pi in presence)
{
@@ -481,13 +485,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
/// <param name="online"></param>
private void StatusChange(UUID agentID, bool online)
{
FriendInfo[] friends = GetFriends(agentID);
FriendInfo[] friends = GetFriendsFromCache(agentID);
if (friends.Length > 0)
{
List<FriendInfo> friendList = new List<FriendInfo>();
foreach (FriendInfo fi in friends)
{
if (((fi.MyFlags & 1) != 0) && (fi.TheirFlags != -1))
if (((fi.MyFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1))
friendList.Add(fi);
}
@@ -550,7 +554,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
UUID principalID = new UUID(im.fromAgentID);
UUID friendID = new UUID(im.toAgentID);
m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2}", principalID, im.fromAgentName, friendID);
m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2} ({3})", principalID, client.FirstName + client.LastName, friendID, im.fromAgentName);
// Check that the friendship doesn't exist yet
FriendInfo[] finfos = GetFriendsFromCache(principalID);
if (finfos != null)
{
FriendInfo f = GetFriend(finfos, friendID);
if (f != null)
{
client.SendAgentAlertMessage("This person is already your friend. Please delete it first if you want to reestablish the friendship.", false);
return;
}
}
// This user wants to be friends with the other user.
// Let's add the relation backwards, in case the other is not online
@@ -561,7 +577,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
protected virtual bool ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
{
// !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
// We stick this agent's ID as imSession, so that it's directly available on the receiving end
@@ -570,7 +586,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// Try the local sim
if (LocalFriendshipOffered(friendID, im))
return;
return true;
// The prospective friend is not here [as root]. Let's forward.
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
@@ -581,9 +597,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message);
return true;
}
}
// If the prospective friend is not online, he'll get the message upon login.
return false;
}
protected virtual string GetFriendshipRequesterName(UUID agentID)
@@ -592,7 +610,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
}
private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
protected virtual void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders)
{
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID);
@@ -603,7 +621,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
StoreFriendships(client.AgentId, friendID);
// Update the local cache
ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>();
if (ccm != null)
{
ccm.CreateCallingCard(client.AgentId, friendID, UUID.Zero);
}
// Update the local cache.
RecacheFriends(client);
//
@@ -631,18 +655,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
private void OnDenyFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders)
{
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", client.AgentId, friendID);
DeleteFriendship(agentID, friendID);
DeleteFriendship(client.AgentId, friendID);
//
// Notify the friend
//
// Try local
if (LocalFriendshipDenied(agentID, client.Name, friendID))
if (LocalFriendshipDenied(client.AgentId, client.Name, friendID))
return;
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
@@ -653,7 +677,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
if (region != null)
m_FriendsSimConnector.FriendshipDenied(region, agentID, client.Name, friendID);
m_FriendsSimConnector.FriendshipDenied(region, client.AgentId, client.Name, friendID);
else
m_log.WarnFormat("[FRIENDS]: Could not find region {0} in locating {1}", friendSession.RegionID, friendID);
}
@@ -690,23 +714,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
public void GrantRights(IClientAPI remoteClient, UUID friendID, int rights)
{
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
UUID requester = remoteClient.AgentId;
FriendInfo[] friends = GetFriends(remoteClient.AgentId);
m_log.DebugFormat(
"[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}",
requester, rights, friendID);
FriendInfo[] friends = GetFriendsFromCache(requester);
if (friends.Length == 0)
{
return;
}
// Let's find the friend in this user's friend list
FriendInfo friend = GetFriend(friends, target);
FriendInfo friend = GetFriend(friends, friendID);
if (friend != null) // Found it
{
// Store it on the DB
if (!StoreRights(requester, target, rights))
if (!StoreRights(requester, friendID, rights))
{
remoteClient.SendAlertMessage("Unable to grant rights.");
return;
@@ -717,17 +745,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
friend.MyFlags = rights;
// Always send this back to the original client
remoteClient.SendChangeUserRights(requester, target, rights);
remoteClient.SendChangeUserRights(requester, friendID, rights);
//
// Notify the friend
//
// Try local
if (LocalGrantRights(requester, target, myFlags, rights))
if (LocalGrantRights(requester, friendID, myFlags, rights))
return;
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() });
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
if (friendSessions != null && friendSessions.Length > 0)
{
PresenceInfo friendSession = friendSessions[0];
@@ -736,12 +764,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
// TODO: You might want to send the delta to save the lookup
// on the other end!!
m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights);
m_FriendsSimConnector.GrantRights(region, requester, friendID, myFlags, rights);
}
}
}
else
m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester);
{
m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", friendID, requester);
}
}
protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
@@ -756,7 +786,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#region Local
public bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
public virtual bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
{
IClientAPI friendClient = LocateClientObject(toID);
if (friendClient != null)
@@ -779,6 +809,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
(byte)OpenMetaverse.InstantMessageDialog.FriendshipAccepted, userID.ToString(), false, Vector3.Zero);
friendClient.SendInstantMessage(im);
ICallingCardModule ccm = friendClient.Scene.RequestModuleInterface<ICallingCardModule>();
if (ccm != null)
{
ccm.CreateCallingCard(friendID, userID, UUID.Zero);
}
// Update the local cache
RecacheFriends(friendClient);
@@ -801,7 +837,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// we're done
return true;
}
return false;
}
@@ -853,7 +889,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
public bool LocalStatusNotification(UUID userID, UUID friendID, bool online)
{
// m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
//m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
IClientAPI friendClient = LocateClientObject(friendID);
if (friendClient != null)
{
@@ -872,18 +908,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#endregion
#region Get / Set friends in several flavours
/// <summary>
/// Get friends from local cache only
/// </summary>
/// <param name="agentID"></param>
/// <returns></returns>
protected FriendInfo[] GetFriends(UUID agentID)
public FriendInfo[] GetFriendsFromCache(UUID userID)
{
UserFriendData friendsData;
lock (m_Friends)
{
if (m_Friends.TryGetValue(agentID, out friendsData))
if (m_Friends.TryGetValue(userID, out friendsData))
return friendsData.Friends;
}
@@ -901,18 +933,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// Update local cache
lock (m_Friends)
{
FriendInfo[] friends = GetFriends(friendID);
FriendInfo[] friends = GetFriendsFromCache(friendID);
FriendInfo finfo = GetFriend(friends, userID);
finfo.TheirFlags = rights;
}
}
protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
public virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
{
return FriendsService.GetFriends(client.AgentId);
}
private void RecacheFriends(IClientAPI client)
protected void RecacheFriends(IClientAPI client)
{
// FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
// is on the critical path for transferring an avatar from one region to another.
@@ -925,6 +957,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
public bool AreFriendsCached(UUID userID)
{
lock (m_Friends)
return m_Friends.ContainsKey(userID);
}
protected virtual bool StoreRights(UUID agentID, UUID friendID, int rights)
{
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights);
@@ -938,8 +976,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
protected virtual void StoreFriendships(UUID agentID, UUID friendID)
{
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), (int)FriendRights.CanSeeOnline);
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), (int)FriendRights.CanSeeOnline);
}
protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
@@ -51,7 +51,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
IUserManagement m_uMan;
IUserManagement UserManagementModule
public IUserManagement UserManagementModule
{
get
{
@@ -61,6 +61,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
protected HGFriendsServicesConnector m_HGFriendsConnector = new HGFriendsServicesConnector();
protected HGStatusNotifier m_StatusNotifier;
#region ISharedRegionModule
public override string Name
{
@@ -76,6 +79,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
scene.RegisterModuleInterface<IFriendsSimConnector>(this);
}
public override void RegionLoaded(Scene scene)
{
if (!m_Enabled)
return;
if (m_StatusNotifier == null)
m_StatusNotifier = new HGStatusNotifier(this);
}
#endregion
#region IFriendsSimConnector
@@ -94,6 +105,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#endregion
protected override void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders)
{
// Update the local cache. Yes, we need to do it right here
// because the HGFriendsService placed something on the DB
// from under the sim
base.OnApproveFriendRequest(client, friendID, callingCardFolders);
}
protected override bool CacheFriends(IClientAPI client)
{
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name);
@@ -144,7 +163,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId);
if (account == null) // foreign
{
FriendInfo[] friends = GetFriends(client.AgentId);
FriendInfo[] friends = GetFriendsFromCache(client.AgentId);
foreach (FriendInfo f in friends)
{
client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags);
@@ -183,91 +202,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID);
}
//protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
//{
// // Let's single out the UUIs
// List<string> localFriends = new List<string>();
// List<string> foreignFriends = new List<string>();
// string tmp = string.Empty;
// foreach (string s in friendList)
// {
// UUID id;
// if (UUID.TryParse(s, out id))
// localFriends.Add(s);
// else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
// {
// foreignFriends.Add(s);
// // add it here too, who knows maybe the foreign friends happens to be on this grid
// localFriends.Add(id.ToString());
// }
// }
// // OK, see who's present on this grid
// List<string> toBeRemoved = new List<string>();
// PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
// foreach (PresenceInfo pi in presence)
// {
// UUID presenceID;
// if (UUID.TryParse(pi.UserID, out presenceID))
// {
// online.Add(presenceID);
// foreach (string s in foreignFriends)
// if (s.StartsWith(pi.UserID))
// toBeRemoved.Add(s);
// }
// }
// foreach (string s in toBeRemoved)
// foreignFriends.Remove(s);
// // OK, let's send this up the stack, and leave a closure here
// // collecting online friends in other grids
// Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
//}
//private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
//{
// // let's divide the friends on a per-domain basis
// Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
// foreach (string friend in foreignFriends)
// {
// UUID friendID;
// if (!UUID.TryParse(friend, out friendID))
// {
// // it's a foreign friend
// string url = string.Empty, tmp = string.Empty;
// if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
// {
// if (!friendsPerDomain.ContainsKey(url))
// friendsPerDomain[url] = new List<string>();
// friendsPerDomain[url].Add(friend);
// }
// }
// }
// // Now, call those worlds
// foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
// {
// List<string> ids = new List<string>();
// foreach (string f in kvp.Value)
// ids.Add(f);
// UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
// List<UUID> online = uConn.GetOnlineFriends(userID, ids);
// // Finally send the notifications to the user
// // this whole process may take a while, so let's check at every
// // iteration that the user is still here
// IClientAPI client = LocateClientObject(userID);
// if (client != null)
// client.SendAgentOnline(online.ToArray());
// else
// break;
// }
//}
protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
{
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID);
@@ -305,25 +239,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (friendsPerDomain.ContainsKey("local"))
base.StatusNotify(friendsPerDomain["local"], userID, online);
foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
{
if (kvp.Key != "local")
{
// For the others, call the user agent service
List<string> ids = new List<string>();
foreach (FriendInfo f in kvp.Value)
ids.Add(f.Friend);
UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
List<UUID> friendsOnline = uConn.StatusNotification(ids, userID, online);
if (online && friendsOnline.Count > 0)
{
IClientAPI client = LocateClientObject(userID);
if (client != null)
client.SendAgentOnline(friendsOnline.ToArray());
}
}
}
m_StatusNotifier.Notify(userID, friendsPerDomain, online);
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting StatusNotify for {0}", userID);
}
@@ -335,26 +251,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return true;
// fid is not a UUID...
string url = string.Empty, tmp = string.Empty;
if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp))
string url = string.Empty, tmp = string.Empty, f = string.Empty, l = string.Empty;
if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out f, out l, out tmp))
{
IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
userMan.AddUser(agentID, first, last, url);
if (!agentID.Equals(UUID.Zero))
{
m_uMan.AddUser(agentID, f, l, url);
return true;
string name = m_uMan.GetUserName(agentID);
string[] parts = name.Trim().Split(new char[] { ' ' });
if (parts.Length == 2)
{
first = parts[0];
last = parts[1];
}
else
{
first = f;
last = l;
}
return true;
}
}
return false;
}
protected override string GetFriendshipRequesterName(UUID agentID)
{
// For the time being we assume that HG friendship requests can only happen
// when avies are on the same region.
IClientAPI client = LocateClientObject(agentID);
if (client != null)
return client.FirstName + " " + client.LastName;
else
return base.GetFriendshipRequesterName(agentID);
return m_uMan.GetUserName(agentID);
}
protected override string FriendshipMessage(string friendID)
@@ -376,8 +300,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return null;
}
protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
public override FriendInfo[] GetFriendsFromService(IClientAPI client)
{
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name);
Boolean agentIsLocal = true;
@@ -392,10 +315,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
if (agentClientCircuit != null)
{
string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
//[XXX] string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
finfos = FriendsService.GetFriends(agentUUI);
m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
finfos = FriendsService.GetFriends(client.AgentId.ToString());
m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, client.AgentId.ToString());
}
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name);
@@ -422,7 +345,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (agentIsLocal) // agent is local, friend is foreigner
{
FriendInfo[] finfos = GetFriends(agentID);
FriendInfo[] finfos = GetFriendsFromCache(agentID);
FriendInfo finfo = GetFriend(finfos, friendID);
if (finfo != null)
{
@@ -454,16 +377,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
friendIsLocal = UserManagementModule.IsLocalGridUser(friendID);
}
// Are they both local users?
if (agentIsLocal && friendIsLocal)
// Is the requester a local user?
if (agentIsLocal)
{
// local grid users
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
m_log.DebugFormat("[HGFRIENDS MODULE]: Friendship requester is local. Storing backwards.");
base.StoreBackwards(friendID, agentID);
return;
}
// no provision for this temporary friendship state
// no provision for this temporary friendship state when user is not local
//FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
}
@@ -501,12 +425,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
RecacheFriends(agentClient);
}
if (friendClient != null)
{
friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
RecacheFriends(friendClient);
}
m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
@@ -515,14 +441,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// Generate a random 8-character hex number that will sign this friendship
string secret = UUID.Random().ToString().Substring(0, 8);
string theFriendUUID = friendUUI + ";" + secret;
string agentUUID = agentUUI + ";" + secret;
if (agentIsLocal) // agent is local, 'friend' is foreigner
{
// This may happen when the agent returned home, in which case the friend is not there
// We need to look for its information in the friends list itself
FriendInfo[] finfos = null;
bool confirming = false;
if (friendUUI == string.Empty)
{
FriendInfo[] finfos = GetFriends(agentID);
finfos = GetFriendsFromCache(agentID);
foreach (FriendInfo finfo in finfos)
{
if (finfo.TheirFlags == -1)
@@ -530,29 +460,57 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (finfo.Friend.StartsWith(friendID.ToString()))
{
friendUUI = finfo.Friend;
theFriendUUID = friendUUI;
UUID utmp = UUID.Zero; String url = String.Empty; String first = String.Empty, last = String.Empty, tmp = String.Empty;
// If it's confirming the friendship, we already have the full UUI with the secret
if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret))
{
agentUUID = agentUUI + ";" + secret;
m_uMan.AddUser(utmp, first, last, url);
}
confirming = true;
break;
}
}
}
}
if (!confirming)
{
friendUUI = m_uMan.GetUserUUI(friendID);
theFriendUUID = friendUUI + ";" + secret;
}
// If it's confirming the friendship, we already have the full friendUUI with the secret
string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret;
friendFriendService = m_uMan.GetUserServerURL(friendID, "FriendsServerURI");
// m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
// agentUUI, friendUUI, agentFriendService, friendFriendService);
}
// Delete any previous friendship relations
DeletePreviousRelations(agentID, friendID);
// store in the local friends service a reference to the foreign friend
FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
// and also the converse
FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
if (!confirming && friendClientCircuit != null)
{
//if (!confirming)
//{
// store in the foreign friends service a reference to the local agent
HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
}
HGFriendsServicesConnector friendsConn = null;
if (friendClientCircuit != null) // the friend is here, validate session
friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
else // the friend is not here, he initiated the request in his home world
friendsConn = new HGFriendsServicesConnector(friendFriendService);
friendsConn.NewFriendship(friendID, agentUUID);
//}
}
else if (friendIsLocal) // 'friend' is local, agent is foreigner
{
// Delete any previous friendship relations
DeletePreviousRelations(agentID, friendID);
// store in the local friends service a reference to the foreign agent
FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
// and also the converse
@@ -582,6 +540,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// my brain hurts now
}
private void DeletePreviousRelations(UUID a1, UUID a2)
{
// Delete any previous friendship relations
FriendInfo[] finfos = null;
FriendInfo f = null;
finfos = GetFriendsFromCache(a1);
if (finfos != null)
{
f = GetFriend(finfos, a2);
if (f != null)
{
FriendsService.Delete(a1, f.Friend);
// and also the converse
FriendsService.Delete(f.Friend, a1.ToString());
}
}
finfos = GetFriendsFromCache(a2);
if (finfos != null)
{
f = GetFriend(finfos, a1);
if (f != null)
{
FriendsService.Delete(a2, f.Friend);
// and also the converse
FriendsService.Delete(f.Friend, a2.ToString());
}
}
}
protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
{
Boolean agentIsLocal = true;
@@ -606,7 +594,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (agentIsLocal) // agent is local, 'friend' is foreigner
{
// We need to look for its information in the friends list itself
FriendInfo[] finfos = GetFriends(agentID);
FriendInfo[] finfos = GetFriendsFromCache(agentID);
FriendInfo finfo = GetFriend(finfos, exfriendID);
if (finfo != null)
{
@@ -650,7 +638,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private string GetUUI(UUID localUser, UUID foreignUser)
{
// Let's see if the user is here by any chance
FriendInfo[] finfos = GetFriends(localUser);
FriendInfo[] finfos = GetFriendsFromCache(localUser);
if (finfos != EMPTY_FRIENDS) // friend is here, cool
{
FriendInfo finfo = GetFriend(finfos, foreignUser);
@@ -684,5 +672,80 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
friendConn.DeleteFriendship(foreignUser, localUser, secret);
}
}
protected override bool ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
{
if (base.ForwardFriendshipOffer(agentID, friendID, im))
return true;
// OK, that didn't work, so let's try to find this user somewhere
if (!m_uMan.IsLocalGridUser(friendID))
{
string friendsURL = m_uMan.GetUserServerURL(friendID, "FriendsServerURI");
if (friendsURL != string.Empty)
{
m_log.DebugFormat("[HGFRIENDS MODULE]: Forwading friendship from {0} to {1} @ {2}", agentID, friendID, friendsURL);
GridRegion region = new GridRegion();
region.ServerURI = friendsURL;
string name = im.fromAgentName;
if (m_uMan.IsLocalGridUser(agentID))
{
IClientAPI agentClient = LocateClientObject(agentID);
AgentCircuitData agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
string agentHomeService = string.Empty;
try
{
agentHomeService = agentClientCircuit.ServiceURLs["HomeURI"].ToString();
string lastname = "@" + new Uri(agentHomeService).Authority;
string firstname = im.fromAgentName.Replace(" ", ".");
name = firstname + lastname;
}
catch (KeyNotFoundException)
{
m_log.DebugFormat("[HGFRIENDS MODULE]: Key HomeURI not found for user {0}", agentID);
return false;
}
catch (NullReferenceException)
{
m_log.DebugFormat("[HGFRIENDS MODULE]: Null HomeUri for local user {0}", agentID);
return false;
}
catch (UriFormatException)
{
m_log.DebugFormat("[HGFRIENDS MODULE]: Malformed HomeUri {0} for local user {1}", agentHomeService, agentID);
return false;
}
}
m_HGFriendsConnector.FriendshipOffered(region, agentID, friendID, im.message, name);
return true;
}
}
return false;
}
public override bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
{
if (base.LocalFriendshipOffered(toID, im))
{
if (im.fromAgentName.Contains("@"))
{
string[] parts = im.fromAgentName.Split(new char[] { '@' });
if (parts.Length == 2)
{
string[] fl = parts[0].Trim().Split(new char[] { '.' });
if (fl.Length == 2)
m_uMan.AddUser(new UUID(im.fromAgentID), fl[0], fl[1], "http://" + parts[1]);
else
m_uMan.AddUser(new UUID(im.fromAgentID), fl[0], "", "http://" + parts[1]);
}
}
return true;
}
return false;
}
}
}
@@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Services.Interfaces;
using OpenSim.Services.Connectors.Hypergrid;
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
using OpenMetaverse;
using log4net;
namespace OpenSim.Region.CoreModules.Avatar.Friends
{
public class HGStatusNotifier
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private HGFriendsModule m_FriendsModule;
public HGStatusNotifier(HGFriendsModule friendsModule)
{
m_FriendsModule = friendsModule;
}
public void Notify(UUID userID, Dictionary<string, List<FriendInfo>> friendsPerDomain, bool online)
{
foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
{
if (kvp.Key != "local")
{
// For the others, call the user agent service
List<string> ids = new List<string>();
foreach (FriendInfo f in kvp.Value)
ids.Add(f.Friend);
if (ids.Count == 0)
continue; // no one to notify. caller don't do this
m_log.DebugFormat("[HG STATUS NOTIFIER]: Notifying {0} friends in {1}", ids.Count, kvp.Key);
// ASSUMPTION: we assume that all users for one home domain
// have exactly the same set of service URLs.
// If this is ever not true, we need to change this.
UUID friendID = UUID.Zero; String tmp = String.Empty;
if (Util.ParseUniversalUserIdentifier(ids[0], out friendID, out tmp, out tmp, out tmp, out tmp))
{
string friendsServerURI = m_FriendsModule.UserManagementModule.GetUserServerURL(friendID, "FriendsServerURI");
if (friendsServerURI != string.Empty)
{
HGFriendsServicesConnector fConn = new HGFriendsServicesConnector(friendsServerURI);
List<UUID> friendsOnline = fConn.StatusNotification(ids, userID, online);
if (online && friendsOnline.Count > 0)
{
IClientAPI client = m_FriendsModule.LocateClientObject(userID);
if (client != null)
client.SendAgentOnline(friendsOnline.ToArray());
}
}
}
}
}
}
}
}
@@ -30,6 +30,7 @@ using System.Collections.Generic;
using Nini.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenSim.Data.Null;
using OpenSim.Framework;
using OpenSim.Region.CoreModules.Avatar.Friends;
using OpenSim.Region.Framework.Scenes;
@@ -44,9 +45,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
private FriendsModule m_fm;
private TestScene m_scene;
[TestFixtureSetUp]
public void FixtureInit()
{
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
}
[TestFixtureTearDown]
public void TearDown()
{
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
// threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
// tests really shouldn't).
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
}
[SetUp]
public void Init()
{
// We must clear friends data between tests since Data.Null holds it in static properties. This is necessary
// so that different services and simulator can share the data in standalone mode. This is pretty horrible
// effectively the statics are global variables.
NullFriendsData.Clear();
IConfigSource config = new IniConfigSource();
config.AddConfig("Modules");
// Not strictly necessary since FriendsModule assumes it is the default (!)
@@ -62,7 +84,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
}
[Test]
public void TestNoFriends()
public void TestLoginWithNoFriends()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
@@ -75,6 +97,76 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
Assert.That(((TestClient)sp.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0));
}
[Test]
public void TestLoginWithOfflineFriends()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
UUID user1Id = TestHelpers.ParseTail(0x1);
UUID user2Id = TestHelpers.ParseTail(0x2);
// UserAccountHelpers.CreateUserWithInventory(m_scene, user1Id);
// UserAccountHelpers.CreateUserWithInventory(m_scene, user2Id);
//
// m_fm.AddFriendship(user1Id, user2Id);
ScenePresence sp1 = SceneHelpers.AddScenePresence(m_scene, user1Id);
ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, user2Id);
m_fm.AddFriendship(sp1.ControllingClient, user2Id);
// Not necessary for this test. CanSeeOnline is automatically granted.
// m_fm.GrantRights(sp1.ControllingClient, user2Id, (int)FriendRights.CanSeeOnline);
// We must logout from the client end so that the presence service is correctly updated by the presence
// detector. This is listening to the OnConnectionClosed event on the client.
((TestClient)sp1.ControllingClient).Logout();
((TestClient)sp2.ControllingClient).Logout();
// m_scene.RemoveClient(sp1.UUID, true);
// m_scene.RemoveClient(sp2.UUID, true);
ScenePresence sp1Redux = SceneHelpers.AddScenePresence(m_scene, user1Id);
// We don't expect to receive notifications of offline friends on login, just online.
Assert.That(((TestClient)sp1Redux.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0));
Assert.That(((TestClient)sp1Redux.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0));
}
[Test]
public void TestLoginWithOnlineFriends()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
UUID user1Id = TestHelpers.ParseTail(0x1);
UUID user2Id = TestHelpers.ParseTail(0x2);
// UserAccountHelpers.CreateUserWithInventory(m_scene, user1Id);
// UserAccountHelpers.CreateUserWithInventory(m_scene, user2Id);
//
// m_fm.AddFriendship(user1Id, user2Id);
ScenePresence sp1 = SceneHelpers.AddScenePresence(m_scene, user1Id);
ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, user2Id);
m_fm.AddFriendship(sp1.ControllingClient, user2Id);
// Not necessary for this test. CanSeeOnline is automatically granted.
// m_fm.GrantRights(sp1.ControllingClient, user2Id, (int)FriendRights.CanSeeOnline);
// We must logout from the client end so that the presence service is correctly updated by the presence
// detector. This is listening to the OnConnectionClosed event on the client.
// ((TestClient)sp1.ControllingClient).Logout();
((TestClient)sp2.ControllingClient).Logout();
// m_scene.RemoveClient(user2Id, true);
ScenePresence sp2Redux = SceneHelpers.AddScenePresence(m_scene, user2Id);
Assert.That(((TestClient)sp2Redux.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0));
Assert.That(((TestClient)sp2Redux.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(1));
}
[Test]
public void TestAddFriendshipWhileOnline()
{
@@ -270,12 +270,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_archiveWriter = new TarArchiveWriter(m_saveStream);
m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive.");
// Write out control file. This has to be done first so that subsequent loaders will see this file first
// XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
// not sure how to fix this though, short of going with a completely different file format.
m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
m_log.InfoFormat("[INVENTORY ARCHIVER]: Added control file to archive.");
if (inventoryFolder != null)
{
m_log.DebugFormat(
@@ -108,7 +108,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted;
scene.AddCommand(
this, "load iar",
"Archiving", this, "load iar",
"load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]",
"Load user inventory archive (IAR).",
"-m|--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones"
@@ -121,18 +121,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
HandleLoadInvConsoleCommand);
scene.AddCommand(
this, "save iar",
"Archiving", this, "save iar",
"save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-v|--verbose]",
"Save user inventory archive (IAR).",
"<first> is the user's first name." + Environment.NewLine
+ "<last> is the user's last name." + Environment.NewLine
+ "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine
+ "-h|--home=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
+ "-c|--creators preserves information about foreign creators." + Environment.NewLine
+ "-v|--verbose extra debug messages." + Environment.NewLine
+ "--noassets stops assets being saved to the IAR."
"<first> is the user's first name.\n"
+ "<last> is the user's last name.\n"
+ "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n"
+ "<IAR path> is the filesystem path at which to save the IAR."
+ string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
+ string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME)
+ "-h|--home=<url> adds the url of the profile service to the saved user information.\n"
+ "-c|--creators preserves information about foreign creators.\n"
+ "-v|--verbose extra debug messages.\n"
+ "--noassets stops assets being saved to the IAR.",
HandleSaveInvConsoleCommand);
m_aScene = scene;
@@ -150,7 +150,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
string skillsText = String.Empty;
string languages = String.Empty;
Byte[] charterMember = Utils.StringToBytes("Avatar");
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, avatarID);
string name = "Avatar";
int created = 0;
if (account != null)
{
name = account.FirstName + " " + account.LastName;
created = account.Created;
}
Byte[] charterMember = Utils.StringToBytes(name);
profileUrl = "No profile data";
aboutText = string.Empty;
@@ -160,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
partner = UUID.Zero;
remoteClient.SendAvatarProperties(avatarID, aboutText,
Util.ToDateTime(0).ToString(
Util.ToDateTime(created).ToString(
"M/d/yyyy", CultureInfo.InvariantCulture),
charterMember, firstLifeAboutText,
(uint)(0 & 0xff),
@@ -69,9 +69,10 @@ namespace OpenSim.Region.CoreModules.Framework
{
m_scene = scene;
m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps",
MainConsole.Instance.Commands.AddCommand("Comms", false, "show caps",
"show caps",
"Shows all registered capabilities", HandleShowCapsCommand);
"Shows all registered capabilities for users", HandleShowCapsCommand);
}
public void RegionLoaded(Scene scene)
@@ -36,6 +36,7 @@ using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Client;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Physics.Manager;
using OpenSim.Services.Interfaces;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
@@ -60,6 +61,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
set { m_MaxTransferDistance = value; }
}
private int m_levelHGTeleport = 0;
protected bool m_Enabled = false;
protected Scene m_aScene;
protected List<Scene> m_Scenes = new List<Scene>();
@@ -101,7 +104,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
IConfig transferConfig = source.Configs["EntityTransfer"];
if (transferConfig != null)
{
MaxTransferDistance = transferConfig.GetInt("max_distance", 4095);
m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0);
}
m_agentsInTransit = new List<UUID>();
m_Enabled = true;
@@ -227,6 +233,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return;
}
// check if HyperGrid teleport is allowed, based on user level
int flags = m_aScene.GridService.GetRegionFlags(sp.Scene.RegionInfo.ScopeID, reg.RegionID);
if (((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) && (sp.UserLevel < m_levelHGTeleport))
{
m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Final destination link is non permitted hypergrid region. Unable to teleport agent.");
sp.ControllingClient.SendTeleportFailed("HyperGrid teleport not permitted");
return;
}
uint curX = 0, curY = 0;
Utils.LongToUInts(sp.Scene.RegionInfo.RegionHandle, out curX, out curY);
int curCellX = (int)(curX / Constants.RegionSize);
@@ -304,6 +320,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return;
}
if (IsInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this.
return;
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Request Teleport to {0} ({1}) {2}/{3}",
reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
@@ -444,7 +463,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
"[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Returning avatar to source region.",
sp.Name, finalDestination.RegionName);
Fail(sp, finalDestination);
Fail(sp, finalDestination, logout);
return;
}
@@ -476,7 +495,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
"[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} failed due to no callback from destination region. Returning avatar to source region.",
sp.Name, finalDestination.RegionName);
Fail(sp, finalDestination);
Fail(sp, finalDestination, logout);
return;
}
@@ -527,7 +546,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
}
private void Fail(ScenePresence sp, GridRegion finalDestination)
protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout)
{
// Client never contacted destination. Let's restore everything back
sp.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
@@ -542,12 +561,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Finally, kill the agent we just created at the destination.
m_aScene.SimulationService.CloseAgent(finalDestination, sp.UUID);
sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout);
}
protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)
{
logout = false;
return m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason);
bool success = m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason);
if (success)
sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
return success;
}
protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent)
@@ -1785,10 +1810,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
if (!grp.IsDeleted)
{
if (grp.RootPart.PhysActor != null)
{
grp.RootPart.PhysActor.CrossingFailure();
}
PhysicsActor pa = grp.RootPart.PhysActor;
if (pa != null)
pa.CrossingFailure();
}
m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
@@ -1861,6 +1885,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
}
protected bool IsInTransit(UUID id)
{
lock (m_agentsInTransit)
{
if (m_agentsInTransit.Contains(id))
return true;
}
return false;
}
protected bool ResetFromTransit(UUID id)
{
lock (m_agentsInTransit)
@@ -30,6 +30,7 @@ using System.Collections.Generic;
using System.Reflection;
using OpenSim.Framework;
using OpenSim.Framework.Client;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Connectors.Hypergrid;
@@ -89,7 +90,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
}
public override void RegionLoaded(Scene scene)
{
base.RegionLoaded(scene);
@@ -98,6 +98,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService);
m_Initialized = true;
}
}
@@ -170,6 +171,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason);
logout = success; // flag for later logout from this grid; this is an HG TP
if (success)
sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
return success;
}
else
@@ -179,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
}
return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason);
return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout);
}
public override void TeleportHome(UUID id, IClientAPI client)
@@ -337,6 +341,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#endregion
private GridRegion MakeRegion(AgentCircuitData aCircuit)
{
GridRegion region = new GridRegion();
@@ -353,5 +358,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0);
return region;
}
}
}
@@ -30,6 +30,7 @@ using System.Collections.Generic;
using System.Reflection;
using OpenSim.Framework;
using OpenSim.Framework.Client;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Connectors.Hypergrid;
@@ -57,6 +58,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
private string m_HomeURI;
private bool m_OutboundPermission;
private string m_ThisGatekeeper;
private bool m_RestrictInventoryAccessAbroad;
// private bool m_Initialized = false;
@@ -90,6 +92,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
m_HomeURI = thisModuleConfig.GetString("HomeURI", m_HomeURI);
m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", false);
}
else
m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
@@ -105,19 +108,85 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
base.AddRegion(scene);
m_assMapper = new HGAssetMapper(scene, m_HomeURI);
scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
scene.EventManager.OnTeleportStart += TeleportStart;
scene.EventManager.OnTeleportFail += TeleportFail;
}
#endregion
#region Event handlers
protected override void OnNewClient(IClientAPI client)
{
base.OnNewClient(client);
client.OnCompleteMovementToRegion += new Action<IClientAPI, bool>(OnCompleteMovementToRegion);
}
protected void OnCompleteMovementToRegion(IClientAPI client, bool arg2)
{
//m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: OnCompleteMovementToRegion of user {0}", client.Name);
object sp = null;
if (client.Scene.TryGetScenePresence(client.AgentId, out sp))
{
if (sp is ScenePresence)
{
AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId);
if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
{
if (m_RestrictInventoryAccessAbroad)
{
IUserManagement uMan = m_Scene.RequestModuleInterface<IUserManagement>();
if (uMan.IsLocalGridUser(client.AgentId))
ProcessInventoryForComingHome(client);
else
ProcessInventoryForArriving(client);
}
}
}
}
}
protected void TeleportStart(IClientAPI client, GridRegion destination, GridRegion finalDestination, uint teleportFlags, bool gridLogout)
{
if (gridLogout && m_RestrictInventoryAccessAbroad)
{
IUserManagement uMan = m_Scene.RequestModuleInterface<IUserManagement>();
if (uMan != null && uMan.IsLocalGridUser(client.AgentId))
{
// local grid user
ProcessInventoryForHypergriding(client);
}
else
{
// Foreigner
ProcessInventoryForLeaving(client);
}
}
}
protected void TeleportFail(IClientAPI client, bool gridLogout)
{
if (gridLogout && m_RestrictInventoryAccessAbroad)
{
IUserManagement uMan = m_Scene.RequestModuleInterface<IUserManagement>();
if (uMan.IsLocalGridUser(client.AgentId))
{
ProcessInventoryForComingHome(client);
}
else
{
ProcessInventoryForArriving(client);
}
}
}
public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
{
string userAssetServer = string.Empty;
if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
{
Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
m_assMapper.Post(assetID, avatarID, userAssetServer);
}
}
@@ -236,8 +305,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
return false;
}
#endregion
protected override InventoryItemBase GetItem(UUID agentID, UUID itemID)
{
InventoryItemBase item = base.GetItem(agentID, itemID);
@@ -248,5 +315,84 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
return item;
}
#endregion
#region Inventory manipulation upon arriving/leaving
//
// These 2 are for local and foreign users coming back, respectively
//
private void ProcessInventoryForComingHome(IClientAPI client)
{
m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Restoring root folder for local user {0}", client.Name);
if (client is IClientCore)
{
IClientCore core = (IClientCore)client;
IClientInventory inv;
if (core.TryGet<IClientInventory>(out inv))
{
InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId);
InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID);
inv.SendBulkUpdateInventory(content.Folders.ToArray(), content.Items.ToArray());
}
}
}
private void ProcessInventoryForArriving(IClientAPI client)
{
}
//
// These 2 are for local and foreign users going away respectively
//
private void ProcessInventoryForHypergriding(IClientAPI client)
{
if (client is IClientCore)
{
IClientCore core = (IClientCore)client;
IClientInventory inv;
if (core.TryGet<IClientInventory>(out inv))
{
InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId);
if (root != null)
{
m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Changing root inventory for user {0}", client.Name);
InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID);
List<UUID> fids = new List<UUID>();
List<UUID> iids = new List<UUID>();
List<InventoryFolderBase> keep = new List<InventoryFolderBase>();
foreach (InventoryFolderBase f in content.Folders)
{
if (f.Name != "My Suitcase")
{
f.Name = f.Name + " (Unavailable)";
keep.Add(f);
}
}
// items directly under the root folder
foreach (InventoryItemBase it in content.Items)
it.Name = it.Name + " (Unavailable)"; ;
// Send the new names
inv.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray());
}
}
}
}
private void ProcessInventoryForLeaving(IClientAPI client)
{
}
#endregion
}
}
@@ -654,9 +654,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
//
if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
{
if (so.RootPart.FromFolderID != UUID.Zero && userID == remoteClient.AgentId)
if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId)
{
InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID);
InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID);
folder = m_Scene.InventoryService.GetFolder(f);
}
}
@@ -935,6 +935,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment))
remoteClient.SendBulkUpdateInventory(item);
ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
remoteClient.SendAlertMessage(string.Format(
"Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.",
item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.RegionInfo.RegionName));
return false;
}
@@ -957,7 +962,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
rootPart.SalePrice = item.SalePrice;
}
rootPart.FromFolderID = item.Folder;
so.FromFolderID = item.Folder;
// Console.WriteLine("rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
@@ -1003,7 +1008,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
rootPart.TrimPermissions();
if (isAttachment)
so.SetFromItemID(item.ID);
so.FromItemID = item.ID;
}
return true;
@@ -72,7 +72,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
m_scene = scene;
m_scene.AddCommand(this, "monitor report",
m_scene.AddCommand("General", this, "monitor report",
"monitor report",
"Returns a variety of statistics about the current region and/or simulator",
DebugMonitors);
@@ -0,0 +1,161 @@
/*
* 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.Reflection;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Services.Connectors.Hypergrid;
using OpenMetaverse;
using OpenMetaverse.Packets;
using log4net;
using Nini.Config;
namespace OpenSim.Region.CoreModules.Framework.UserManagement
{
public class HGUserManagementModule : UserManagementModule, ISharedRegionModule, IUserManagement
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#region ISharedRegionModule
public new void Initialise(IConfigSource config)
{
string umanmod = config.Configs["Modules"].GetString("UserManagementModule", base.Name);
if (umanmod == Name)
{
m_Enabled = true;
RegisterConsoleCmds();
m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name);
}
}
public override string Name
{
get { return "HGUserManagementModule"; }
}
#endregion ISharedRegionModule
protected override void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users)
{
if (query.Contains("@")) // First.Last@foo.com, maybe?
{
string[] words = query.Split(new char[] { '@' });
if (words.Length != 2)
{
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Malformed address {0}", query);
return;
}
words[0] = words[0].Trim(); // it has at least 1
words[1] = words[1].Trim();
if (words[0] == String.Empty) // query was @foo.com?
{
foreach (UserData d in m_UserCache.Values)
{
if (d.LastName.ToLower().StartsWith("@" + words[1].ToLower()))
users.Add(d);
}
// We're done
return;
}
// words.Length == 2 and words[0] != string.empty
// first.last@foo.com ?
foreach (UserData d in m_UserCache.Values)
{
if (d.LastName.StartsWith("@") &&
d.FirstName.ToLower().Equals(words[0].ToLower()) &&
d.LastName.ToLower().Equals("@" + words[1].ToLower()))
{
users.Add(d);
// It's cached. We're done
return;
}
}
// This is it! Let's ask the other world
if (words[0].Contains("."))
{
string[] names = words[0].Split(new char[] { '.' });
if (names.Length >= 2)
{
string uriStr = "http://" + words[1];
// Let's check that the last name is a valid address
try
{
new Uri(uriStr);
}
catch (UriFormatException)
{
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Malformed address {0}", uriStr);
return;
}
UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr);
UUID userID = uasConn.GetUUID(names[0], names[1]);
if (!userID.Equals(UUID.Zero))
{
UserData ud = new UserData();
ud.Id = userID;
ud.FirstName = words[0];
ud.LastName = "@" + words[1];
users.Add(ud);
AddUser(userID, names[0], names[1], uriStr);
m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} found", words[0], words[1]);
}
else
m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} not found", words[0], words[1]);
}
}
}
//else
//{
// foreach (UserData d in m_UserCache.Values)
// {
// if (d.LastName.StartsWith("@") &&
// (d.FirstName.ToLower().StartsWith(query.ToLower()) ||
// d.LastName.ToLower().StartsWith(query.ToLower())))
// users.Add(d);
// }
//}
}
}
}
@@ -38,12 +38,13 @@ using OpenSim.Services.Interfaces;
using OpenSim.Services.Connectors.Hypergrid;
using OpenMetaverse;
using OpenMetaverse.Packets;
using log4net;
using Nini.Config;
namespace OpenSim.Region.CoreModules.Framework.UserManagement
{
class UserData
public class UserData
{
public UUID Id { get; set; }
public string FirstName { get; set; }
@@ -56,36 +57,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private List<Scene> m_Scenes = new List<Scene>();
protected bool m_Enabled;
protected List<Scene> m_Scenes = new List<Scene>();
// The cache
Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>();
protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>();
#region ISharedRegionModule
public void Initialise(IConfigSource config)
{
//m_Enabled = config.Configs["Modules"].GetBoolean("LibraryModule", m_Enabled);
//if (m_Enabled)
//{
// IConfig libConfig = config.Configs["LibraryService"];
// if (libConfig != null)
// {
// string dllName = libConfig.GetString("LocalServiceModule", string.Empty);
// m_log.Debug("[LIBRARY MODULE]: Library service dll is " + dllName);
// if (dllName != string.Empty)
// {
// Object[] args = new Object[] { config };
// m_Library = ServerUtils.LoadPlugin<ILibraryService>(dllName, args);
// }
// }
//}
MainConsole.Instance.Commands.AddCommand("grid", true,
"show names",
"show names",
"Show the bindings between user UUIDs and user names",
String.Empty,
HandleShowUsers);
string umanmod = config.Configs["Modules"].GetString("UserManagementModule", Name);
if (umanmod == Name)
{
m_Enabled = true;
RegisterConsoleCmds();
m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name);
}
}
public bool IsSharedModule
@@ -93,9 +81,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
get { return true; }
}
public string Name
public virtual string Name
{
get { return "UserManagement Module"; }
get { return "BasicUserManagementModule"; }
}
public Type ReplaceableInterface
@@ -105,17 +93,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
public void AddRegion(Scene scene)
{
m_Scenes.Add(scene);
if (m_Enabled)
{
m_Scenes.Add(scene);
scene.RegisterModuleInterface<IUserManagement>(this);
scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
scene.RegisterModuleInterface<IUserManagement>(this);
scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
}
}
public void RemoveRegion(Scene scene)
{
scene.UnregisterModuleInterface<IUserManagement>(this);
m_Scenes.Remove(scene);
if (m_Enabled)
{
scene.UnregisterModuleInterface<IUserManagement>(this);
m_Scenes.Remove(scene);
}
}
public void RegionLoaded(Scene s)
@@ -149,7 +143,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
void EventManager_OnNewClient(IClientAPI client)
{
client.OnConnectionClosed += new Action<IClientAPI>(HandleConnectionClosed);
client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
client.OnAvatarPickerRequest += new AvatarPickerRequest(HandleAvatarPickerRequest);
}
void HandleConnectionClosed(IClientAPI client)
{
client.OnNameFromUUIDRequest -= new UUIDNameRequest(HandleUUIDNameRequest);
client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest);
}
void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client)
@@ -170,6 +172,77 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
}
}
public void HandleAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query)
{
//EventManager.TriggerAvatarPickerRequest();
m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query);
List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
List<UserData> users = new List<UserData>();
if (accs != null)
{
foreach (UserAccount acc in accs)
{
UserData ud = new UserData();
ud.FirstName = acc.FirstName;
ud.LastName = acc.LastName;
ud.Id = acc.PrincipalID;
users.Add(ud);
}
}
AddAdditionalUsers(avatarID, query, users);
AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
// TODO: don't create new blocks if recycling an old packet
AvatarPickerReplyPacket.DataBlock[] searchData =
new AvatarPickerReplyPacket.DataBlock[users.Count];
AvatarPickerReplyPacket.AgentDataBlock agentData = new AvatarPickerReplyPacket.AgentDataBlock();
agentData.AgentID = avatarID;
agentData.QueryID = RequestID;
replyPacket.AgentData = agentData;
//byte[] bytes = new byte[AvatarResponses.Count*32];
int i = 0;
foreach (UserData item in users)
{
UUID translatedIDtem = item.Id;
searchData[i] = new AvatarPickerReplyPacket.DataBlock();
searchData[i].AvatarID = translatedIDtem;
searchData[i].FirstName = Utils.StringToBytes((string)item.FirstName);
searchData[i].LastName = Utils.StringToBytes((string)item.LastName);
i++;
}
if (users.Count == 0)
{
searchData = new AvatarPickerReplyPacket.DataBlock[0];
}
replyPacket.Data = searchData;
AvatarPickerReplyAgentDataArgs agent_data = new AvatarPickerReplyAgentDataArgs();
agent_data.AgentID = replyPacket.AgentData.AgentID;
agent_data.QueryID = replyPacket.AgentData.QueryID;
List<AvatarPickerReplyDataArgs> data_args = new List<AvatarPickerReplyDataArgs>();
for (i = 0; i < replyPacket.Data.Length; i++)
{
AvatarPickerReplyDataArgs data_arg = new AvatarPickerReplyDataArgs();
data_arg.AvatarID = replyPacket.Data[i].AvatarID;
data_arg.FirstName = replyPacket.Data[i].FirstName;
data_arg.LastName = replyPacket.Data[i].LastName;
data_args.Add(data_arg);
}
client.SendAvatarPickerReply(agent_data, data_args);
}
protected virtual void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users)
{
}
#endregion Event Handlers
private void CacheCreators(SceneObjectGroup sog)
@@ -224,9 +297,37 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
#region IUserManagement
public UUID GetUserIdByName(string name)
{
string[] parts = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 2)
throw new Exception("Name must have 2 components");
return GetUserIdByName(parts[0], parts[1]);
}
public UUID GetUserIdByName(string firstName, string lastName)
{
// TODO: Optimize for reverse lookup if this gets used by non-console commands.
lock (m_UserCache)
{
foreach (UserData user in m_UserCache.Values)
{
if (user.FirstName == firstName && user.LastName == lastName)
return user.Id;
}
}
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, firstName, lastName);
if (account != null)
return account.PrincipalID;
return UUID.Zero;
}
public string GetUserName(UUID uuid)
{
//m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
string[] names = GetUserNames(uuid);
if (names.Length == 2)
{
@@ -267,9 +368,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
if (userdata.HomeURL != null && userdata.HomeURL != string.Empty)
{
m_log.DebugFormat(
"[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}",
serverType, userdata.HomeURL, userID);
//m_log.DebugFormat(
// "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}",
// serverType, userdata.HomeURL, userID);
UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
userdata.ServerURLs = uConn.GetServerURLs(userID);
@@ -328,11 +429,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
public void AddUser(UUID uuid, string first, string last, string homeURL)
{
// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL);
AddUser(uuid, homeURL + ";" + first + " " + last);
}
public void AddUser (UUID id, string creatorData)
{
//m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
UserData oldUser;
//lock the whole block - prevent concurrent update
lock (m_UserCache)
@@ -358,9 +463,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
return;
}
}
// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
UserAccount account = m_Scenes [0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id);
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id);
if (account != null)
{
@@ -409,9 +513,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
lock (m_UserCache)
m_UserCache[user.Id] = user;
// m_log.DebugFormat(
// "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
// user.Id, user.FirstName, user.LastName, user.HomeURL);
//m_log.DebugFormat(
// "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
// user.Id, user.FirstName, user.LastName, user.HomeURL);
}
public bool IsLocalGridUser(UUID uuid)
@@ -425,13 +529,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
#endregion IUserManagement
protected void RegisterConsoleCmds()
{
MainConsole.Instance.Commands.AddCommand("Users", true,
"show names",
"show names",
"Show the bindings between user UUIDs and user names",
String.Empty,
HandleShowUsers);
}
private void HandleShowUsers(string module, string[] cmd)
{
lock (m_UserCache)
{
if (m_UserCache.Count == 0)
{
MainConsole.Instance.Output("No users not found");
MainConsole.Instance.Output("No users found");
return;
}
@@ -9,6 +9,7 @@
<Extension path = "/OpenSim/RegionModules">
<RegionModule id="UserManagementModule" type="OpenSim.Region.CoreModules.Framework.UserManagement.UserManagementModule" />
<RegionModule id="HGUserManagementModule" type="OpenSim.Region.CoreModules.Framework.UserManagement.HGUserManagementModule" />
<RegionModule id="EntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule" />
<RegionModule id="HGEntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.HGEntityTransferModule" />
<RegionModule id="InventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.BasicInventoryAccessModule" />
@@ -151,6 +151,14 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
#region IWorldComm Members
public int ListenerCount
{
get
{
return m_listenerManager.ListenerCount;
}
}
/// <summary>
/// Create a listen event callback with the specified filters.
/// The parameters localID,itemID are needed to uniquely identify
@@ -311,7 +319,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
// Send message to avatar
if (channel == 0)
{
m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Owner, 0, pos, name, id, false);
m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, false);
}
List<SceneObjectGroup> attachments = sp.GetAttachments();
@@ -438,6 +446,18 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
private int m_maxhandles;
private int m_curlisteners;
/// <summary>
/// Total number of listeners
/// </summary>
public int ListenerCount
{
get
{
lock (m_listeners)
return m_listeners.Count;
}
}
public ListenerManager(int maxlisteners, int maxhandles)
{
m_maxlisteners = maxlisteners;
@@ -48,8 +48,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
private static bool m_Enabled = false;
private IConfigSource m_Config;
bool m_Registered = false;
GatekeeperServiceInConnector m_HypergridHandler;
private bool m_Registered = false;
private string m_LocalServiceDll = String.Empty;
private GatekeeperServiceInConnector m_HypergridHandler;
private UserAgentServerConnector m_UASHandler;
#region IRegionModule interface
@@ -63,6 +65,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
if (m_Enabled)
{
m_log.Info("[HGGRID IN CONNECTOR]: Hypergrid Service In Connector enabled");
IConfig fconfig = config.Configs["FriendsService"];
if (fconfig != null)
{
m_LocalServiceDll = fconfig.GetString("LocalServiceModule", m_LocalServiceDll);
if (m_LocalServiceDll == String.Empty)
m_log.WarnFormat("[HGGRID IN CONNECTOR]: Friends LocalServiceModule config missing");
}
}
}
@@ -91,7 +100,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
{
if (!m_Enabled)
return;
}
public void RemoveRegion(Scene scene)
@@ -112,14 +120,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
m_log.Info("[HypergridService]: Starting...");
ISimulationService simService = scene.RequestModuleInterface<ISimulationService>();
IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>();
Object[] args = new Object[] { m_Config };
IFriendsService friendsService = ServerUtils.LoadPlugin<IFriendsService>(m_LocalServiceDll, args);
m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>();
new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
m_UASHandler = new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService");
new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService", friendsConn);
}
scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
scene.RegisterModuleInterface<IUserAgentService>(m_UASHandler.HomeUsersService);
}
#endregion
@@ -73,14 +73,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
return;
}
string serviceDll = assetConfig.GetString("LocalServiceModule",
String.Empty);
string serviceDll = assetConfig.GetString("LocalServiceModule", String.Empty);
if (serviceDll == String.Empty)
{
m_log.Error("[LOCAL ASSET SERVICES CONNECTOR]: No LocalServiceModule named in section AssetService");
return;
}
else
{
m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Loading asset service at {0}", serviceDll);
}
Object[] args = new Object[] { source };
m_AssetService = ServerUtils.LoadPlugin<IAssetService>(serviceDll, args);
@@ -0,0 +1,124 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Nini.Config;
using log4net;
using OpenSim.Framework;
using OpenSim.Services.Interfaces;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenMetaverse;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
{
public class AuthorizationService : IAuthorizationService
{
private enum AccessFlags
{
None = 0, /* No restrictions */
DisallowResidents = 1, /* Only gods and managers*/
DisallowForeigners = 2, /* Only local people */
}
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private IUserManagement m_UserManagement;
private IGridService m_GridService;
private Scene m_Scene;
AccessFlags m_accessValue = AccessFlags.None;
public AuthorizationService(IConfig config, Scene scene)
{
m_Scene = scene;
m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
m_GridService = scene.GridService;
if (config != null)
{
string accessStr = config.GetString("Region_" + scene.RegionInfo.RegionName.Replace(' ', '_'), String.Empty);
if (accessStr != string.Empty)
{
try
{
m_accessValue = (AccessFlags)Enum.Parse(typeof(AccessFlags), accessStr);
}
catch (ArgumentException)
{
m_log.WarnFormat("[AuthorizationService]: {0} is not a valid access flag", accessStr);
}
}
m_log.DebugFormat("[AuthorizationService]: Region {0} access restrictions: {1}", m_Scene.RegionInfo.RegionName, m_accessValue);
}
}
public bool IsAuthorizedForRegion(
string user, string firstName, string lastName, string regionID, out string message)
{
message = "authorized";
// This should not happen
if (m_Scene.RegionInfo.RegionID.ToString() != regionID)
{
m_log.WarnFormat("[AuthorizationService]: Service for region {0} received request to authorize for region {1}",
m_Scene.RegionInfo.RegionID, regionID);
return true;
}
if (m_accessValue == AccessFlags.None)
return true;
UUID userID = new UUID(user);
bool authorized = true;
if ((m_accessValue & AccessFlags.DisallowForeigners) == AccessFlags.DisallowForeigners)
{
authorized = m_UserManagement.IsLocalGridUser(userID);
if (!authorized)
message = "no foreigner users allowed in this region";
}
if (authorized && (m_accessValue & AccessFlags.DisallowResidents) == AccessFlags.DisallowResidents)
{
authorized = m_Scene.Permissions.IsGod(userID) | m_Scene.Permissions.IsAdministrator(userID);
if (!authorized)
message = "only Admins and Managers allowed in this region";
}
return authorized;
}
}
}
@@ -39,13 +39,15 @@ using OpenMetaverse;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
{
public class LocalAuthorizationServicesConnector : ISharedRegionModule, IAuthorizationService
public class LocalAuthorizationServicesConnector : INonSharedRegionModule, IAuthorizationService
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private IAuthorizationService m_AuthorizationService;
private Scene m_Scene;
private IConfig m_AuthorizationConfig;
private bool m_Enabled = false;
@@ -69,33 +71,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
string name = moduleConfig.GetString("AuthorizationServices", string.Empty);
if (name == Name)
{
IConfig authorizationConfig = source.Configs["AuthorizationService"];
if (authorizationConfig == null)
{
m_log.Error("[AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini");
return;
}
string serviceDll = authorizationConfig.GetString("LocalServiceModule",
String.Empty);
if (serviceDll == String.Empty)
{
m_log.Error("[AUTHORIZATION CONNECTOR]: No LocalServiceModule named in section AuthorizationService");
return;
}
Object[] args = new Object[] { source };
m_AuthorizationService =
ServerUtils.LoadPlugin<IAuthorizationService>(serviceDll,
args);
if (m_AuthorizationService == null)
{
m_log.Error("[AUTHORIZATION CONNECTOR]: Can't load authorization service");
return;
}
m_Enabled = true;
m_AuthorizationConfig = source.Configs["AuthorizationService"];
m_log.Info("[AUTHORIZATION CONNECTOR]: Local authorization connector enabled");
}
}
@@ -115,6 +92,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
return;
scene.RegisterModuleInterface<IAuthorizationService>(this);
m_Scene = scene;
}
public void RemoveRegion(Scene scene)
@@ -126,6 +104,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
if (!m_Enabled)
return;
m_AuthorizationService = new AuthorizationService(m_AuthorizationConfig, m_Scene);
m_log.InfoFormat(
"[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}",
scene.RegionInfo.RegionName);
@@ -134,6 +114,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
public bool IsAuthorizedForRegion(
string userID, string firstName, string lastName, string regionID, out string message)
{
message = "";
if (!m_Enabled)
return true;
return m_AuthorizationService.IsAuthorizedForRegion(userID, firstName, lastName, regionID, out message);
}
}
@@ -48,8 +48,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private static LocalGridServicesConnector m_MainInstance;
private IGridService m_GridService;
private Dictionary<UUID, RegionCache> m_LocalCache = new Dictionary<UUID, RegionCache>();
@@ -62,7 +60,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public LocalGridServicesConnector(IConfigSource source)
{
m_log.Debug("[LOCAL GRID CONNECTOR]: LocalGridServicesConnector instantiated");
m_MainInstance = this;
InitialiseService(source);
}
@@ -87,7 +84,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (name == Name)
{
InitialiseService(source);
m_MainInstance = this;
m_Enabled = true;
m_log.Info("[LOCAL GRID CONNECTOR]: Local grid connector enabled");
}
@@ -126,12 +122,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public void PostInitialise()
{
if (m_MainInstance == this)
{
MainConsole.Instance.Commands.AddCommand("LocalGridConnector", false, "show neighbours",
"show neighbours",
"Shows the local regions' neighbours", NeighboursCommand);
}
MainConsole.Instance.Commands.AddCommand("Regions", false, "show neighbours",
"show neighbours",
"Shows the local regions' neighbours", NeighboursCommand);
}
public void Close()
@@ -143,22 +136,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (m_Enabled)
scene.RegisterModuleInterface<IGridService>(this);
if (m_MainInstance == this)
{
if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID))
m_log.ErrorFormat("[LOCAL GRID CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
else
m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene));
}
if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID))
m_log.ErrorFormat("[LOCAL GRID CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
else
m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene));
}
public void RemoveRegion(Scene scene)
{
if (m_MainInstance == this)
{
m_LocalCache[scene.RegionInfo.RegionID].Clear();
m_LocalCache.Remove(scene.RegionInfo.RegionID);
}
m_LocalCache[scene.RegionInfo.RegionID].Clear();
m_LocalCache.Remove(scene.RegionInfo.RegionID);
}
public void RegionLoaded(Scene scene)
@@ -259,6 +246,5 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
MainConsole.Instance.Output(caps.ToString());
}
}
}
}
@@ -58,6 +58,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
private List<Scene> m_Scenes = new List<Scene>();
private InventoryCache m_Cache = new InventoryCache();
protected IUserManagement m_UserManagement;
protected IUserManagement UserManagementModule
{
@@ -295,14 +297,35 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return m_LocalGridInventoryService.CreateUserInventory(userID);
}
public List<InventoryFolderBase> GetInventorySkeleton(UUID userId)
public List<InventoryFolderBase> GetInventorySkeleton(UUID userID)
{
return m_LocalGridInventoryService.GetInventorySkeleton(userId);
string invURL = GetInventoryServiceURL(userID);
if (invURL == null) // not there, forward to local inventory connector to resolve
return m_LocalGridInventoryService.GetInventorySkeleton(userID);
IInventoryService connector = GetConnector(invURL);
return connector.GetInventorySkeleton(userID);
}
public InventoryCollection GetUserInventory(UUID userID)
{
return null;
string invURL = GetInventoryServiceURL(userID);
m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetUserInventory for {0} {1}", userID, invURL);
if (invURL == null) // not there, forward to local inventory connector to resolve
return m_LocalGridInventoryService.GetUserInventory(userID);
InventoryCollection c = m_Cache.GetUserInventory(userID);
if (c != null)
return c;
IInventoryService connector = GetConnector(invURL);
c = connector.GetUserInventory(userID);
m_Cache.Cache(userID, c);
return c;
}
public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
@@ -312,6 +335,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
public InventoryFolderBase GetRootFolder(UUID userID)
{
//m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetRootFolder for {0}", userID);
InventoryFolderBase root = m_Cache.GetRootFolder(userID);
if (root != null)
return root;
string invURL = GetInventoryServiceURL(userID);
@@ -320,12 +346,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
IInventoryService connector = GetConnector(invURL);
return connector.GetRootFolder(userID);
root = connector.GetRootFolder(userID);
m_Cache.Cache(userID, root);
return root;
}
public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
{
//m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetFolderForType {0} type {1}", userID, type);
InventoryFolderBase f = m_Cache.GetFolderForType(userID, type);
if (f != null)
return f;
string invURL = GetInventoryServiceURL(userID);
@@ -334,7 +367,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
IInventoryService connector = GetConnector(invURL);
return connector.GetFolderForType(userID, type);
f = connector.GetFolderForType(userID, type);
m_Cache.Cache(userID, type, f);
return f;
}
public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
@@ -346,8 +383,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
if (invURL == null) // not there, forward to local inventory connector to resolve
return m_LocalGridInventoryService.GetFolderContent(userID, folderID);
IInventoryService connector = GetConnector(invURL);
InventoryCollection c = m_Cache.GetFolderContent(userID, folderID);
if (c != null)
{
m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderContent found content in cache " + folderID);
return c;
}
IInventoryService connector = GetConnector(invURL);
return connector.GetFolderContent(userID, folderID);
}
@@ -361,8 +404,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
if (invURL == null) // not there, forward to local inventory connector to resolve
return m_LocalGridInventoryService.GetFolderItems(userID, folderID);
IInventoryService connector = GetConnector(invURL);
List<InventoryItemBase> items = m_Cache.GetFolderItems(userID, folderID);
if (items != null)
{
m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems found items in cache " + folderID);
return items;
}
IInventoryService connector = GetConnector(invURL);
return connector.GetFolderItems(userID, folderID);
}
@@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using OpenSim.Framework;
using OpenMetaverse;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
{
public class InventoryCache
{
private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour
private static ExpiringCache<UUID, InventoryFolderBase> m_RootFolders = new ExpiringCache<UUID, InventoryFolderBase>();
private static ExpiringCache<UUID, Dictionary<AssetType, InventoryFolderBase>> m_FolderTypes = new ExpiringCache<UUID, Dictionary<AssetType, InventoryFolderBase>>();
private static ExpiringCache<UUID, InventoryCollection> m_Inventories = new ExpiringCache<UUID, InventoryCollection>();
public void Cache(UUID userID, InventoryFolderBase root)
{
lock (m_RootFolders)
m_RootFolders.AddOrUpdate(userID, root, CACHE_EXPIRATION_SECONDS);
}
public InventoryFolderBase GetRootFolder(UUID userID)
{
InventoryFolderBase root = null;
if (m_RootFolders.TryGetValue(userID, out root))
return root;
return null;
}
public void Cache(UUID userID, AssetType type, InventoryFolderBase folder)
{
lock (m_FolderTypes)
{
Dictionary<AssetType, InventoryFolderBase> ff = null;
if (!m_FolderTypes.TryGetValue(userID, out ff))
{
ff = new Dictionary<AssetType, InventoryFolderBase>();
m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS);
}
if (!ff.ContainsKey(type))
ff.Add(type, folder);
}
}
public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
{
Dictionary<AssetType, InventoryFolderBase> ff = null;
if (m_FolderTypes.TryGetValue(userID, out ff))
{
InventoryFolderBase f = null;
if (ff.TryGetValue(type, out f))
return f;
}
return null;
}
public void Cache(UUID userID, InventoryCollection inv)
{
lock (m_Inventories)
m_Inventories.AddOrUpdate(userID, inv, 120);
}
public InventoryCollection GetUserInventory(UUID userID)
{
InventoryCollection inv = null;
if (m_Inventories.TryGetValue(userID, out inv))
return inv;
return null;
}
public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
{
InventoryCollection inv = null;
InventoryCollection c;
if (m_Inventories.TryGetValue(userID, out inv))
{
c = new InventoryCollection();
c.UserID = userID;
c.Folders = inv.Folders.FindAll(delegate(InventoryFolderBase f)
{
return f.ParentID == folderID;
});
c.Items = inv.Items.FindAll(delegate(InventoryItemBase i)
{
return i.Folder == folderID;
});
return c;
}
return null;
}
public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
{
InventoryCollection inv = null;
if (m_Inventories.TryGetValue(userID, out inv))
{
List<InventoryItemBase> items = inv.Items.FindAll(delegate(InventoryItemBase i)
{
return i.Folder == folderID;
});
return items;
}
return null;
}
}
}
@@ -167,12 +167,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
public List<InventoryFolderBase> GetInventorySkeleton(UUID userId)
{
return new List<InventoryFolderBase>();
return m_RemoteConnector.GetInventorySkeleton(userId);
}
public InventoryCollection GetUserInventory(UUID userID)
{
return null;
return m_RemoteConnector.GetUserInventory(userID);
}
public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
@@ -193,16 +193,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
{
InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID);
if (UserManager != null)
if (invCol != null && UserManager != null)
{
// Protect ourselves against the caller subsequently modifying the items list
List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
Util.FireAndForget(delegate
{
foreach (InventoryItemBase item in items)
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
});
if (items != null && items.Count > 0)
Util.FireAndForget(delegate
{
foreach (InventoryItemBase item in items)
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
});
}
return invCol;
@@ -193,6 +193,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
return m_PresenceService.GetAgents(userIDs);
}
public PresenceInfo VerifyAgent(UUID s_sessionID)
{
return m_PresenceService.VerifyAgent(s_sessionID);
}
#endregion
}
@@ -27,14 +27,12 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
using log4net;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
{
public class PresenceDetector
@@ -97,7 +95,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
// m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
m_PresenceService.LogoutAgent(client.SessionId);
}
}
}
}
}
@@ -153,6 +153,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
return m_RemoteConnector.GetAgents(userIDs);
}
public PresenceInfo VerifyAgent(UUID sessionID)
{
return m_RemoteConnector.VerifyAgent(sessionID);
}
#endregion
}
@@ -47,21 +47,21 @@ namespace OpenSim.Region.CoreModules.World
public void Initialise(IConfigSource config)
{
MainConsole.Instance.Commands.AddCommand("access", true,
MainConsole.Instance.Commands.AddCommand("Users", true,
"login enable",
"login enable",
"Enable simulator logins",
String.Empty,
HandleLoginCommand);
MainConsole.Instance.Commands.AddCommand("access", true,
MainConsole.Instance.Commands.AddCommand("Users", true,
"login disable",
"login disable",
"Disable simulator logins",
String.Empty,
HandleLoginCommand);
MainConsole.Instance.Commands.AddCommand("access", true,
MainConsole.Instance.Commands.AddCommand("Users", true,
"login status",
"login status",
"Show login status",
@@ -108,12 +108,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// "[ARCHIVER]: Received {0} of {1} assets requested",
// assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count);
m_log.InfoFormat("[ARCHIVER]: Adding region settings to archive.");
// Write out region settings
string settingsPath
= String.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_scene.RegionInfo.RegionName);
m_archiveWriter.WriteFile(settingsPath, RegionSettingsSerializer.Serialize(m_scene.RegionInfo.RegionSettings));
m_log.InfoFormat("[ARCHIVER]: Added region settings to archive.");
m_log.InfoFormat("[ARCHIVER]: Adding parcel settings to archive.");
// Write out land data (aka parcel) settings
List<ILandObject>landObjects = m_scene.LandChannel.AllParcels();
@@ -124,7 +126,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
landData.GlobalID.ToString());
m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData));
}
m_log.InfoFormat("[ARCHIVER]: Added parcel settings to archive.");
m_log.InfoFormat("[ARCHIVER]: Adding terrain information to archive.");
// Write out terrain
string terrainPath
@@ -135,7 +138,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
m_archiveWriter.WriteFile(terrainPath, ms.ToArray());
ms.Close();
m_log.InfoFormat("[ARCHIVER]: Added terrain information to archive.");
m_log.InfoFormat("[ARCHIVER]: Adding scene objects to archive.");
// Write out scene object metadata
foreach (SceneObjectGroup sceneObject in m_sceneObjects)
@@ -145,10 +148,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
string serializedObject = m_serialiser.SerializeGroupToXml2(sceneObject, m_options);
m_archiveWriter.WriteFile(ArchiveHelpers.CreateObjectPath(sceneObject), serializedObject);
}
m_log.InfoFormat("[ARCHIVER]: Added scene objects to archive.");
}
}
}
}
@@ -219,12 +219,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver
m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
if (SaveAssets)
new AssetsRequest(
new AssetsArchiver(archiveWriter), assetUuids,
m_scene.AssetService, m_scene.UserAccountService,
m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute();
{
AssetsRequest ar
= new AssetsRequest(
new AssetsArchiver(archiveWriter), assetUuids,
m_scene.AssetService, m_scene.UserAccountService,
m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets);
Util.FireAndForget(o => ar.Execute());
}
else
{
awre.ReceivedAllAssets(new List<UUID>(), new List<UUID>());
}
}
catch (Exception)
{
@@ -141,13 +141,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
PerformAssetsRequestCallback(null);
return;
}
foreach (KeyValuePair<UUID, AssetType> kvp in m_uuids)
{
m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback);
}
m_requestCallbackTimer.Enabled = true;
foreach (KeyValuePair<UUID, AssetType> kvp in m_uuids)
{
// m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback);
AssetBase asset = m_assetService.Get(kvp.Key.ToString());
PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset);
}
}
protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args)
@@ -62,58 +62,25 @@ namespace OpenSim.Region.CoreModules.World.Estate
{
m_log.DebugFormat("[ESTATE MODULE]: Setting up estate commands for region {0}", m_module.Scene.RegionInfo.RegionName);
m_module.Scene.AddCommand(m_module, "set terrain texture",
m_module.Scene.AddCommand("Regions", m_module, "set terrain texture",
"set terrain texture <number> <uuid> [<x>] [<y>]",
"Sets the terrain <number> to <uuid>, if <x> or <y> are specified, it will only " +
"set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" +
" that coordinate.",
consoleSetTerrainTexture);
m_module.Scene.AddCommand(m_module, "set terrain heights",
m_module.Scene.AddCommand("Regions", m_module, "set terrain heights",
"set terrain heights <corner> <min> <max> [<x>] [<y>]",
"Sets the terrain texture heights on corner #<corner> to <min>/<max>, if <x> or <y> are specified, it will only " +
"set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" +
" that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3.",
consoleSetTerrainHeights);
Command showCommand
= new Command("show", CommandIntentions.COMMAND_STATISTICAL, ShowEstatesCommand, "Shows all estates on the simulator.");
consoleSetTerrainHeights);
m_commander.RegisterCommand("show", showCommand);
m_module.Scene.RegisterModuleCommander(m_commander);
m_module.Scene.EventManager.OnPluginConsole += EventManagerOnPluginConsole;
m_module.Scene.AddCommand(
"Estates", m_module, "estate show", "estate show", "Shows all estates on the simulator.", ShowEstatesCommand);
}
public void Close()
{
m_module.Scene.EventManager.OnPluginConsole -= EventManagerOnPluginConsole;
m_module.Scene.UnregisterModuleCommander(m_commander.Name);
}
/// <summary>
/// Processes commandline input. Do not call directly.
/// </summary>
/// <param name="args">Commandline arguments</param>
protected void EventManagerOnPluginConsole(string[] args)
{
if (args[0] == "estate")
{
if (args.Length == 1)
{
m_commander.ProcessConsoleCommand("help", new string[0]);
return;
}
string[] tmpArgs = new string[args.Length - 2];
int i;
for (i = 2; i < args.Length; i++)
tmpArgs[i - 2] = args[i];
m_commander.ProcessConsoleCommand(args[1], tmpArgs);
}
}
public void Close() {}
protected void consoleSetTerrainTexture(string module, string[] args)
{
@@ -201,7 +168,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
}
}
protected void ShowEstatesCommand(Object[] args)
protected void ShowEstatesCommand(string module, string[] cmd)
{
StringBuilder report = new StringBuilder();
RegionInfo ri = m_module.Scene.RegionInfo;
@@ -26,8 +26,10 @@
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security;
using log4net;
@@ -45,8 +47,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private delegate void LookupUUIDS(List<UUID> uuidLst);
public Scene Scene { get; private set; }
public IUserManagement UserManager { get; private set; }
@@ -157,12 +157,18 @@ namespace OpenSim.Region.CoreModules.World.Estate
sendRegionInfoPacketToAll();
}
public void setEstateTerrainBaseTexture(IClientAPI remoteClient, int corner, UUID texture)
public void setEstateTerrainBaseTexture(int level, UUID texture)
{
setEstateTerrainBaseTexture(null, level, texture);
sendRegionHandshakeToAll();
}
public void setEstateTerrainBaseTexture(IClientAPI remoteClient, int level, UUID texture)
{
if (texture == UUID.Zero)
return;
switch (corner)
switch (level)
{
case 0:
Scene.RegionInfo.RegionSettings.TerrainTexture1 = texture;
@@ -182,6 +188,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
sendRegionInfoPacketToAll();
}
public void setEstateTerrainTextureHeights(int corner, float lowValue, float highValue)
{
setEstateTerrainTextureHeights(null, corner, lowValue, highValue);
}
public void setEstateTerrainTextureHeights(IClientAPI client, int corner, float lowValue, float highValue)
{
switch (corner)
@@ -604,7 +615,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
public void handleOnEstateManageTelehub (IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1)
{
uint ObjectLocalID;
SceneObjectPart part;
switch (cmd)
@@ -661,28 +671,23 @@ namespace OpenSim.Region.CoreModules.World.Estate
TriggerEstateMessage(senderID, senderName, message);
}
private void handleEstateDebugRegionRequest(IClientAPI remote_client, UUID invoice, UUID senderID, bool scripted, bool collisionEvents, bool physics)
private void handleEstateDebugRegionRequest(
IClientAPI remote_client, UUID invoice, UUID senderID,
bool disableScripts, bool disableCollisions, bool disablePhysics)
{
if (physics)
Scene.RegionInfo.RegionSettings.DisablePhysics = true;
else
Scene.RegionInfo.RegionSettings.DisablePhysics = false;
if (scripted)
Scene.RegionInfo.RegionSettings.DisableScripts = true;
else
Scene.RegionInfo.RegionSettings.DisableScripts = false;
if (collisionEvents)
Scene.RegionInfo.RegionSettings.DisableCollisions = true;
else
Scene.RegionInfo.RegionSettings.DisableCollisions = false;
Scene.RegionInfo.RegionSettings.DisablePhysics = disablePhysics;
Scene.RegionInfo.RegionSettings.DisableScripts = disableScripts;
Scene.RegionInfo.RegionSettings.DisableCollisions = disableCollisions;
Scene.RegionInfo.RegionSettings.Save();
TriggerRegionInfoChange();
Scene.SetSceneCoreDebug(scripted, collisionEvents, physics);
Scene.SetSceneCoreDebug(
new Dictionary<string, string>() {
{ "scripting", (!disableScripts).ToString() },
{ "collisions", (!disableCollisions).ToString() },
{ "physics", (!disablePhysics).ToString() }
}
);
}
private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey)
@@ -876,98 +881,76 @@ namespace OpenSim.Region.CoreModules.World.Estate
if (!Scene.Permissions.CanIssueEstateCommand(remoteClient.AgentId, false))
return;
Dictionary<uint, float> SceneData = new Dictionary<uint,float>();
List<UUID> uuidNameLookupList = new List<UUID>();
Dictionary<uint, float> sceneData = null;
if (reportType == 1)
{
SceneData = Scene.PhysicsScene.GetTopColliders();
sceneData = Scene.PhysicsScene.GetTopColliders();
}
else if (reportType == 0)
{
SceneData = Scene.SceneGraph.GetTopScripts();
IScriptModule scriptModule = Scene.RequestModuleInterface<IScriptModule>();
if (scriptModule != null)
sceneData = scriptModule.GetObjectScriptsExecutionTimes();
}
List<LandStatReportItem> SceneReport = new List<LandStatReportItem>();
lock (SceneData)
if (sceneData != null)
{
foreach (uint obj in SceneData.Keys)
var sortedSceneData
= sceneData.Select(
item => new { Measurement = item.Value, Part = Scene.GetSceneObjectPart(item.Key) });
sortedSceneData.OrderBy(item => item.Measurement);
int items = 0;
foreach (var entry in sortedSceneData)
{
SceneObjectPart prt = Scene.GetSceneObjectPart(obj);
if (prt != null)
// The object may have been deleted since we received the data.
if (entry.Part == null)
continue;
// Don't show scripts that haven't executed or where execution time is below one microsecond in
// order to produce a more readable report.
if (entry.Measurement < 0.001)
continue;
items++;
SceneObjectGroup so = entry.Part.ParentGroup;
LandStatReportItem lsri = new LandStatReportItem();
lsri.LocationX = so.AbsolutePosition.X;
lsri.LocationY = so.AbsolutePosition.Y;
lsri.LocationZ = so.AbsolutePosition.Z;
lsri.Score = entry.Measurement;
lsri.TaskID = so.UUID;
lsri.TaskLocalID = so.LocalId;
lsri.TaskName = entry.Part.Name;
lsri.OwnerName = UserManager.GetUserName(so.OwnerID);
if (filter.Length != 0)
{
SceneObjectGroup sog = prt.ParentGroup;
LandStatReportItem lsri = new LandStatReportItem();
lsri.LocationX = sog.AbsolutePosition.X;
lsri.LocationY = sog.AbsolutePosition.Y;
lsri.LocationZ = sog.AbsolutePosition.Z;
lsri.Score = SceneData[obj];
lsri.TaskID = sog.UUID;
lsri.TaskLocalID = sog.LocalId;
lsri.TaskName = sog.GetPartName(obj);
lsri.OwnerName = "waiting";
lock (uuidNameLookupList)
uuidNameLookupList.Add(sog.OwnerID);
if (filter.Length != 0)
if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
{
if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
{
}
else
{
continue;
}
}
SceneReport.Add(lsri);
else
{
continue;
}
}
SceneReport.Add(lsri);
if (items >= 100)
break;
}
}
remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray());
if (uuidNameLookupList.Count > 0)
LookupUUID(uuidNameLookupList);
}
private static void LookupUUIDSCompleted(IAsyncResult iar)
{
LookupUUIDS icon = (LookupUUIDS)iar.AsyncState;
icon.EndInvoke(iar);
}
private void LookupUUID(List<UUID> uuidLst)
{
LookupUUIDS d = LookupUUIDsAsync;
d.BeginInvoke(uuidLst,
LookupUUIDSCompleted,
d);
}
private void LookupUUIDsAsync(List<UUID> uuidLst)
{
UUID[] uuidarr;
lock (uuidLst)
{
uuidarr = uuidLst.ToArray();
}
for (int i = 0; i < uuidarr.Length; i++)
{
// string lookupname = m_scene.CommsManager.UUIDNameRequestString(uuidarr[i]);
IUserManagement userManager = Scene.RequestModuleInterface<IUserManagement>();
if (userManager != null)
userManager.GetUserName(uuidarr[i]);
// we drop it. It gets cached though... so we're ready for the next request.
// diva commnent 11/21/2010: uh?!? wft?
// justincc comment 21/01/2011: A side effect of userManager.GetUserName() I presume.
}
}
#endregion
#region Outgoing Packets
@@ -56,6 +56,9 @@ namespace OpenSim.Region.CoreModules.World.Land
protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>();
protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>();
protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds
public bool[,] LandBitmap
{
get { return m_landBitmap; }
@@ -417,6 +420,48 @@ namespace OpenSim.Region.CoreModules.World.Land
return false;
}
public bool HasGroupAccess(UUID avatar)
{
if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
{
ScenePresence sp;
if (!m_scene.TryGetScenePresence(avatar, out sp))
{
bool isMember;
if (m_groupMemberCache.TryGetValue(avatar, out isMember))
{
m_groupMemberCache.Update(avatar, isMember, m_groupMemberCacheTimeout);
return isMember;
}
IGroupsModule groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
if (groupsModule == null)
return false;
GroupMembershipData[] membership = groupsModule.GetMembershipData(avatar);
if (membership == null || membership.Length == 0)
{
m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout);
return false;
}
foreach (GroupMembershipData d in membership)
{
if (d.GroupID == LandData.GroupID)
{
m_groupMemberCache.Add(avatar, true, m_groupMemberCacheTimeout);
return true;
}
}
m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout);
return false;
}
return sp.ControllingClient.IsGroupMember(LandData.GroupID);
}
return false;
}
public bool IsBannedFromLand(UUID avatar)
{
ExpireAccessList();
@@ -448,7 +493,8 @@ namespace OpenSim.Region.CoreModules.World.Land
public bool IsRestrictedFromLand(UUID avatar)
{
ExpireAccessList();
if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) == 0)
return false;
if (m_scene.Permissions.IsAdministrator(avatar))
return false;
@@ -459,20 +505,27 @@ namespace OpenSim.Region.CoreModules.World.Land
if (avatar == LandData.OwnerID)
return false;
if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0)
if (HasGroupAccess(avatar))
return false;
return !IsInLandAccessList(avatar);
}
public bool IsInLandAccessList(UUID avatar)
{
ExpireAccessList();
if (LandData.ParcelAccessList.FindIndex(
delegate(LandAccessEntry e)
{
if (e.AgentID == avatar && e.Flags == AccessList.Access)
return true;
return false;
}) == -1)
{
if (LandData.ParcelAccessList.FindIndex(
delegate(LandAccessEntry e)
{
if (e.AgentID == avatar && e.Flags == AccessList.Access)
return true;
return false;
}) == -1)
{
return true;
}
return false;
}
return false;
return true;
}
public void SendLandUpdateToClient(IClientAPI remote_client)
@@ -78,45 +78,45 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
m_scene = scene;
m_console = MainConsole.Instance;
m_console.Commands.AddCommand("region", false, "delete object owner",
m_console.Commands.AddCommand("Regions", false, "delete object owner",
"delete object owner <UUID>",
"Delete a scene object by owner", HandleDeleteObject);
m_console.Commands.AddCommand("region", false, "delete object creator",
m_console.Commands.AddCommand("Regions", false, "delete object creator",
"delete object creator <UUID>",
"Delete a scene object by creator", HandleDeleteObject);
m_console.Commands.AddCommand("region", false, "delete object uuid",
m_console.Commands.AddCommand("Regions", false, "delete object uuid",
"delete object uuid <UUID>",
"Delete a scene object by uuid", HandleDeleteObject);
m_console.Commands.AddCommand("region", false, "delete object name",
m_console.Commands.AddCommand("Regions", false, "delete object name",
"delete object name <name>",
"Delete a scene object by name", HandleDeleteObject);
m_console.Commands.AddCommand("region", false, "delete object outside",
m_console.Commands.AddCommand("Regions", false, "delete object outside",
"delete object outside",
"Delete all scene objects outside region boundaries", HandleDeleteObject);
m_console.Commands.AddCommand(
"region",
"Regions",
false,
"show object uuid",
"show object uuid <UUID>",
"Show details of a scene object with the given UUID", HandleShowObjectByUuid);
m_console.Commands.AddCommand(
"region",
"Regions",
false,
"show object name",
"show object name <name>",
"Show details of scene objects with the given name", HandleShowObjectByName);
m_console.Commands.AddCommand(
"region",
"Regions",
false,
"show part uuid",
"show part uuid <UUID>",
"Show details of a scene object parts with the given UUID", HandleShowPartByUuid);
m_console.Commands.AddCommand(
"region",
"Regions",
false,
"show part name",
"show part name <name>",
@@ -94,7 +94,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions
private bool m_RegionOwnerIsGod = false;
private bool m_RegionManagerIsGod = false;
private bool m_ParcelOwnerIsGod = false;
private bool m_SimpleBuildPermissions = false;
/// <value>
/// The set of users that are allowed to create scripts. This is only active if permissions are not being
/// bypassed. This overrides normal permissions.
@@ -139,7 +141,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_RegionOwnerIsGod = myConfig.GetBoolean("region_owner_is_god", true);
m_RegionManagerIsGod = myConfig.GetBoolean("region_manager_is_god", false);
m_ParcelOwnerIsGod = myConfig.GetBoolean("parcel_owner_is_god", true);
m_SimpleBuildPermissions = myConfig.GetBoolean("simple_build_permissions", false);
m_allowedScriptCreators
= ParseUserSetConfigSetting(myConfig, "allowed_script_creators", m_allowedScriptCreators);
m_allowedScriptEditors
@@ -206,17 +210,17 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia;
m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia;
m_scene.AddCommand(this, "bypass permissions",
m_scene.AddCommand("Users", this, "bypass permissions",
"bypass permissions <true / false>",
"Bypass permission checks",
HandleBypassPermissions);
m_scene.AddCommand(this, "force permissions",
m_scene.AddCommand("Users", this, "force permissions",
"force permissions <true / false>",
"Force permissions on or off",
HandleForcePermissions);
m_scene.AddCommand(this, "debug permissions",
m_scene.AddCommand("Users", this, "debug permissions",
"debug permissions <true / false>",
"Turn on permissions debugging",
HandleDebugPermissions);
@@ -483,7 +487,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
return false;
}
protected bool IsFriendWithPerms(UUID user,UUID objectOwner)
protected bool IsFriendWithPerms(UUID user, UUID objectOwner)
{
if (user == UUID.Zero)
return false;
@@ -491,11 +495,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (m_friendsModule == null)
return false;
uint friendPerms = m_friendsModule.GetFriendPerms(user, objectOwner);
if ((friendPerms & (uint)FriendRights.CanModifyObjects) != 0)
return true;
return false;
int friendPerms = m_friendsModule.GetRightsGrantedByFriend(user, objectOwner);
return (friendPerms & (int)FriendRights.CanModifyObjects) != 0;
}
protected bool IsEstateManager(UUID user)
@@ -504,6 +505,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
return m_scene.RegionInfo.EstateSettings.IsEstateManager(user);
}
#endregion
public bool PropagatePermissions()
@@ -824,6 +826,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions
permission = true;
}
if (m_SimpleBuildPermissions &&
(parcel.LandData.Flags & (uint)ParcelFlags.UseAccessList) == 0 && parcel.IsInLandAccessList(user))
permission = true;
return permission;
}
@@ -66,21 +66,21 @@ namespace OpenSim.Region.CoreModules.World.Region
m_Scene = scene;
scene.RegisterModuleInterface<IRestartModule>(this);
MainConsole.Instance.Commands.AddCommand("RestartModule",
MainConsole.Instance.Commands.AddCommand("Regions",
false, "region restart bluebox",
"region restart bluebox <message> <delta seconds>+",
"Schedule a region restart",
"Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a dismissable bluebox notice. If multiple deltas are given then a notice is sent when we reach each delta.",
HandleRegionRestart);
MainConsole.Instance.Commands.AddCommand("RestartModule",
MainConsole.Instance.Commands.AddCommand("Regions",
false, "region restart notice",
"region restart notice <message> <delta seconds>+",
"Schedule a region restart",
"Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a transient notice. If multiple deltas are given then a notice is sent when we reach each delta.",
HandleRegionRestart);
MainConsole.Instance.Commands.AddCommand("RestartModule",
MainConsole.Instance.Commands.AddCommand("Regions",
false, "region restart abort",
"region restart abort [<message>]",
"Abort a region restart", HandleRegionRestart);
@@ -277,18 +277,19 @@ namespace OpenSim.Region.CoreModules
m_frame = 0;
// This one puts an entry in the main help screen
m_scene.AddCommand(this, String.Empty, "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null);
// m_scene.AddCommand("Regions", this, "sun", "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null);
// This one enables the ability to type just "sun" without any parameters
m_scene.AddCommand(this, "sun", "", "", HandleSunConsoleCommand);
// m_scene.AddCommand("Regions", this, "sun", "", "", HandleSunConsoleCommand);
foreach (KeyValuePair<string, string> kvp in GetParamList())
{
m_scene.AddCommand(this, String.Format("sun {0}", kvp.Key), String.Format("{0} - {1}", kvp.Key, kvp.Value), "", HandleSunConsoleCommand);
string sunCommand = string.Format("sun {0}", kvp.Key);
m_scene.AddCommand("Regions", this, sunCommand, string.Format("{0} [<value>]", sunCommand), kvp.Value, "", HandleSunConsoleCommand);
}
TimeZone local = TimeZone.CurrentTimeZone;
TicksUTCOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks;
m_log.Debug("[SUN]: localtime offset is " + TicksUTCOffset);
m_log.DebugFormat("[SUN]: localtime offset is {0}", TicksUTCOffset);
// Align ticks with Second Life
@@ -72,5 +72,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
{
return "BMP";
}
//Returns true if this extension is supported for terrain save-tile
public override bool SupportsTileSave()
{
return false;
}
}
}
@@ -57,5 +57,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
{
return "GIF";
}
//Returns true if this extension is supported for terrain save-tile
public override bool SupportsTileSave()
{
return false;
}
}
}
@@ -132,13 +132,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
{
// We need to do this because:
// "Saving the image to the same file it was constructed from is not allowed and throws an exception."
string tempName = offsetX + "_ " + offsetY + "_" + filename;
string tempName = Path.GetTempFileName();
Bitmap entireBitmap = null;
Bitmap thisBitmap = null;
if (File.Exists(filename))
{
File.Copy(filename, tempName);
File.Copy(filename, tempName, true);
entireBitmap = new Bitmap(tempName);
if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY)
{
@@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
}
thisBitmap = CreateGrayscaleBitmapFromMap(m_channel);
Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY);
// Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY);
for (int x = 0; x < regionSizeX; x++)
for (int y = 0; y < regionSizeY; y++)
entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y));
@@ -177,6 +177,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
return "SYS.DRAWING";
}
//Returns true if this extension is supported for terrain save-tile
public virtual bool SupportsTileSave()
{
return false;
}
/// <summary>
/// Protected method, generates a grayscale bitmap
/// image from a specified terrain channel.
@@ -91,6 +91,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
return "JPEG";
}
//Returns true if this extension is supported for terrain save-tile
public bool SupportsTileSave()
{
return false;
}
private static Bitmap CreateBitmapFromMap(ITerrainChannel map)
{
Bitmap gradientmapLd = new Bitmap("defaultstripe.png");
@@ -254,5 +254,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
{
return "LL/SL RAW";
}
//Returns true if this extension is supported for terrain save-tile
public bool SupportsTileSave()
{
return false;
}
}
}
@@ -57,5 +57,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
{
return "PNG";
}
//Returns true if this extension is supported for terrain save-tile
public override bool SupportsTileSave()
{
return true;
}
}
}
@@ -173,5 +173,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
{
return "RAW32";
}
//Returns true if this extension is supported for terrain save-tile
public bool SupportsTileSave()
{
return false;
}
}
}
@@ -57,5 +57,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
{
return "TIFF";
}
//Returns true if this extension is supported for terrain save-tile
public bool SupportsTileSave()
{
return false;
}
}
}
@@ -323,6 +323,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
return "Terragen";
}
//Returns true if this extension is supported for terrain save-tile
public bool SupportsTileSave()
{
return false;
}
/// <summary>
/// terragen SCAL floats need to be written intel ordered regardless of
/// big or little endian system
@@ -32,12 +32,31 @@ namespace OpenSim.Region.CoreModules.World.Terrain
{
public interface ITerrainLoader
{
// Returns true if that extension can be used for terrain save-tile
// (Look into each file in Region.CoreModules.World.Terrain.FileLoaders)
bool SupportsTileSave();
string FileExtension { get; }
ITerrainChannel LoadFile(string filename);
ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight);
ITerrainChannel LoadStream(Stream stream);
void SaveFile(string filename, ITerrainChannel map);
void SaveStream(Stream stream, ITerrainChannel map);
/// <summary>
/// Save a number of map tiles to a single big image file.
/// </summary>
/// <remarks>
/// If the image file already exists then the tiles saved will replace those already in the file - other tiles
/// will be untouched.
/// </remarks>
/// <param name="filename">The terrain file to save</param>
/// <param name="offsetX">The map x co-ordinate at which to begin the save.</param>
/// <param name="offsetY">The may y co-ordinate at which to begin the save.</param>
/// <param name="fileWidth">The number of tiles to save along the X axis.</param>
/// <param name="fileHeight">The number of tiles to save along the Y axis.</param>
/// <param name="regionSizeX">The width of a map tile.</param>
/// <param name="regionSizeY">The height of a map tile.</param>
void SaveFile(ITerrainChannel map, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY);
}
}
@@ -86,11 +86,16 @@ namespace OpenSim.Region.CoreModules.World.Terrain
private volatile bool m_tainted;
private readonly Stack<LandUndoState> m_undo = new Stack<LandUndoState>(5);
private String m_InitialTerrain = "pinhead-island";
/// <summary>
/// Human readable list of terrain file extensions that are supported.
/// </summary>
private string m_supportedFileExtensions = "";
//For terrain save-tile file extensions
private string m_supportFileExtensionsForTileSave = "";
#region ICommandableModule Members
public ICommander CommandInterface
@@ -109,6 +114,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
/// <param name="config">Config for the region</param>
public void Initialise(IConfigSource config)
{
IConfig terrainConfig = config.Configs["Terrain"];
if (terrainConfig != null)
m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain);
}
public void AddRegion(Scene scene)
@@ -120,7 +128,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
{
if (m_scene.Heightmap == null)
{
m_channel = new TerrainChannel();
m_channel = new TerrainChannel(m_InitialTerrain);
m_scene.Heightmap = m_channel;
m_revert = new TerrainChannel();
UpdateRevertMap();
@@ -143,11 +151,20 @@ namespace OpenSim.Region.CoreModules.World.Terrain
// Generate user-readable extensions list
string supportedFilesSeparator = "";
string supportedFilesSeparatorForTileSave = "";
m_supportFileExtensionsForTileSave = "";
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
{
m_supportedFileExtensions += supportedFilesSeparator + loader.Key + " (" + loader.Value + ")";
supportedFilesSeparator = ", ";
//For terrain save-tile file extensions
if (loader.Value.SupportsTileSave() == true)
{
m_supportFileExtensionsForTileSave += supportedFilesSeparatorForTileSave + loader.Key + " (" + loader.Value + ")";
supportedFilesSeparatorForTileSave = ", ";
}
}
}
@@ -556,43 +573,56 @@ namespace OpenSim.Region.CoreModules.World.Terrain
}
/// <summary>
/// Saves the terrain to a larger terrain file.
/// Save a number of map tiles to a single big image file.
/// </summary>
/// <remarks>
/// If the image file already exists then the tiles saved will replace those already in the file - other tiles
/// will be untouched.
/// </remarks>
/// <param name="filename">The terrain file to save</param>
/// <param name="fileWidth">The width of the file in units</param>
/// <param name="fileHeight">The height of the file in units</param>
/// <param name="fileStartX">Where to begin our slice</param>
/// <param name="fileStartY">Where to begin our slice</param>
/// <param name="fileWidth">The number of tiles to save along the X axis.</param>
/// <param name="fileHeight">The number of tiles to save along the Y axis.</param>
/// <param name="fileStartX">The map x co-ordinate at which to begin the save.</param>
/// <param name="fileStartY">The may y co-ordinate at which to begin the save.</param>
public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY)
{
int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX;
int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY;
if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight)
if (offsetX < 0 || offsetX >= fileWidth || offsetY < 0 || offsetY >= fileHeight)
{
// this region is included in the tile request
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
{
if (filename.EndsWith(loader.Key))
{
lock (m_scene)
{
loader.Value.SaveFile(m_channel, filename, offsetX, offsetY,
fileWidth, fileHeight,
(int)Constants.RegionSize,
(int)Constants.RegionSize);
MainConsole.Instance.OutputFormat(
"ERROR: file width + minimum X tile and file height + minimum Y tile must incorporate the current region at ({0},{1}). File width {2} from {3} and file height {4} from {5} does not.",
m_scene.RegionInfo.RegionLocX, m_scene.RegionInfo.RegionLocY, fileWidth, fileStartX, fileHeight, fileStartY);
m_log.InfoFormat("[TERRAIN]: Saved terrain from {0} to {1}", m_scene.RegionInfo.RegionName, filename);
}
return;
}
}
m_log.ErrorFormat(
"[TERRAIN]: Could not save terrain from {0} to {1}. Valid file extensions are {2}",
m_scene.RegionInfo.RegionName, filename, m_supportedFileExtensions);
return;
}
// this region is included in the tile request
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
{
if (filename.EndsWith(loader.Key) && loader.Value.SupportsTileSave())
{
lock (m_scene)
{
loader.Value.SaveFile(m_channel, filename, offsetX, offsetY,
fileWidth, fileHeight,
(int)Constants.RegionSize,
(int)Constants.RegionSize);
MainConsole.Instance.OutputFormat(
"Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}",
fileStartX, fileStartY, fileStartX + fileWidth - 1, fileStartY + fileHeight - 1,
m_scene.RegionInfo.RegionName, filename);
}
return;
}
}
MainConsole.Instance.OutputFormat(
"ERROR: Could not save terrain from {0} to {1}. Valid file extensions are {2}",
m_scene.RegionInfo.RegionName, filename, m_supportFileExtensionsForTileSave);
}
/// <summary>
@@ -1174,13 +1204,17 @@ namespace OpenSim.Region.CoreModules.World.Terrain
new Command("save-tile", CommandIntentions.COMMAND_HAZARDOUS, InterfaceSaveTileFile, "Saves the current heightmap to the larger file.");
saveToTileCommand.AddArgument("filename",
"The file you wish to save to, the file extension determines the loader to be used. Supported extensions include: " +
m_supportedFileExtensions, "String");
m_supportFileExtensionsForTileSave, "String");
saveToTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer");
saveToTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer");
saveToTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file",
"Integer");
saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file",
"Integer");
saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first tile on the file\n"
+ "= Example =\n"
+ "To save a PNG file for a set of map tiles 2 regions wide and 3 regions high from map co-ordinate (9910,10234)\n"
+ " # terrain save-tile ST06.png 2 3 9910 10234\n",
"Integer");
// Terrain adjustments
Command fillRegionCommand =
new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value.");

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