Compare commits

...

181 Commits

Author SHA1 Message Date
Justin Clark-Casey 0592bc69e5 Merge branch '0.8-post-fixes' into 0.8-extended 2014-11-11 20:37:40 +00:00
Justin Clark-Casey f9ec086565 Fix issue where llRemoteLoadScriptPin() would treat 0 (the default) as a valid set pin in a destination prim rather than the unset no pin state
Adds regression test for this case.
2014-11-11 17:42:39 +00:00
Kevin Cozens bd86ae3d67 Prevent exception if inventory item in llGiveInventory() call doesn't exist. 2014-10-16 17:12:15 -04:00
Kevin Cozens c9f494c00e Added RestrictEmail to make llEmail only send to avatars email address if true. 2014-10-16 17:12:15 -04:00
Justin Clark-Casey 3879f9a081 Change 0.8-post-fixes branch back to Post-Fixes flavour 2014-10-16 21:10:02 +01:00
Justin Clark-Casey 10ed3a5520 Change 0.8 post fixes to 0.8.0.2 release 2014-10-16 20:22:43 +01:00
Justin Clark-Casey (justincc) ddda314f14 Add some more llGiveInventory() regression tests 2014-10-16 20:18:20 +01:00
Melanie Thielker 8fb0dccffa Fix transferring inventory from prims to agent inventory 2014-10-16 20:18:16 +01:00
Justin Clark-Casey (justincc) 5f4c2eb5e6 Make LLUDP output queue refill thread active by default, since load tests have shown that this has better scalability.
For testing, previous behaviour can be restored with the console command "debug lludp oqre stop" at runtime.
2014-09-05 18:55:41 +01:00
Justin Clark-Casey (justincc) b40483dd27 For processing outbound http requests in the XMLRPCModule, start the thread through Watchdog for monitoring and stat purposes. 2014-09-04 18:53:59 +01:00
Justin Clark-Casey (justincc) cbf4106987 Start long-lived thread in IRCConnector via watchdog rather than indepedently, so that it can be seen in "show threads" and stats 2014-09-04 18:53:55 +01:00
Justin Clark-Casey (justincc) badeefdf99 Don't need to check separate physics status in bulletsim update since that method is only run for an indepndent thread anyway.
Also remove bulletsim monitored thread from watchdog on shutdown.
2014-09-04 18:53:45 +01:00
Justin Clark-Casey (justincc) 771011542a Make bulletsim thread alarm if no update for 5 seconds.
The cost is minimal (also done for scene loop) at the benefit of telling us if this thread simply stops for some reason.
2014-09-04 18:53:41 +01:00
Justin Clark-Casey (justincc) 2f0dfb055c minor: fix indenting from previous commit b08ab1e 2014-09-04 18:53:38 +01:00
Justin Clark-Casey (justincc) 78734dd723 If BulletSim is running on its own threads, start this thread via the thread watchdog.
This allows us to see the presence of the permanent thread via the "show threads" console comand.
Also adds the region name to the thread name.
2014-09-04 18:53:32 +01:00
Kevin Cozens 3f2aaa910a Don't show the ScrLPS data twice in the WebStats based statistics page. 2014-09-04 18:53:22 +01:00
Justin Clark-Casey (justincc) 793dc74cf4 Add [EntityTransfer] AllowAvatarCrossing setting to determine whether avatars are allowed to cross regions at all.
Defaults to true.  For test purposes.
2014-09-04 18:53:12 +01:00
Justin Clark-Casey (justincc) 3f8a0a95da Ignore whitespace when reading serialized XML objects.
This was previously effectively being done by XmlDocument in the multiple passes through the XML.
This change tells XmlReader to ignore whitespace.  This also means changing arguments to use XmlReader instead of XmlTextReader (a descendent of XmlReader) directly.
XmlReader.Create() has been the recommend way to create XML readers since .NET 2.0 as per MS SDK and is the only way to specific ignore whitespace settings.
2014-09-04 18:52:47 +01:00
Justin Clark-Casey (justincc) 38df5f1e9b Fix recent regression test TestDeserializeXmlObjectWithOtherParts() which was not meant to indent the input xml 2014-09-04 18:52:43 +01:00
Justin Clark-Casey (justincc) 8acb863060 Add regression test for deserializing xml objects with more than one non-root part. 2014-09-04 18:52:37 +01:00
Justin Clark-Casey (justincc) 27299438d0 minor: Eliminate more unnecessary code copying individual parameters for Vector3 copying in Scene - this is not necessary as Vector3 is a value type 2014-09-04 18:52:34 +01:00
Justin Clark-Casey (justincc) 5eb6b14854 On code section that rezzes single objects and attachments, reduce CPU use by reading asset XML a single time with a stream reader rather than multiple times.
Reading large XML documents (e.g. complex attachments) is CPU expensive - this must be done as few times as possible (preferably just once).
Reading these documents into XmlDocument is also more resource intensive than using XmlTextReader, as per Microsoft's own publication "Improve .NET Application Performance and Scalability"
Optimization of other cases will follow if this change is successful.
2014-09-04 18:52:29 +01:00
Justin Clark-Casey (justincc) 5614b28886 Remove race conditions from where SP.AbsolutePosition could change between the various property checks. 2014-09-04 18:52:20 +01:00
Justin Clark-Casey (justincc) a068c1dd9d Remove database connection locking in MySQLXAssetData. This is unnecessary as connections aren't shared and transactions are already in place where necessary. 2014-09-04 18:51:12 +01:00
Justin Clark-Casey (justincc) 3d49be21bc Remove query locking in MySQLUserProfileData. This is not necessary as the connection is not shared. 2014-09-04 18:51:06 +01:00
Justin Clark-Casey (justincc) 3438985b0d Remove some use of database connection locking from MySQLSimulationData - this has not been necessary for some time as database connections are not shared.
However, many locks remain since they may effectively be providing transactionality in some operations (e.g. prim updates across multiple tables).
These are candidates for being replaced with proper database transactions, since this would not block unrelated operations (e.g. land save and object save)
or unrelated operations on the same tables (e.g. storage of one linkset whilst another is being removed).
In practice, any performance deg due to contention is probably rare and short lived as the major prim operations are performed in memory and only persisted some time afterwards.
2014-09-04 18:51:01 +01:00
Justin Clark-Casey (justincc) 8dd6830efb Remove lock in MySQLFramework. This is not necessary as the connection is not shared. 2014-09-04 18:50:57 +01:00
Justin Clark-Casey (justincc) 2e1e076629 Removing locking on requests in MySQLAssetData.
These locks are not necessary since the connection is taken from the underlying mysql pool and not shared.
Such locking is already not done by some other parts of OpenSim.Data.MySQL.
Pointed out by arribasim-dev
2014-09-04 18:50:53 +01:00
Justin Clark-Casey (justincc) 30e04ee79c Extend drop command to "debug lludp drop <in|out>..." to allow drop of inbound packets.
For test/debug purposes.
2014-09-04 18:50:49 +01:00
Justin Clark-Casey (justincc) e0cb3ef959 Add "debug lludp drop out <add|remove> <packet-name>" console command for debug/test purposes.
This drops all outbound packets that match a given packet name.
Can currently only be applied to all connections in a scene.
2014-09-04 18:50:44 +01:00
Justin Clark-Casey (justincc) 4f12d5a3f1 minor:Give console feedback when we sit or stand pCampbot bots.
Also only write console lines for actually connected bots.
2014-09-04 18:50:39 +01:00
Justin Clark-Casey (justincc) c83eb4eb0a Add clientstack.<scene>.OQRERequestsWaiting stat
Only present if OQRE is enabled
2014-09-04 18:50:34 +01:00
Justin Clark-Casey (justincc) 34a5c3be24 Add experimental OutgoingQueueRefillEngine to handle queue refill processing on a controlled number of threads rather than the threadpool.
Disabled by default.  Currently can only be enabled with console "debug lludp oqre start" command, though this can be started and stopped whilst simulator is running.
When a connection requires packet queue refill processing (used to populate queues with entity updates, entity prop updates and image queue updates), this is done via Threadpool requests.
However, with a very high number of connections (e.g. 100 root + 300 child) a very large number of simultaneous requests may be causing performance issues.
This commit adds an experimental engine for processing these requests from a queue with a persistent thread instead.
Unlike inbound processing, there are no network requests in this processing that might hold the thread up for a long time.
Early implementation - currently only one thread which may (or may not) get overloaded with requests.  Added for testing purposes.
2014-09-04 18:50:29 +01:00
Justin Clark-Casey (justincc) 0cd4320cbd Make LLUDPServer.Scene publicly gettable/privately settable instead of protected so that other logging code in the clientstack can record more useful information
Adds some commented out logging for use again in the future.
No functional change.
2014-09-04 18:50:26 +01:00
Kevin Cozens 9a42589837 Prevent exception if inventory item in llGiveInventory() call doesn't exist. 2014-09-04 18:50:22 +01:00
Justin Clark-Casey (justincc) d0ed6ed86e Don't allow the last behavior to be removed from a pCampbot bot
If you want to stop existing behavious, add the None behaviour.
2014-09-04 18:50:11 +01:00
Justin Clark-Casey (justincc) 940c79a66d Resolve a small race condition on removing bot behaviours that might leave previous behaviour active
Also closes behaviours on disconnect instead of interrupt, though this makes no practical difference.
If existing behaviour is None, other added behavious will not take affect until None is removed (as this is an infinite wait until interrupted).
2014-09-04 18:50:06 +01:00
Justin Clark-Casey (justincc) 72be9eaa8b If a user moves back in sight of a child region before the agent has been closed on teleport, don't unnecessarily resend all avatar and object data about that region. 2014-09-04 18:50:02 +01:00
Justin Clark-Casey (justincc) ad1b5959d3 On teleport to a region that already has a child agent established (e.g. a neighbour) don't resend all the initial avatar and object data again.
This is unnecessary since it has been received (and data continues to be received) in the existing child connection.
2014-09-04 18:49:59 +01:00
Justin Clark-Casey (justincc) 4ec5349192 Make RootTerseUpdatePeriod and ChildTerseUpdatePeriod configurable in [InterestManagement] in OpenSim.ini for experimental purposes.
If n > 1 for RootTerseUpdatePeriod only every n terse update is actually sent to observers on same region, unless velocity is effectively zero (to stop av drift).
If n > 1 for ChildTerseUpdatePeriod only every n terse update is sent to observers in other regions, unless velocity is effectively zero.
Defaults are same as before (all packets are sent).
Tradeoff is reduction of UDP traffic vs fidelity of observed av mvmt.
Increasing n > 1 leads to jerky observed mvmt immediateley for root, though not on child, where experimentally have gone to n = 4 before jerkiness is noticeable.
2014-09-04 18:49:44 +01:00
Justin Clark-Casey (justincc) 045e644824 Make some existing reprioritization values changeable outside the scene for test purposes, and use more consise property syntax.
No functional change.
2014-09-04 18:49:30 +01:00
Justin Clark-Casey (justincc) bd54798923 On entity transfer of scene presence, replace polling sleep in SP.WaitForUpdateAgent() with a triggered event instead.
Rapid polls are more expensive than triggered events (several polls vs one trigger) and may be problematic on heavily loaded simulators where many threads are vying for processor time.
A triggered event is also slightly quicker as there is no maximum 200ms wait between polls.
2014-09-04 18:49:23 +01:00
Justin Clark-Casey (justincc) 5360cd4247 Remove redundant origin region lock in SP.CompleteMovement()
This is already going to be correctly set by WaitForUpdateAgent() earlier on in that method, which is always called where a callback to the originating region is required.
2014-09-04 18:49:18 +01:00
Justin Clark-Casey (justincc) d66e264e50 Only set up the UnackedMethod for an outgoing message if that message is actually meant to get an ack (because it's reliable). 2014-09-04 18:49:13 +01:00
Justin Clark-Casey (justincc) 238c51329e Terminate 'nothing' behaviour (and potentially others) by signalling using an event rather than polling connection state every 100ms
This kind of polling is very expensive with many bots/polling threads and appears to be the primary cause of bot falloff from the client end at higher loads.
Where inbound packet threads can't run in time due to contention and simulator disconnect timeout occurs.
2014-09-04 18:49:06 +01:00
Justin Clark-Casey (justincc) 605da59ed3 Change RootRotationUpdateTolerance from 0.01 to 0.1 in code as well. 2014-09-04 18:48:37 +01:00
Justin Clark-Casey (justincc) 70ca01283e Reduce default rotation AgentUpdate output sensitivity to a setting that cuts down UDP traffic without obvious adverse effects on observed avatar rotations.
Experimentally, on the Linden Lab grid the avatar can rotate slightly before triggering AvatarUpdates, whereas this is practically impossible in OpenSimulator.
These updates allow other avatars to see rotations, though sensitivity is low since other avatars can only be seen in one of 8 body rotations.
This commit changes sensitivity from 0.01 to 0.1, which better matches LL and reduces UDP traffic which has a beneficial impact on network and CPU load.
This has no impact on rotations in the simulator itself so simulation fidelity is the same as before.
To change this setting back for test/other purposes, edit RootRotationUpdateTolerance in the [InterestManagement] section of OpenSim.ini
2014-09-04 18:48:29 +01:00
Justin Clark-Casey (justincc) ba5f6fdfad Add RootPositionUpdateTolerance, RootRotationUpdateTolerance, and RootVelocityUpdateTolerance parameters to [InterestManagement] in OpenSimDefaults.ini
These govern when AgentUpdates are sent to observers on position, rotation and velocity changes to an avatar (including the avatar themselves).
Higher values reduce AgentUpdate traffic but at a certain level will degrade smoothness of avatar and perceived avatar movement.
2014-09-04 18:48:02 +01:00
Justin Clark-Casey (justincc) 59a79f52b3 refactor: Rename recent new Client*UpdateTolerance to Root*UpdateTolerance for better accuracy and consistency with other similar parameters 2014-09-04 18:47:58 +01:00
Justin Clark-Casey (justincc) 4443e05d5d Go back to disconnecting bots in parallel since serially is too slow.
However, disconnecting now halts any current connection, with the possible exception of the single currently connecting bot.
2014-09-04 18:47:48 +01:00
Justin Clark-Casey (justincc) 04cb9bc4bf Put pCampbot "disconnect" command on separate thread like "connect" so that we can continue to run status commands whilst bots are disconnecting. 2014-09-04 18:47:41 +01:00
Justin Clark-Casey (justincc) 9fe282f902 Allow "show bots" pCampbot console command to quickly report status by not locking entire bot list for almost 100% of connection time. 2014-09-04 18:47:36 +01:00
Robert Adams 588a3b91c5 BulletSim: thread safe handling of list of avatars.
Fix for 7284 which is an enumeration exception when starting up a region.
2014-09-04 18:46:29 +01:00
Justin Clark-Casey (justincc) d19126207e Implement "scene debug set root-upd-per" for dropping 1 in N root agent updates except to originator
For experimental purposes.
Also corrects a previous bug where each terse update sent was counted rather than each set of terse updates to agents.
2014-09-04 18:45:55 +01:00
Justin Clark-Casey (justincc) 6757633f12 Add debug mechanism for only sending 1 in N AgentUpdate packets to child agents.
Allows experiments in manually reducing updates under heavy load.
Activated by "debug scene set client-upd-per" console command.
In a simple test, can send as few as every 4th update before observed movement starts becoming disturbingly rubber-banded.
2014-09-04 18:45:50 +01:00
Justin Clark-Casey (justincc) 71d425c07c Add "debug scene set appear-refresh true|false" to control whether periodic appearance refresh is active.
Corresponds to ResendAppearnceUpdates setting in [Appearance] in OpenSim.ini
This was originally implemented to alleviate cloud appearance problems but could be too expensive with large numbers of avatars.
2014-09-04 18:45:40 +01:00
Justin Clark-Casey (justincc) cc149a95e7 Make it possible to change avatar position update, rotation and velocity tolerances on the fly.
This is done via "debug scene set client-pos-upd, client-rot-upd, client-vel-upd".
For testing purposes.
2014-09-04 18:45:34 +01:00
Justin Clark-Casey (justincc) 01bd3a8632 Allow the "debug scene set physics false|true" command to work when bulletsim physics is running in a separate thread.
This will also allow the "disable physics" setting in the region debug viewer dialog to work in this circumstance.
2014-09-04 18:45:29 +01:00
Justin Clark-Casey (justincc) 8938bc6905 minor: make "debug scene set" usage command accurate again from last commit f6f7585 2014-09-04 18:45:24 +01:00
Justin Clark-Casey (justincc) 1b037c8e8e Add a "debug scene set child-repri <double>" command that allows child reprioritization distance to be changed on the fly.
This governs when child agent position changes are sent to neighbouring regions.
Corresponding config parameter is ChildReprioritizationDistance in [InterestManagement] in OpenSim.ini
For test purposes.
2014-09-04 18:45:15 +01:00
AliciaRaven 058861ec70 Include option to remove auto backup files older than given number of days. New property created to specify how many days to keep files for. Off by default, also made sure only oar files will be removed. 2014-09-04 18:38:41 +01:00
Justin Clark-Casey 4a90dd3556 Change 0.8-post-fixes branch back to Post_Fixes flavour 2014-08-23 00:02:12 +01:00
Justin Clark-Casey f6d02a63eb Change 0.8 post fixes branch to version 0.8.0.1 with release flavour. 2014-08-22 20:19:16 +01:00
Oren Hurvitz 422f718949 Fixed crash when using Allowed/Denied Viewers, and the viewer's name is shorter than one of the test strings
This fixes http://opensimulator.org/mantis/view.php?id=7294
2014-08-22 19:20:19 +01:00
Oren Hurvitz 3176237169 Fixed premature closing of the connection in DataSnapshotManager 2014-08-08 20:46:59 +01:00
Justin Clark-Casey (justincc) a4595b18ca Make currently unfiltered EventQueue log messages only appear now at DebugLevel 1
This covers event queue setup messages and some outgoing messages (e.g. EnableSimulator)
In my experience these messages are only useful if you really know what they mean and you're looking for them
Otherwise, they're quite spammy.
Event queue DebugLevel 1 is enabled with the "debug eq 1" console command
2014-08-05 00:51:17 +01:00
Justin Clark-Casey 4640281e57 Add conflict resolution that should have been done in conflict resolution of 4e3a2d3a64 2014-08-02 01:04:58 +01:00
Justin Clark-Casey (justincc) 319bbce517 If REMOVEAGENTFROMGROUP core groups call fails because requesting agent does not have sufficient permission, return null failure result rather than true.
On non-HG this is on the only recognized failure state so we can return more information in the error result.
On HG there are multiple failure states which would require more work to distinguish, so currently return the unsatisfying "Internal Error" like some other existing calls.
2014-08-02 00:58:37 +01:00
Justin Clark-Casey (justincc) a48b3ef97a Don't overwrite the null result with the true result is groups service REMOVEAGENTFROMGROUP call has failed because of missing parameters 2014-08-02 00:58:33 +01:00
Justin Clark-Casey (justincc) 32a9fcd8b3 Fix bug where calling PUTGROUP on the core groups service without specifying a ServiceLocation would set the group name to an empty string.
This should set the ServiceLocation to an empty string instead.
2014-08-02 00:58:30 +01:00
Robert Adams eedefdc5ff BulletSim: rearrange code for sensing whether shapes have been
constructed.
Add routine to check for failed and use that method rather than
    checking individual state.
2014-08-02 00:58:27 +01:00
Justin Clark-Casey (justincc) 05dfc38f66 Add inventory.<url>.RequestsMade stat.
This gives a count of all requests made to the remote inventory service.
This is finer grained than inventory.httpfetch.ProcessedFetchInventoryRequests since such a request can be comprised of many individual inv service calls.
In addition, this will count requests that don't go through the HTTP inventory fetch (e.g. HG, archiving, etc.)

Conflicts:
	OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs
2014-08-02 00:58:23 +01:00
Justin Clark-Casey (justincc) 95f3a9452d Fix issue with TestTextureNotFound in previous commit 1e3027a
Stop failure by actually giving the test handler a path instead of null
2014-08-02 00:58:15 +01:00
Justin Clark-Casey (justincc) 3410b36d76 Temporary stop CAPS service points from being added to stats as this can be a huge number.
A stop gap solution - a better one may be to improve stats display on simulator-side.
Caps information is still accessible via the "show caps stats by user" and "show caps stats by cap" commands
2014-08-02 00:58:12 +01:00
Justin Clark-Casey (justincc) 2f7d950ead Add stats for service endpoints using existing data.
For each service endpoint (e.g. posts to the xinventory service), a stat is available which shows the number of requests received and moving average per second
The full name is "service.<http-method>:<path>.requests (e.g. service.POST:/xinventory.requests)
2014-08-02 00:58:09 +01:00
Michael Cerquoni 26916806db fix comments in physics section of [Startup] to reflect the actual default engine. 2014-08-02 00:58:06 +01:00
Justin Clark-Casey (justincc) bdfbe4d0e2 Add missing default female hair texture for Ruth avatar.
This was not in library assets despite being referred to in assets/BodyPartsAssetSet/base_hair.dat
Texture ID is 7ca39b4c-bd19-4699-aff7-f93fd03d3e7b
Taken from https://github.com/openmetaversefoundation/simiangrid/blob/master/Grid/default_assets/Default%20Female%20Hair-7ca39b4c-bd19-4699-aff7-f93fd03d3e7b.j2c
2014-08-02 00:58:02 +01:00
Justin Clark-Casey (justincc) dfaabf4d0d Fix recent regression in 3c6becd5 where login or hg login to variable sized regions failed with outdated simulator message.
I forgot that a null 'their version' would not be passed over the wire and ends up as an empty string instead (like older simulators).
So instead pass through the correct simulator protcol version instead (SIMULATOR/0.3) when querying from login or hg login.
Also removes a debug console write for agent limit accidentally left in for the same commit.
Relates to mantis 7276
2014-08-02 00:57:59 +01:00
Justin Clark-Casey (justincc) fdb0c7389e minor: convert tabs to spaces that got in on recent commit 4a9282e 2014-08-02 00:57:49 +01:00
Justin Clark-Casey (justincc) 92e2478059 On login and first HG entrance to a foreign grid, perform query access checks before proceeding. 2014-08-02 00:57:43 +01:00
Justin Clark-Casey (justincc) b6e32c000b minor: Limit processor related stats to 3 decimal places instead of all the places.
Easier to read and analyze, and probably still too much detail (1 dp would probably be fine)
2014-08-02 00:57:36 +01:00
Justin Clark-Casey (justincc) ed4a4d6bbd Fix CPU processor use reporting on Mono.
Despite the comments in the code, it appears that the issue where the .NET performance counter was wrongly idle time time on Mono was fixed in 2009.
https://bugzilla.novell.com/show_bug.cgi?id=468625
Which means that the workaround is no longer necessary and produces bad results instead.
2014-08-02 00:57:33 +01:00
BlueWall 7e0d0282c4 Add missing parts to profiles - classified delete 2014-08-02 00:57:29 +01:00
Oren Hurvitz 8de1be746f Fixed: after a Hypergrid teleport, attachments often either disappear, or appear both on the avatar AND as in-world objects.
Another manifestation of this bug is that after a Hypergrid teleport, when you click on one of the avatar's attachments the object doesn't show its name. This means that the viewer knows the attachment is there, but the simulator does not.

The problem was caused by treating Hypergrid teleports as if they're Logins (because the teleport flag ViaLogin is enabled).

This may fix: http://opensimulator.org/mantis/view.php?id=7238
This may fix: http://opensimulator.org/mantis/view.php?id=7220
2014-08-02 00:57:24 +01:00
Oren Hurvitz e7bd4a11aa Don't append attachments multiple times 2014-08-02 00:57:20 +01:00
Oren Hurvitz f1536de438 Allow reading the BulletSim detail log while the sim is running 2014-08-02 00:57:17 +01:00
Oren Hurvitz 4514799c8d Changed the default XBakes directory to a local path: "./bakes".
Previously it was an absolute path. Now it's a sibling of the maptiles directory.

This fixes http://opensimulator.org/mantis/view.php?id=7063
2014-08-02 00:57:11 +01:00
Oren Hurvitz 5f0456d91f XBakes: store the assets only in the sim's local assets cache; not in the main assets server. Also, some cleanup. 2014-08-02 00:57:07 +01:00
Oren Hurvitz 9a2dc6a0d7 Log RestClient requests similarly to WebClient (e.g, "debug http all 6" logs the entire request and response) 2014-08-02 00:57:04 +01:00
Oren Hurvitz 37fcc827e2 Fixed problems if an avatar tries to cross regions when the previous cross hasn't completed yet
This caused the client to stop responding, and even the simulators to have problems. The solution is to disallow crossing before the previous cross has completed.
2014-08-02 00:56:58 +01:00
Oren Hurvitz 5229a3c51c Added locking in AccessModule to prevent possible errors when shutting down a simulator that has >1 region 2014-08-02 00:56:54 +01:00
Oren Hurvitz e16403db80 Minor: changed "existant" to "existent" 2014-08-02 00:56:37 +01:00
Oren Hurvitz c4467353da Removed warning about YieldProlog 2014-08-02 00:56:29 +01:00
Oren Hurvitz d616f75d9a In "show throttles", show the maximum drip rate. This shows whether a client is being throttled due to past poor performance. 2014-08-02 00:56:26 +01:00
Oren Hurvitz ae53c6b834 Include the group name in group IM's
When sending an ImprovedInstantMessage to a group, the IM's binary bucket is supposed to contain the group's name (this is what SL does). Singularity uses this to show the group name when it shows the message at the bottom of the viewer for a few seconds: "[Group Name] From User: Message". Before this update, the group name was empty ("[]").

This update doesn't have any visible effect in Firestorm, because it doesn't use the group name sent in the IM.
2014-08-02 00:56:23 +01:00
Oren Hurvitz af344aa532 Added "debug packet --all" option, which changes the packet logging level for both current and future clients
The existing "--default" option only changes the logging level for future clients.
2014-08-02 00:56:16 +01:00
Oren Hurvitz 8920c65b9c Fixed the logic that decides if a packet was queued (it was reversed) 2014-08-02 00:56:13 +01:00
Oren Hurvitz e41e52e097 Close streams immediately when we finish using them 2014-08-02 00:55:57 +01:00
Robert Adams 01d13b4ad7 Add code to GridService to check for overlapping of varregions
when registering a new region.

Adds parameter "[GridService]SuppressVarRegionOverlapCheckOnRegistration=false"
that can be turned on to suppress the error check if a simulator's database
has old regions that overlap.
2014-08-02 00:55:47 +01:00
Justin Clark-Casey (justincc) 74848e9cdb minor: remove long unused RegionInfo.ignoreIncomingConfiguration 2014-08-02 00:55:12 +01:00
Justin Clark-Casey (justincc) ff88d371d2 minor: remove long unused RegionInfo.commFailTF 2014-08-02 00:55:04 +01:00
Justin Clark-Casey (justincc) 19bd27071a refactor: slightly adjust some code in ODECharacter.Move() to eliminate a condition check without changing the logic 2014-08-02 00:55:01 +01:00
Justin Clark-Casey (justincc) ad3ce54aca With ODE physics, fix an issue where the avatar couldn't jump and then move forward when moving south or west.
Addresses http://opensimulator.org/mantis/view.php?id=5003
Thanks to UbitUmarov for this fix.
2014-08-02 00:54:57 +01:00
Robert Adams db17f98c6f BulletSim: rearrange code to prevent using null pointers when a
child mesh is not available when building a linkset.
2014-08-02 00:54:54 +01:00
Michael Cerquoni 66340824e5 fix all instances of "non-existant" to "non-existent" (spelling mistakes) thanks Ai Austin for pointing this out. 2014-08-02 00:54:48 +01:00
Justin Clark-Casey (justincc) 539ffb7769 Use thread-safe version of .NET Random as the SDK class is not thread-safe.
As per http://msdn.microsoft.com/en-us/library/system.random%28v=vs.100%29.aspx, the .NET Random class is not thread-safe.
If called by multiple threads at once, methods may return 0.
Except for llRand(), other OpenSimulator code did not lock before calling a shared Random instance.
This commit adds a ThreadSafeRandom class that extends Random but does internal locking so that it is thread-safe.
This change is invisible to existing callers and the explicit locking in the llFrand() implementation is now redundant.
2014-08-02 00:54:42 +01:00
Dev Random d35b5737a8 Call RemoveScriptInstance when removing from inventory 2014-08-02 00:53:35 +01:00
Justin Clark-Casey (justincc) 1670d306d7 minor: Move debug xengine script console command to Debug help section where other debug commands live. 2014-08-02 00:53:32 +01:00
Justin Clark-Casey (justincc) 405db6d450 refactor: use existing Compiler.CreateScriptsDirectory() (renamed to CheckOrCreateScriptsDirectory()) when checking that scripts directory exists on compile.
Code was identical apart from error logging, but if there are failures creating these directories then you'll be
seeing lots of errors anyway, and these will be more informative
2014-08-02 00:53:20 +01:00
Justin Clark-Casey (justincc) 743b1efdb4 Fix bug in "show modules" comamnd that was showing shared modules as non-shared and non-shared as shared 2014-08-02 00:53:14 +01:00
Justin Clark-Casey (justincc) b243cde14f Turn RestClient.Request() logging down the debug and comment out for now. 2014-08-02 00:53:10 +01:00
Justin Clark-Casey (justincc) 73ed56f46a Fix issue with running "stats record start|stop" console command
In commit e6080a38 (Wed Mar 19 00:29:36 2014) I renamed this from "debug stats record start|stop"
Unfortunately, I didn't do this fully so before this commit "stats record start|stop" will report a usage failure with the old debug text.
Unfortunately this is in the 0.8 release.  The workaround is to repeat the last command twice (e.g. "stats record start start")
2014-08-02 00:53:06 +01:00
Justin Clark-Casey (justincc) 6b5533dbdb Add experimental "show grid size" robust console command.
This will show an approximate grid size that doesn't count regions that are hyperlinks
Not particularly trustworthy since it will still count regions that are not active but were not deregistered (deliberately or due to simulator crash or similar)
2014-08-02 00:52:53 +01:00
Diva Canto 3dd5d8508c Small change to my previous commit: not so aggressive on the trigger, please. 2014-08-02 00:52:46 +01:00
Justin Clark-Casey (justincc) 2a15739935 Show region size column in simulator version of "show regions" console command 2014-08-02 00:52:25 +01:00
Justin Clark-Casey (justincc) fabe054608 Adjust "show regions" and "show region" robust service console output to show size
"show regions" drops the owner id column but is till present in "show region"
"show regions" name column expanded to allow for longer hg regions (probably still too short, may eventually have to truncate rather than taking up huge screen space)
2014-08-02 00:52:22 +01:00
Diva Canto fe1ae9db1b Instrument the UDP path of creating assets so that it triggers an asset post for users with different asset servers 2014-08-02 00:52:15 +01:00
Justin Clark-Casey (justincc) 12ce20a203 minor: put standard 'category' in brackets at front of log messages from previous commit 3d70db4a 2014-08-02 00:52:12 +01:00
Latif Khalifa 45e280274c When uploading mesh objects with textures also create inventory items for uploaded textures.
This implements:
http://opensimulator.org/mantis/view.php?id=7250
2014-08-02 00:52:07 +01:00
Justin Clark-Casey (justincc) e87a0d9db1 Still log (but this time with warning rather than an exception) if we regenerate a new child caps seed for a region where we already have one.
I think it's still useful to know this to show up any errors early, but it's reasonable to still carry on rather than throw an exception.
Follow on from Diva's commit 9643792
2014-08-02 00:51:57 +01:00
Diva Canto 62e9cdd72a On logout, delay the removal of AgentCircuitData until the very end, because that data structure contains important information about the agent that may be needed by modules. 2014-08-02 00:51:53 +01:00
Diva Canto 3730163e5d This fixes the bug related to rebooting neighboring varregions while avatars are logged in; the avies would not see the region anymore until they relogged. Same problem as before: inconsistent calculation of scope. 2014-08-02 00:51:49 +01:00
Diva Canto 4e3a2d3a64 It turns out that child agent management has had a bug for a while: there was an inconsistency in the scope between opening and closing child agents in neighboring regions. For opening (in EnableChildAgents), the region's DrawDistance was being used; for closing (in IsOUtsideView) , the viewer's (SP) DrawDistance was being used. This fixes this inconsistency, therefore eliminating bugs observed in TPs between, at least, neighboring varregions. 2014-08-02 00:51:36 +01:00
Diva Canto e9447cc836 Avoid an exception in creating child agents some times. 2014-08-02 00:50:21 +01:00
Justin Clark-Casey (justincc) 693a3ea8fa Temporarily disable new regression test TestLifecycle() until I have a chance to fix it
This was working for me locally because it was still picking up all my *.ini config files, which jenkins won't have in its test env
2014-08-02 00:50:18 +01:00
Justin Clark-Casey (justincc) 7e2927f537 Re-enabled TestLifecycle regression test logging so I can get some idea of why it's failing on jenkins but not locally 2014-08-02 00:50:15 +01:00
Justin Clark-Casey (justincc) ba745a524d Actually call Close() for shared region modules when the simulator is being shutdown.
Adds regression test for this case.
2014-08-02 00:50:10 +01:00
Justin Clark-Casey (justincc) cf8b6efaf2 minor: Change default max phys prim size in code to match OpenSimDefaults.ini 2014-08-02 00:50:02 +01:00
Justin Clark-Casey (justincc) 40f7062d02 minor: change allow script crossings default in code to true in order to match OpenSimDefaults.ini 2014-08-02 00:49:59 +01:00
dahlia 81fe05bb84 add LSL constant PRIM_ALPHA_MODE 2014-08-02 00:49:56 +01:00
Vegaslon ed6aabb197 Bulletsim: Create AvatarTerminalVelocity to BulletSim like what ODE and SL has. Before this falling from really high caused the avatar to fall faster then the veiwer can handle and cause camera issues. 2014-08-02 00:49:50 +01:00
dahlia 8542f34d7d add LSL constants PRIM_SPECULAR and PRIM_NORMAL 2014-08-02 00:49:46 +01:00
Diva Canto 025ac85a46 Bug fix in map teleports in varregions. The cherry was missing from the ice-cream Sunday: the packet itself was hardcoding the size of the region... 2014-08-02 00:49:43 +01:00
Robert Adams 5edffc9ecd BulletSim: add some locking for collision lists to prevent collsions
from locking up when running BulletSim on a separate thread.
2014-08-02 00:49:39 +01:00
Aleric Inglewood 56a3d2f00d Improved line map heuristics.
If the C# column can't be found in the positionMap (but the line can),
use the map immediately after it while correcting for the offset,
unless that results in an LSL position before the previous LSL position
in the positionMap.

The idea behind this heuristic is that in most, if not all cases C#
consumes more characters than LSL (for example LSL_Types.LSLInteger
instead of just 'integer').

Thus if the distance between the columns of two markers differ in
the C# and LSL file, the distance in the C# file will be larger.
Moreover, we can assume that every time this happens we will have
a marker at the beginning of the longer 'keyword', because those
keywords were generated by us in the first place.

For example:

C#:     LSL_Types.LSLInteger f2(LSL_Types.LSLString s)
        ^                       ^
        1                       2

will always have markers at the beginning of the long keywords
'LSL_Types.LSLInteger' and 'LSL_Types.LSLString'.
If an error is generated in between (for example at the beginning
of the function name 'f2') then the correct position is found
by using an offset relative to 2 rather than 1.

Note that a case where this isn't working correctly is
when the user adds extra spaces. For example:

LSL:   integer f2(    string s)

would still use the start of 'string' as reference and
then go backwards 3 characters only because the corresponding
C# still looks like

C#:     LSL_Types.LSLInteger f2(LSL_Types.LSLString s)
                             ^  ^
			     only 3 chars difference

and the reported error at 'f2' would be here:

LSL:   integer f2(    string s)
                   ^

This can only be fixed by generating a mapping for 'f2' itself, or
generating a mapping whenever the amount of spaces is changed.
2014-08-02 00:49:36 +01:00
Aleric Inglewood 28babf307e Fix looking up line number and colum when there is no exact match.
When a compile error reports a colum/error that is not an exact
match in the positionMap dictionary, the last position in the
map with a line number and position before the reported error
should be returned.

The old code had the following problems:
1) It returns l,c - which are line and column of the C# file, not LSL.
2) It doesn't set l to 'line' when the map has an entry with 'line'.
3) It sorts the map without taking columns into account, which may
   result in a random order of the columns. With my mono implementation
   the columns were reversed in order.

For example, if the map contains the following lines:

99,5,49,10
100,30,50,10
100,40,1,0
101,5,51,10

and a translation of 100,35 was requested,
then the old code would compare '100' with the keys in
the first column - setting l to that key while it is
smaller. Hence, l is set to 99.
Then it finds the key 100 and doesn't update l.
Because of the reversed sort order, it first compares
the column 35 with 40, finding that it is smaller
and therefore it stops; returning 99,1 instead of finding
the correct 100,30 entry and returning 50,10.

This patch causes 50,10 to be returned.

The remaining problems after this patch are:
1) The sorting might not be necessary at all.
2) The is code duplication (I fixed both instances,
   but really there should be no code duplication
   imho).
2014-08-02 00:49:32 +01:00
Robert Adams 03c6d2b0b4 BulletSim: stop processing linkset child when it is discovered that the
child doesn't have a physical shape. Another attempt at fixing Mantis 7191.
2014-08-02 00:49:28 +01:00
Robert Adams b293242017 BulletSim: more tweeks to AliciaRaven's flying mods. Added parameters
AvatarFlyingGroundMargin and AvatarFlyingGroundUpForce set to 5.0 and
2.0 respectively which seems to give about the same action as in SL.
Also moved force addition to before the velocity to force computation
so the upward velocity is properly applied to the avatar mass.
2014-08-02 00:49:24 +01:00
Justin Clark-Casey (justincc) 924ca8e2e9 refactor: Simplify compilation result tests by factoring out common code. 2014-08-02 00:49:21 +01:00
Justin Clark-Casey (justincc) 86630a9010 In compiler regression tests, setup and teardown structures for each test to avoid any possibility of inter-test inter-ference 2014-08-02 00:49:17 +01:00
Justin Clark-Casey (justincc) 68fcb132d9 Fix issue with LSL jumps screwing up the C# compiler error -> LSL code position map and leading to invalid error line numbers/columns
This is because jump statement generation was mistakenly inserting its own line without updating the csharp positions in CSCodeGenerator.
This is Aleric Inglewood's patch in http://opensimulator.org/mantis/view.php?id=7195 but applied to opensim itself rather than the defunct code generation in opensim-libs.  Thanks!
This patch also adds a regression test for this case from myself.
2014-08-02 00:49:02 +01:00
AliciaRaven 6f582aeaff Fix previous commit to ignore water height and allow flying underwater (swimming)
Signed-off-by: Michael Cerquoni <nebadon2025@gmail.com>
2014-08-02 00:48:59 +01:00
AliciaRaven fa1f6031ca Add upward force to flight when close to the ground. Prevents current belly flop to the floor when flying with bullet physics and acts more like ODE and SL flight.
Signed-off-by: Michael Cerquoni <nebadon2025@gmail.com>
2014-08-02 00:48:55 +01:00
Justin Clark-Casey eea3be9b17 Change flavour to post-fixes 2014-06-17 18:44:31 +01:00
Justin Clark-Casey 698dfe8977 Change 0.8 flavour to release 2014-06-17 16:48:36 +01:00
Justin Clark-Casey (justincc) 25757a6abb If MaterialsModule unexpected sees a part with DefaultTexture of null, log this with a warning. 2014-06-17 16:44:27 +01:00
Justin Clark-Casey (justincc) 5a1017241f If processing a queued request fails up to the top of the stack, log the exception and move to the next request rather than terminate the simulator. 2014-06-17 16:44:23 +01:00
Justin Clark-Casey (justincc) 76ee671dc6 In materials module, if a texture entry somehow has no default entry then don't try to extract materials data rather than throw an exception 2014-06-17 16:44:06 +01:00
Diva Canto 2cdef143c4 Behavior change: only local users can set home in any parcel of a grid. Setting it for foreign users does not make sense, since cntrl+shift+H always teleports them back to their original grid. 2014-06-16 18:04:45 +01:00
Diva Canto 34a645efb6 Manual change as per patch in mantis #7212. (the patch failed to apply, but the fix was good) Thanks FreakyTech. 2014-06-16 18:04:39 +01:00
Robert Adams 02980336a3 Add [Startup]LogShowStatsSeconds=n parameter which controls the interval
that simulator statistics is output to the console. Setting to zero turns
stats logging off.
2014-06-16 18:04:35 +01:00
Justin Clark-Casey 8899f2e2bb Change release flavour to rc3 2014-06-10 23:12:41 +01:00
Justin Clark-Casey (justincc) 60d4b0999c Add rc3 flavour option 2014-06-10 23:12:08 +01:00
Diva Canto a8edc908e0 Don't try to package null invites. 2014-06-10 20:29:24 +01:00
Robert Adams 901602411c BulletSim: fix exceptions while rebuilding linksets with mesh children.
This should get around the exception reported in Mantis 7191 and 7204
by checking for the unbuilt child and rebuilding the linkset the next tick.
A warning message is output when this rebuild happens and this message is
clamped to 10 times in case there is a problem with a loop.
2014-06-10 20:29:05 +01:00
Michael Cerquoni d98a19b398 fix the comment section of max_distance setting to reflect default value 2014-06-10 20:29:00 +01:00
Diva Canto e8f363ff90 Missed this ini change in previous commit 2014-06-10 20:28:54 +01:00
Michael Cerquoni 5e4cf1b84c bump default teleport limit to 65535 regions 2014-06-10 20:28:50 +01:00
Diva Canto ffe07527fc Added simulation version compatibility check so that agents coming from 0.7.6 to a varregion running in 0.8 and above will be denied teleport, rather than be allowed and crash the viewer. 2014-06-10 20:28:47 +01:00
Diva Canto 72456f90a4 Better comment regarding SizeX and SizeY 2014-06-10 20:28:40 +01:00
Diva Canto 0cf5ea9420 Amend to previous commit -- write down the problematic Profile server URL. 2014-06-10 20:28:36 +01:00
Diva Canto becb949a33 May fix mantis #7133 2014-06-10 20:28:29 +01:00
Diva Canto 63a6998409 Updated Regions.ini.example to include var regions configs. 2014-06-10 20:27:40 +01:00
Michael Cerquoni 15f323295b add Alicia Raven to Contributors list, thanks for the patch! 2014-06-10 20:27:35 +01:00
AliciaRaven 2c823c9f72 Fix AutoBackupModule and include option to skip saving assets.
Signed-off-by: Michael Cerquoni <nebadon2025@gmail.com>
2014-06-10 20:27:31 +01:00
Diva Canto d541f150d0 Added a ResetLand method to RemoteAdmin, whereby all land is reset with the given parameters. 2014-06-10 20:27:10 +01:00
Diva Canto 4da471a5aa Fix a bug where estate not found would result in a dummy estate record with erroneous information.
Also, added conversion of EstateSettings from/to key-value pairs in preparation for robust net work connectors.
2014-06-10 20:22:18 +01:00
Diva Canto 75d21aa71a Added missing reference 2014-06-10 20:21:58 +01:00
Justin Clark-Casey (justincc) 88e9cd0eee minor: rename velocidyDiff -> velocityDiff 2014-06-10 20:21:52 +01:00
Justin Clark-Casey (justincc) 26ec918ec8 minor: Add some commented out logging to ScenePresence.SendTerseUpdateToAllClients() which is extremely helpful when investigating presence update triggers. 2014-06-10 20:21:48 +01:00
Justin Clark-Casey (justincc) 4bc2201453 Fix issue with BulletSim avatar level flight jitter by commenting out RawVelocity update threshold for now in BSCharacter.UpdateProperties().
For some reason as yet unidentified (feedback?) a threshold above 0.4 here causes the RawVelocity to move between a lower and upper bound rather than remaining constant.
The RawVelocity increased until it triggered the threshold update, at which point it started to decrease until it again triggered the threshhold update.
This delta-v was enough to exceed the checks in ScenePresence.SendTerseUpdateToAllClients() and produce jittery avatar flight because of the fluctuating velocity.
With a threshold of 0.4 (or 0, as with ODE), the RawVelocity remains constant in BulletSim and so avatar flight becomes mostly smooth - remaining occasional glitches appear to be a result of errors in distance extraploation.
There are no obvious problems with commenting out the threshold.
Misterblue, if this is wrong or I've missed some subtlety here, please feel free to revert and/or correct.
The same considerations may or may not apply to object velocity updates.
2014-06-10 20:21:44 +01:00
dahlia 344db4dc0b Add a 0 parameter overload for RestClient.Request() for use when no auth is required. This preserves API compatibility for external modules using this function. 2014-06-10 20:21:39 +01:00
Diva Canto de6e3edfbb Moved these two estate-related interfaces to the projects where they belong. 2014-06-10 20:21:33 +01:00
Justin Clark-Casey (justincc) a1e92dead2 minor: Comment out log line in Groups V2 GroupsServicePostHandler for now which logs every request it receives. 2014-06-10 20:21:24 +01:00
Justin Clark-Casey (justincc) 068cab94e0 Fix bug where setting a parcel in a varregion for sale would make sale bitmap generation in WorldMapModule throw an exception on next startup.
This commit replaces the hardcoded region sizes in WorldMapModule.GenerateOverlay() with numbers pulled from m_scene.RegionInfo
2014-06-10 20:21:15 +01:00
BlueWall 7b66ef44c3 Add some info about xbuild command line switches to clean and select between producing Debug or Release binaries 2014-06-10 20:21:09 +01:00
Justin Clark-Casey dcbe9d1ffb Merge branch 'master' into 0.8-post-fixes 2014-05-27 23:42:20 +01:00
Justin Clark-Casey 3a477a29d7 Change release flavour to RC2 2014-05-27 23:38:08 +01:00
Justin Clark-Casey 3f703ae1cb Merge branch 'master' into 0.8-post-fixes 2014-05-27 23:29:54 +01:00
Justin Clark-Casey c38736de82 Merge branch 'master' into 0.8-post-fixes 2014-05-06 19:57:31 +01:00
Justin Clark-Casey 766c94213c Change version flavour to RC1. Make version number more normal "0.8" rather than "0.8.0" 2014-05-06 19:04:44 +01:00
168 changed files with 4988 additions and 2740 deletions

1
.gitignore vendored
View File

@ -54,6 +54,7 @@ bin/Regions/*
bin/UserAssets bin/UserAssets
bin/assetcache bin/assetcache
bin/maptiles bin/maptiles
bin/bakes
bin/estate_settings.xml bin/estate_settings.xml
bin/config-include/CenomeCache.ini bin/config-include/CenomeCache.ini
bin/config-include/FlotsamCache.ini bin/config-include/FlotsamCache.ini

View File

@ -19,10 +19,14 @@ Prereqs:
From the distribution type: From the distribution type:
* ./runprebuild.sh * ./runprebuild.sh
* nant (or xbuild) * nant (or !* xbuild)
* cd bin * cd bin
* copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include * copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
* run mono OpenSim.exe * run mono OpenSim.exe
!* xbuild option switches
!* clean: xbuild /target:clean
!* debug: (default) xbuild /property:Configuration=Debug
!* release: xbuild /property:Configuration=Release
# Using Monodevelop # Using Monodevelop

View File

@ -68,6 +68,7 @@ what it is today.
* alex_carnell * alex_carnell
* Alan Webb (IBM) * Alan Webb (IBM)
* Aleric * Aleric
* Alicia Raven
* Allen Kerensky * Allen Kerensky
* BigFootAg * BigFootAg
* BlueWall Slade * BlueWall Slade

View File

@ -174,7 +174,7 @@ namespace OpenSim.Groups
if (dict.ContainsKey("ServiceLocation") && dict["ServiceLocation"] != null) if (dict.ContainsKey("ServiceLocation") && dict["ServiceLocation"] != null)
grec.ServiceLocation = dict["ServiceLocation"].ToString(); grec.ServiceLocation = dict["ServiceLocation"].ToString();
else else
grec.GroupName = string.Empty; grec.ServiceLocation = string.Empty;
if (dict.ContainsKey("ShownInList") && dict["ShownInList"] != null) if (dict.ContainsKey("ShownInList") && dict["ShownInList"] != null)
grec.ShowInList = bool.Parse(dict["ShownInList"].ToString()); grec.ShowInList = bool.Parse(dict["ShownInList"].ToString());

View File

@ -325,6 +325,13 @@ namespace OpenSim.Groups
im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid; im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid;
} }
if ((im.binaryBucket == null) || (im.binaryBucket.Length == 0) || ((im.binaryBucket.Length == 1 && im.binaryBucket[0] == 0)))
{
ExtendedGroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), groupID, null);
if (groupInfo != null)
im.binaryBucket = Util.StringToBytes256(groupInfo.GroupName);
}
// Send to self first of all // Send to self first of all
im.toAgentID = im.fromAgentID; im.toAgentID = im.fromAgentID;
im.fromGroup = true; im.fromGroup = true;

View File

@ -1296,7 +1296,7 @@ namespace OpenSim.Groups
presence.Grouptitle = Title; presence.Grouptitle = Title;
if (! presence.IsChildAgent) if (! presence.IsChildAgent)
presence.SendAvatarDataToAllAgents(); presence.SendAvatarDataToAllClients();
} }
} }
} }

View File

@ -209,11 +209,13 @@ namespace OpenSim.Groups
string agentID = request["AgentID"].ToString(); string agentID = request["AgentID"].ToString();
string token = request["AccessToken"].ToString(); string token = request["AccessToken"].ToString();
m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token); if (!m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token))
NullResult(result, "Internal error");
else
result["RESULT"] = "true";
} }
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
result["RESULT"] = "true";
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result)); return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
} }

View File

@ -109,7 +109,7 @@ namespace OpenSim.Groups
string method = request["METHOD"].ToString(); string method = request["METHOD"].ToString();
request.Remove("METHOD"); request.Remove("METHOD");
m_log.DebugFormat("[Groups.Handler]: {0}", method); // m_log.DebugFormat("[Groups.Handler]: {0}", method);
switch (method) switch (method)
{ {
case "PUTGROUP": case "PUTGROUP":
@ -285,11 +285,13 @@ namespace OpenSim.Groups
string agentID = request["AgentID"].ToString(); string agentID = request["AgentID"].ToString();
string requestingAgentID = request["RequestingAgentID"].ToString(); string requestingAgentID = request["RequestingAgentID"].ToString();
m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID); if (!m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID))
NullResult(result, string.Format("Insufficient permissions.", agentID));
else
result["RESULT"] = "true";
} }
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
result["RESULT"] = "true";
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result)); return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
} }
@ -665,7 +667,11 @@ namespace OpenSim.Groups
GroupInviteInfo invite = m_GroupsService.GetAgentToGroupInvite(request["RequestingAgentID"].ToString(), GroupInviteInfo invite = m_GroupsService.GetAgentToGroupInvite(request["RequestingAgentID"].ToString(),
new UUID(request["InviteID"].ToString())); new UUID(request["InviteID"].ToString()));
if (invite != null)
result["RESULT"] = GroupsDataUtils.GroupInviteInfo(invite); result["RESULT"] = GroupsDataUtils.GroupInviteInfo(invite);
else
result["RESULT"] = "NULL";
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result)); return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
} }

View File

@ -393,13 +393,15 @@ namespace OpenSim.Groups
return true; return true;
} }
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID) public bool RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
{ {
// check perms // check perms
if (RequestingAgentID != AgentID && !HasPower(RequestingAgentID, GroupID, GroupPowers.Eject)) if (RequestingAgentID != AgentID && !HasPower(RequestingAgentID, GroupID, GroupPowers.Eject))
return; return false;
_RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID); _RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
return true;
} }
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID) public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)

View File

@ -131,19 +131,27 @@ namespace OpenSim.Groups
return true; return true;
} }
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, string token) public bool RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, string token)
{ {
// check the token // check the token
MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID); MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
if (membership != null) if (membership != null)
{ {
if (token != string.Empty && token.Equals(membership.Data["AccessToken"])) if (token != string.Empty && token.Equals(membership.Data["AccessToken"]))
RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID); {
else return RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
m_log.DebugFormat("[Groups.HGGroupsService]: access token {0} did not match stored one {1}", token, membership.Data["AccessToken"]);
} }
else else
{
m_log.DebugFormat("[Groups.HGGroupsService]: access token {0} did not match stored one {1}", token, membership.Data["AccessToken"]);
return false;
}
}
else
{
m_log.DebugFormat("[Groups.HGGroupsService]: membership not found for {0}", AgentID); m_log.DebugFormat("[Groups.HGGroupsService]: membership not found for {0}", AgentID);
return false;
}
} }
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string groupName, string token) public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string groupName, string token)

View File

@ -215,18 +215,7 @@ namespace OpenSim.OfflineIM
rootElement.AppendChild(result); rootElement.AppendChild(result);
return DocToBytes(doc); return Util.DocToBytes(doc);
}
private byte[] DocToBytes(XmlDocument doc)
{
MemoryStream ms = new MemoryStream();
XmlTextWriter xw = new XmlTextWriter(ms, null);
xw.Formatting = Formatting.Indented;
doc.WriteTo(xw);
xw.Flush();
return ms.ToArray();
} }
#endregion #endregion

View File

@ -32,6 +32,7 @@ using log4net;
using Mono.Addins; using Mono.Addins;
using Nini.Config; using Nini.Config;
using OpenSim; using OpenSim;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
@ -45,6 +46,12 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
LogManager.GetLogger( LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType); MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Controls whether we load modules from Mono.Addins.
/// </summary>
/// <remarks>For debug purposes. Defaults to true.</remarks>
public bool LoadModulesFromAddins { get; set; }
// Config access // Config access
private OpenSimBase m_openSim; private OpenSimBase m_openSim;
@ -61,6 +68,11 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
private List<ISharedRegionModule> m_sharedInstances = private List<ISharedRegionModule> m_sharedInstances =
new List<ISharedRegionModule>(); new List<ISharedRegionModule>();
public RegionModulesControllerPlugin()
{
LoadModulesFromAddins = true;
}
#region IApplicationPlugin implementation #region IApplicationPlugin implementation
public void Initialise (OpenSimBase openSim) public void Initialise (OpenSimBase openSim)
@ -69,6 +81,9 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
m_openSim.ApplicationRegistry.RegisterInterface<IRegionModulesController>(this); m_openSim.ApplicationRegistry.RegisterInterface<IRegionModulesController>(this);
m_log.DebugFormat("[REGIONMODULES]: Initializing..."); m_log.DebugFormat("[REGIONMODULES]: Initializing...");
if (!LoadModulesFromAddins)
return;
// Who we are // Who we are
string id = AddinManager.CurrentAddin.Id; string id = AddinManager.CurrentAddin.Id;
@ -88,40 +103,8 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
Dictionary<RuntimeAddin, IList<int>> loadedModules = new Dictionary<RuntimeAddin, IList<int>>(); Dictionary<RuntimeAddin, IList<int>> loadedModules = new Dictionary<RuntimeAddin, IList<int>>();
// Scan modules and load all that aren't disabled // Scan modules and load all that aren't disabled
foreach (TypeExtensionNode node in foreach (TypeExtensionNode node in AddinManager.GetExtensionNodes("/OpenSim/RegionModules"))
AddinManager.GetExtensionNodes("/OpenSim/RegionModules")) AddNode(node, modulesConfig, loadedModules);
{
IList<int> loadedModuleData;
if (!loadedModules.ContainsKey(node.Addin))
loadedModules.Add(node.Addin, new List<int> { 0, 0, 0 });
loadedModuleData = loadedModules[node.Addin];
if (node.Type.GetInterface(typeof(ISharedRegionModule).ToString()) != null)
{
if (CheckModuleEnabled(node, modulesConfig))
{
m_log.DebugFormat("[REGIONMODULES]: Found shared region module {0}, class {1}", node.Id, node.Type);
m_sharedModules.Add(node);
loadedModuleData[0]++;
}
}
else if (node.Type.GetInterface(typeof(INonSharedRegionModule).ToString()) != null)
{
if (CheckModuleEnabled(node, modulesConfig))
{
m_log.DebugFormat("[REGIONMODULES]: Found non-shared region module {0}, class {1}", node.Id, node.Type);
m_nonSharedModules.Add(node);
loadedModuleData[1]++;
}
}
else
{
m_log.WarnFormat("[REGIONMODULES]: Found unknown type of module {0}, class {1}", node.Id, node.Type);
loadedModuleData[2]++;
}
}
foreach (KeyValuePair<RuntimeAddin, IList<int>> loadedModuleData in loadedModules) foreach (KeyValuePair<RuntimeAddin, IList<int>> loadedModuleData in loadedModules)
{ {
@ -194,6 +177,41 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
#region IPlugin implementation #region IPlugin implementation
private void AddNode(
TypeExtensionNode node, IConfig modulesConfig, Dictionary<RuntimeAddin, IList<int>> loadedModules)
{
IList<int> loadedModuleData;
if (!loadedModules.ContainsKey(node.Addin))
loadedModules.Add(node.Addin, new List<int> { 0, 0, 0 });
loadedModuleData = loadedModules[node.Addin];
if (node.Type.GetInterface(typeof(ISharedRegionModule).ToString()) != null)
{
if (CheckModuleEnabled(node, modulesConfig))
{
m_log.DebugFormat("[REGIONMODULES]: Found shared region module {0}, class {1}", node.Id, node.Type);
m_sharedModules.Add(node);
loadedModuleData[0]++;
}
}
else if (node.Type.GetInterface(typeof(INonSharedRegionModule).ToString()) != null)
{
if (CheckModuleEnabled(node, modulesConfig))
{
m_log.DebugFormat("[REGIONMODULES]: Found non-shared region module {0}, class {1}", node.Id, node.Type);
m_nonSharedModules.Add(node);
loadedModuleData[1]++;
}
}
else
{
m_log.WarnFormat("[REGIONMODULES]: Found unknown type of module {0}, class {1}", node.Id, node.Type);
loadedModuleData[2]++;
}
}
// We don't do that here // We don't do that here
// //
public void Initialise () public void Initialise ()
@ -215,6 +233,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
m_sharedInstances[0].Close(); m_sharedInstances[0].Close();
m_sharedInstances.RemoveAt(0); m_sharedInstances.RemoveAt(0);
} }
m_sharedModules.Clear(); m_sharedModules.Clear();
m_nonSharedModules.Clear(); m_nonSharedModules.Clear();
} }

View File

@ -162,6 +162,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController
availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList); availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList);
availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload); availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload);
// Land management
availableMethods["admin_reset_land"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcResetLand);
// Either enable full remote functionality or just selected features // Either enable full remote functionality or just selected features
string enabledMethods = m_config.GetString("enabled_methods", "all"); string enabledMethods = m_config.GetString("enabled_methods", "all");
@ -2063,6 +2066,56 @@ namespace OpenSim.ApplicationPlugins.RemoteController
responseData["success"] = true; responseData["success"] = true;
} }
private void XmlRpcResetLand(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{
Hashtable requestData = (Hashtable)request.Params[0];
Hashtable responseData = (Hashtable)response.Value;
string musicURL = string.Empty;
UUID groupID = UUID.Zero;
uint flags = 0;
bool set_group = false, set_music = false, set_flags = false;
if (requestData.Contains("group") && requestData["group"] != null)
set_group = UUID.TryParse(requestData["group"].ToString(), out groupID);
if (requestData.Contains("music") && requestData["music"] != null)
{
musicURL = requestData["music"].ToString();
set_music = true;
}
if (requestData.Contains("flags") && requestData["flags"] != null)
set_flags = UInt32.TryParse(requestData["flags"].ToString(), out flags);
m_log.InfoFormat("[RADMIN]: Received Reset Land Request group={0} musicURL={1} flags={2}",
(set_group ? groupID.ToString() : "unchanged"),
(set_music ? musicURL : "unchanged"),
(set_flags ? flags.ToString() : "unchanged"));
m_application.SceneManager.ForEachScene(delegate(Scene s)
{
List<ILandObject> parcels = s.LandChannel.AllParcels();
foreach (ILandObject p in parcels)
{
if (set_music)
p.LandData.MusicURL = musicURL;
if (set_group)
p.LandData.GroupID = groupID;
if (set_flags)
p.LandData.Flags = flags;
s.LandChannel.UpdateLandObject(p.LandData.LocalID, p.LandData);
}
}
);
responseData["success"] = true;
m_log.Info("[RADMIN]: Reset Land Request complete");
}
/// <summary> /// <summary>
/// Parse a float with the given parameter name from a request data hash table. /// Parse a float with the given parameter name from a request data hash table.
/// </summary> /// </summary>

View File

@ -52,7 +52,7 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
// Overkill - we only really need the asset service, not a whole scene. // Overkill - we only really need the asset service, not a whole scene.
Scene scene = new SceneHelpers().SetupScene(); Scene scene = new SceneHelpers().SetupScene();
GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService, "TestGetTexture", null, null); GetTextureHandler handler = new GetTextureHandler("/gettexture", scene.AssetService, "TestGetTexture", null, null);
TestOSHttpRequest req = new TestOSHttpRequest(); TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse(); TestOSHttpResponse resp = new TestOSHttpResponse();
req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012"); req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");

View File

@ -68,7 +68,10 @@ namespace OpenSim.Framework.Capabilities
/// <returns></returns> /// <returns></returns>
public static object LLSDDeserialize(byte[] b) public static object LLSDDeserialize(byte[] b)
{ {
return LLSDDeserialize(new MemoryStream(b, false)); using (MemoryStream ms = new MemoryStream(b, false))
{
return LLSDDeserialize(ms);
}
} }
/// <summary> /// <summary>
@ -78,7 +81,8 @@ namespace OpenSim.Framework.Capabilities
/// <returns></returns> /// <returns></returns>
public static object LLSDDeserialize(Stream st) public static object LLSDDeserialize(Stream st)
{ {
XmlTextReader reader = new XmlTextReader(st); using (XmlTextReader reader = new XmlTextReader(st))
{
reader.Read(); reader.Read();
SkipWS(reader); SkipWS(reader);
@ -94,6 +98,7 @@ namespace OpenSim.Framework.Capabilities
return ret; return ret;
} }
}
/// <summary> /// <summary>
/// ///

View File

@ -29,7 +29,7 @@ using System.Collections.Generic;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
namespace OpenSim.Region.Framework.Interfaces namespace OpenSim.Data
{ {
public interface IEstateDataStore public interface IEstateDataStore
{ {

View File

@ -52,12 +52,12 @@ namespace OpenSim.Data
public int sizeY; public int sizeY;
/// <summary> /// <summary>
/// Return the x-coordinate of this region. /// Return the x-coordinate of this region in region units.
/// </summary> /// </summary>
public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } } public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } }
/// <summary> /// <summary>
/// Return the y-coordinate of this region. /// Return the y-coordinate of this region in region units.
/// </summary> /// </summary>
public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } } public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } }

View File

@ -45,7 +45,6 @@ namespace OpenSim.Data.MySQL
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string m_connectionString; private string m_connectionString;
private object m_dbLock = new object();
protected virtual Assembly Assembly protected virtual Assembly Assembly
{ {
@ -107,8 +106,7 @@ namespace OpenSim.Data.MySQL
override public AssetBase GetAsset(UUID assetID) override public AssetBase GetAsset(UUID assetID)
{ {
AssetBase asset = null; AssetBase asset = null;
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
@ -147,7 +145,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
return asset; return asset;
} }
@ -157,8 +155,6 @@ namespace OpenSim.Data.MySQL
/// <param name="asset">Asset UUID to create</param> /// <param name="asset">Asset UUID to create</param>
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks> /// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
override public void StoreAsset(AssetBase asset) override public void StoreAsset(AssetBase asset)
{
lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -219,11 +215,8 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
private void UpdateAccessTime(AssetBase asset) private void UpdateAccessTime(AssetBase asset)
{
lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -254,7 +247,6 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
/// <summary> /// <summary>
/// Check if the assets exist in the database. /// Check if the assets exist in the database.
@ -271,8 +263,6 @@ namespace OpenSim.Data.MySQL
string ids = "'" + string.Join("','", uuids) + "'"; string ids = "'" + string.Join("','", uuids) + "'";
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids); string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
@ -288,7 +278,6 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
bool[] results = new bool[uuids.Length]; bool[] results = new bool[uuids.Length];
for (int i = 0; i < uuids.Length; i++) for (int i = 0; i < uuids.Length; i++)
@ -309,8 +298,6 @@ namespace OpenSim.Data.MySQL
{ {
List<AssetMetadata> retList = new List<AssetMetadata>(count); List<AssetMetadata> retList = new List<AssetMetadata>(count);
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
@ -355,14 +342,11 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
return retList; return retList;
} }
public override bool Delete(string id) public override bool Delete(string id)
{
lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -374,7 +358,6 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
} }
}
return true; return true;
} }

View File

@ -145,7 +145,11 @@ namespace OpenSim.Data.MySQL
cmd.CommandText = sql; cmd.CommandText = sql;
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
return DoLoad(cmd, regionID, create); EstateSettings e = DoLoad(cmd, regionID, create);
if (!create && e.EstateID == 0) // Not found
return null;
return e;
} }
} }
@ -427,7 +431,10 @@ namespace OpenSim.Data.MySQL
cmd.CommandText = sql; cmd.CommandText = sql;
cmd.Parameters.AddWithValue("?EstateID", estateID); cmd.Parameters.AddWithValue("?EstateID", estateID);
return DoLoad(cmd, UUID.Zero, false); EstateSettings e = DoLoad(cmd, UUID.Zero, false);
if (e.EstateID != estateID)
return null;
return e;
} }
} }

View File

@ -45,21 +45,13 @@ namespace OpenSim.Data.MySQL
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
protected string m_connectionString; protected string m_connectionString;
protected object m_dbLock = new object();
protected MySqlFramework(string connectionString) protected MySqlFramework(string connectionString)
{ {
m_connectionString = connectionString; m_connectionString = connectionString;
} }
//////////////////////////////////////////////////////////////
//
// All non queries are funneled through one connection
// to increase performance a little
//
protected int ExecuteNonQuery(MySqlCommand cmd) protected int ExecuteNonQuery(MySqlCommand cmd)
{
lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -78,5 +70,4 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
} }

View File

@ -51,6 +51,15 @@ namespace OpenSim.Data.MySQL
private static string LogHeader = "[REGION DB MYSQL]"; private static string LogHeader = "[REGION DB MYSQL]";
private string m_connectionString; private string m_connectionString;
/// <summary>
/// This lock was being used to serialize database operations when the connection was shared, but this has
/// been unnecessary for a long time after we switched to using MySQL's underlying connection pooling instead.
/// FIXME: However, the locks remain in many places since they are effectively providing a level of
/// transactionality. This should be replaced by more efficient database transactions which would not require
/// unrelated operations to block each other or unrelated operations on the same tables from blocking each
/// other.
/// </summary>
private object m_dbLock = new object(); private object m_dbLock = new object();
protected virtual Assembly Assembly protected virtual Assembly Assembly
@ -738,8 +747,6 @@ namespace OpenSim.Data.MySQL
RegionLightShareData nWP = new RegionLightShareData(); RegionLightShareData nWP = new RegionLightShareData();
nWP.OnSave += StoreRegionWindlightSettings; nWP.OnSave += StoreRegionWindlightSettings;
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
@ -829,7 +836,6 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
return nWP; return nWP;
} }
@ -875,8 +881,6 @@ namespace OpenSim.Data.MySQL
} }
public void StoreRegionWindlightSettings(RegionLightShareData wl) public void StoreRegionWindlightSettings(RegionLightShareData wl)
{
lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -978,11 +982,8 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
public void RemoveRegionWindlightSettings(UUID regionID) public void RemoveRegionWindlightSettings(UUID regionID)
{
lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -996,12 +997,9 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
#region RegionEnvironmentSettings #region RegionEnvironmentSettings
public string LoadRegionEnvironmentSettings(UUID regionUUID) public string LoadRegionEnvironmentSettings(UUID regionUUID)
{
lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -1027,11 +1025,8 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
{
lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -1048,11 +1043,8 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
public void RemoveRegionEnvironmentSettings(UUID regionUUID) public void RemoveRegionEnvironmentSettings(UUID regionUUID)
{
lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -1066,12 +1058,9 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
#endregion #endregion
public void StoreRegionSettings(RegionSettings rs) public void StoreRegionSettings(RegionSettings rs)
{
lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -1121,7 +1110,7 @@ namespace OpenSim.Data.MySQL
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }
} }
}
SaveSpawnPoints(rs); SaveSpawnPoints(rs);
} }
@ -2042,8 +2031,6 @@ namespace OpenSim.Data.MySQL
} }
public void SaveExtra(UUID regionID, string name, string val) public void SaveExtra(UUID regionID, string name, string val)
{
lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -2060,11 +2047,8 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
public void RemoveExtra(UUID regionID, string name) public void RemoveExtra(UUID regionID, string name)
{
lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -2080,14 +2064,11 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
public Dictionary<string, string> GetExtra(UUID regionID) public Dictionary<string, string> GetExtra(UUID regionID)
{ {
Dictionary<string, string> ret = new Dictionary<string, string>(); Dictionary<string, string> ret = new Dictionary<string, string>();
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
@ -2105,7 +2086,6 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
return ret; return ret;
} }

View File

@ -47,11 +47,6 @@ namespace OpenSim.Data.MySQL
get; set; get; set;
} }
protected object Lock
{
get; set;
}
protected virtual Assembly Assembly protected virtual Assembly Assembly
{ {
get { return GetType().Assembly; } get { return GetType().Assembly; }
@ -250,7 +245,7 @@ namespace OpenSim.Data.MySQL
string query = string.Empty; string query = string.Empty;
query += "DELETE FROM classifieds WHERE "; query += "DELETE FROM classifieds WHERE ";
query += "classifieduuid = ?ClasifiedId"; query += "classifieduuid = ?recordId";
try try
{ {
@ -260,15 +255,11 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
{ {
cmd.Parameters.AddWithValue("?ClassifiedId", recordId.ToString()); cmd.Parameters.AddWithValue("?recordId", recordId.ToString());
lock(Lock)
{
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
} }
} }
}
catch (Exception e) catch (Exception e)
{ {
m_log.DebugFormat("[PROFILES_DATA]" + m_log.DebugFormat("[PROFILES_DATA]" +
@ -1030,8 +1021,6 @@ namespace OpenSim.Data.MySQL
put.Parameters.AddWithValue("?DataKey", props.DataKey.ToString()); put.Parameters.AddWithValue("?DataKey", props.DataKey.ToString());
put.Parameters.AddWithValue("?DataVal", props.DataVal.ToString()); put.Parameters.AddWithValue("?DataVal", props.DataVal.ToString());
lock(Lock)
{
put.ExecuteNonQuery(); put.ExecuteNonQuery();
} }
} }
@ -1039,7 +1028,6 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
catch (Exception e) catch (Exception e)
{ {
m_log.DebugFormat("[PROFILES_DATA]" + m_log.DebugFormat("[PROFILES_DATA]" +
@ -1069,17 +1057,14 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
{ {
cmd.Parameters.AddWithValue("?UserId", props.UserId.ToString()); cmd.Parameters.AddWithValue("?UserId", props.UserId.ToString());
cmd.Parameters.AddWithValue("?TagId", props.TagId.ToString ()); cmd.Parameters.AddWithValue("?TagId", props.TagId.ToString());
cmd.Parameters.AddWithValue("?DataKey", props.DataKey.ToString ()); cmd.Parameters.AddWithValue("?DataKey", props.DataKey.ToString());
cmd.Parameters.AddWithValue("?DataVal", props.DataKey.ToString ()); cmd.Parameters.AddWithValue("?DataVal", props.DataKey.ToString());
lock(Lock)
{
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
} }
} }
}
catch (Exception e) catch (Exception e)
{ {
m_log.DebugFormat("[PROFILES_DATA]" + m_log.DebugFormat("[PROFILES_DATA]" +
@ -1091,4 +1076,3 @@ namespace OpenSim.Data.MySQL
#endregion Integration #endregion Integration
} }
} }

View File

@ -57,7 +57,6 @@ namespace OpenSim.Data.MySQL
private bool m_enableCompression = false; private bool m_enableCompression = false;
private string m_connectionString; private string m_connectionString;
private object m_dbLock = new object();
/// <summary> /// <summary>
/// We can reuse this for all hashing since all methods are single-threaded through m_dbBLock /// We can reuse this for all hashing since all methods are single-threaded through m_dbBLock
@ -131,8 +130,7 @@ namespace OpenSim.Data.MySQL
// m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID); // m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID);
AssetBase asset = null; AssetBase asset = null;
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
@ -168,12 +166,12 @@ namespace OpenSim.Data.MySQL
{ {
MemoryStream outputStream = new MemoryStream(); MemoryStream outputStream = new MemoryStream();
WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue); WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue);
// int compressedLength = asset.Data.Length; // int compressedLength = asset.Data.Length;
asset.Data = outputStream.ToArray(); asset.Data = outputStream.ToArray();
// m_log.DebugFormat( // m_log.DebugFormat(
// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}", // "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}",
// asset.ID, asset.Name, asset.Data.Length, compressedLength); // asset.ID, asset.Name, asset.Data.Length, compressedLength);
} }
} }
@ -187,7 +185,6 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
return asset; return asset;
} }
@ -201,8 +198,6 @@ namespace OpenSim.Data.MySQL
{ {
// m_log.DebugFormat("[XASSETS DB]: Storing asset {0} {1}", asset.Name, asset.ID); // m_log.DebugFormat("[XASSETS DB]: Storing asset {0} {1}", asset.Name, asset.ID);
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
@ -233,7 +228,7 @@ namespace OpenSim.Data.MySQL
using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress, false)) using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress, false))
{ {
// Console.WriteLine(WebUtil.CopyTo(new MemoryStream(asset.Data), compressionStream, int.MaxValue)); // 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. // We have to close the compression stream in order to make sure it writes everything out to the underlying memory output stream.
compressionStream.Close(); compressionStream.Close();
byte[] compressedData = outputStream.ToArray(); byte[] compressedData = outputStream.ToArray();
@ -310,7 +305,6 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
/// <summary> /// <summary>
/// Updates the access time of the asset if it was accessed above a given threshhold amount of time. /// Updates the access time of the asset if it was accessed above a given threshhold amount of time.
@ -328,8 +322,6 @@ namespace OpenSim.Data.MySQL
if ((now - Utils.UnixTimeToDateTime(accessTime)).TotalDays < DaysBetweenAccessTimeUpdates) if ((now - Utils.UnixTimeToDateTime(accessTime)).TotalDays < DaysBetweenAccessTimeUpdates)
return; return;
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
@ -354,7 +346,6 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
/// <summary> /// <summary>
/// We assume we already have the m_dbLock. /// We assume we already have the m_dbLock.
@ -411,8 +402,6 @@ namespace OpenSim.Data.MySQL
string ids = "'" + string.Join("','", uuids) + "'"; string ids = "'" + string.Join("','", uuids) + "'";
string sql = string.Format("SELECT ID FROM assets WHERE ID IN ({0})", ids); string sql = string.Format("SELECT ID FROM assets WHERE ID IN ({0})", ids);
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
@ -428,7 +417,6 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
bool[] results = new bool[uuids.Length]; bool[] results = new bool[uuids.Length];
for (int i = 0; i < uuids.Length; i++) for (int i = 0; i < uuids.Length; i++)
@ -449,8 +437,6 @@ namespace OpenSim.Data.MySQL
{ {
List<AssetMetadata> retList = new List<AssetMetadata>(count); List<AssetMetadata> retList = new List<AssetMetadata>(count);
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
@ -487,7 +473,6 @@ namespace OpenSim.Data.MySQL
m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString()); m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
} }
} }
}
return retList; return retList;
} }
@ -496,8 +481,6 @@ namespace OpenSim.Data.MySQL
{ {
// m_log.DebugFormat("[XASSETS DB]: Deleting asset {0}", id); // m_log.DebugFormat("[XASSETS DB]: Deleting asset {0}", id);
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
@ -511,7 +494,6 @@ namespace OpenSim.Data.MySQL
// TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we // TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we
// keep a reference count (?) // keep a reference count (?)
} }
}
return true; return true;
} }

View File

@ -239,7 +239,7 @@ namespace OpenSim.Data.SQLite
if (inventoryRow == null) if (inventoryRow == null)
{ {
if (! add) if (! add)
m_log.ErrorFormat("Interface Misuse: Attempting to Update non-existant inventory folder: {0}", folder.ID); m_log.ErrorFormat("Interface Misuse: Attempting to Update non-existent inventory folder: {0}", folder.ID);
inventoryRow = inventoryFolderTable.NewRow(); inventoryRow = inventoryFolderTable.NewRow();
fillFolderRow(inventoryRow, folder); fillFolderRow(inventoryRow, folder);
@ -298,7 +298,7 @@ namespace OpenSim.Data.SQLite
if (inventoryRow == null) if (inventoryRow == null)
{ {
if (!add) if (!add)
m_log.ErrorFormat("[INVENTORY DB]: Interface Misuse: Attempting to Update non-existant inventory item: {0}", item.ID); m_log.ErrorFormat("[INVENTORY DB]: Interface Misuse: Attempting to Update non-existent inventory item: {0}", item.ID);
inventoryRow = inventoryItemTable.NewRow(); inventoryRow = inventoryItemTable.NewRow();
fillItemRow(inventoryRow, item); fillItemRow(inventoryRow, item);

View File

@ -520,6 +520,12 @@ namespace OpenSim.Framework
if (!m_attachments.ContainsKey(attach.AttachPoint)) if (!m_attachments.ContainsKey(attach.AttachPoint))
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>(); m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
foreach (AvatarAttachment prev in m_attachments[attach.AttachPoint])
{
if (prev.ItemID == attach.ItemID)
return;
}
m_attachments[attach.AttachPoint].Add(attach); m_attachments[attach.AttachPoint].Add(attach);
} }
} }

View File

@ -54,6 +54,7 @@ namespace OpenSim.Framework
public int assetThrottle; public int assetThrottle;
public int textureThrottle; public int textureThrottle;
public int totalThrottle; public int totalThrottle;
public int maxThrottle;
public Dictionary<string, int> SyncRequests = new Dictionary<string,int>(); public Dictionary<string, int> SyncRequests = new Dictionary<string,int>();
public Dictionary<string, int> AsyncRequests = new Dictionary<string,int>(); public Dictionary<string, int> AsyncRequests = new Dictionary<string,int>();

View File

@ -56,7 +56,7 @@ namespace OpenSim.Framework.Communications
/// other threads to execute, while it waits for a response from the web-service. RestClient itself can be /// other threads to execute, while it waits for a response from the web-service. RestClient itself can be
/// invoked by the caller in either synchronous mode or asynchronous modes. /// invoked by the caller in either synchronous mode or asynchronous modes.
/// </remarks> /// </remarks>
public class RestClient public class RestClient : IDisposable
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -148,6 +148,33 @@ namespace OpenSim.Framework.Communications
#endregion constructors #endregion constructors
#region Dispose
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
_resource.Dispose();
}
disposed = true;
}
#endregion Dispose
/// <summary> /// <summary>
/// Add a path element to the query, e.g. assets /// Add a path element to the query, e.g. assets
/// </summary> /// </summary>
@ -296,6 +323,14 @@ namespace OpenSim.Framework.Communications
#endregion Async communications with server #endregion Async communications with server
/// <summary>
/// Perform a synchronous request
/// </summary>
public Stream Request()
{
return Request(null);
}
/// <summary> /// <summary>
/// Perform a synchronous request /// Perform a synchronous request
/// </summary> /// </summary>
@ -312,6 +347,10 @@ namespace OpenSim.Framework.Communications
if (auth != null) if (auth != null)
auth.AddAuthorization(_request.Headers); auth.AddAuthorization(_request.Headers);
int reqnum = WebUtil.RequestNumber++;
if (WebUtil.DebugLevel >= 3)
m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} REST {1} to {2}", reqnum, _request.Method, _request.RequestUri);
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request); // IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
try try
{ {
@ -358,6 +397,9 @@ namespace OpenSim.Framework.Communications
_resource.Seek(0, SeekOrigin.Begin); _resource.Seek(0, SeekOrigin.Begin);
} }
if (WebUtil.DebugLevel >= 5)
WebUtil.LogResponseDetail(reqnum, _resource);
return _resource; return _resource;
} }
} }
@ -374,16 +416,18 @@ namespace OpenSim.Framework.Communications
if (auth != null) if (auth != null)
auth.AddAuthorization(_request.Headers); auth.AddAuthorization(_request.Headers);
m_log.InfoFormat("[REST]: Request Length {0}", _request.ContentLength);
m_log.InfoFormat("[REST]: Sending Web Request {0}", buildUri());
src.Seek(0, SeekOrigin.Begin); src.Seek(0, SeekOrigin.Begin);
m_log.Info("[REST]: Seek is ok");
int reqnum = WebUtil.RequestNumber++;
if (WebUtil.DebugLevel >= 3)
m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} REST {1} to {2}", reqnum, _request.Method, _request.RequestUri);
if (WebUtil.DebugLevel >= 5)
WebUtil.LogOutgoingDetail(string.Format("SEND {0}: ", reqnum), src);
Stream dst = _request.GetRequestStream(); Stream dst = _request.GetRequestStream();
m_log.Info("[REST]: GetRequestStream is ok");
byte[] buf = new byte[1024]; byte[] buf = new byte[1024];
int length = src.Read(buf, 0, 1024); int length = src.Read(buf, 0, 1024);
m_log.Info("[REST]: First Read is ok");
while (length > 0) while (length > 0)
{ {
dst.Write(buf, 0, length); dst.Write(buf, 0, length);
@ -398,14 +442,29 @@ namespace OpenSim.Framework.Communications
{ {
m_log.WarnFormat("[REST]: Request {0} {1} failed with status {2} and message {3}", m_log.WarnFormat("[REST]: Request {0} {1} failed with status {2} and message {3}",
RequestMethod, _request.RequestUri, e.Status, e.Message); RequestMethod, _request.RequestUri, e.Status, e.Message);
return null;
} }
catch (Exception e) catch (Exception e)
{ {
m_log.WarnFormat( m_log.WarnFormat(
"[REST]: Request {0} {1} failed with exception {2} {3}", "[REST]: Request {0} {1} failed with exception {2} {3}",
RequestMethod, _request.RequestUri, e.Message, e.StackTrace); RequestMethod, _request.RequestUri, e.Message, e.StackTrace);
return null;
} }
if (WebUtil.DebugLevel >= 5)
{
using (Stream responseStream = _response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
string responseStr = reader.ReadToEnd();
WebUtil.LogResponseDetail(reqnum, responseStr);
}
}
}
_response.Close();
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request); // IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);

View File

@ -156,7 +156,7 @@ namespace OpenSim.Framework.Console
} }
/// <summary> /// <summary>
/// Convert a console integer to an int, automatically complaining if a console is given. /// Convert a console input to a bool, automatically complaining if a console is given.
/// </summary> /// </summary>
/// <param name='console'>Can be null if no console is available.</param> /// <param name='console'>Can be null if no console is available.</param>
/// <param name='rawConsoleVector'>/param> /// <param name='rawConsoleVector'>/param>
@ -176,7 +176,7 @@ namespace OpenSim.Framework.Console
} }
/// <summary> /// <summary>
/// Convert a console integer to an int, automatically complaining if a console is given. /// Convert a console input to an int, automatically complaining if a console is given.
/// </summary> /// </summary>
/// <param name='console'>Can be null if no console is available.</param> /// <param name='console'>Can be null if no console is available.</param>
/// <param name='rawConsoleInt'>/param> /// <param name='rawConsoleInt'>/param>
@ -195,6 +195,46 @@ namespace OpenSim.Framework.Console
return true; return true;
} }
/// <summary>
/// Convert a console input to a float, automatically complaining if a console is given.
/// </summary>
/// <param name='console'>Can be null if no console is available.</param>
/// <param name='rawConsoleInput'>/param>
/// <param name='i'></param>
/// <returns></returns>
public static bool TryParseConsoleFloat(ICommandConsole console, string rawConsoleInput, out float i)
{
if (!float.TryParse(rawConsoleInput, out i))
{
if (console != null)
console.OutputFormat("ERROR: {0} is not a valid float", rawConsoleInput);
return false;
}
return true;
}
/// <summary>
/// Convert a console input to a double, automatically complaining if a console is given.
/// </summary>
/// <param name='console'>Can be null if no console is available.</param>
/// <param name='rawConsoleInput'>/param>
/// <param name='i'></param>
/// <returns></returns>
public static bool TryParseConsoleDouble(ICommandConsole console, string rawConsoleInput, out double i)
{
if (!double.TryParse(rawConsoleInput, out i))
{
if (console != null)
console.OutputFormat("ERROR: {0} is not a valid double", rawConsoleInput);
return false;
}
return true;
}
/// <summary> /// <summary>
/// Convert a console integer to a natural int, automatically complaining if a console is given. /// Convert a console integer to a natural int, automatically complaining if a console is given.
/// </summary> /// </summary>

View File

@ -28,6 +28,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection;
using OpenMetaverse; using OpenMetaverse;
namespace OpenSim.Framework namespace OpenSim.Framework
@ -411,5 +412,23 @@ namespace OpenSim.Framework
{ {
return l_EstateGroups.Contains(groupID); return l_EstateGroups.Contains(groupID);
} }
public Dictionary<string, object> ToMap()
{
Dictionary<string, object> map = new Dictionary<string, object>();
PropertyInfo[] properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo p in properties)
map[p.Name] = p.GetValue(this, null);
return map;
}
public EstateSettings(Dictionary<string, object> map)
{
PropertyInfo[] properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo p in properties)
p.SetValue(this, map[p.Name], null);
}
} }
} }

View File

@ -65,13 +65,18 @@ namespace OpenSim.Framework
/// </remarks> /// </remarks>
AvatarAppearance Appearance { get; set; } AvatarAppearance Appearance { get; set; }
/// <summary>
/// Set if initial data about the scene (avatars, objects) has been sent to the client.
/// </summary>
bool SentInitialDataToClient { get; }
/// <summary> /// <summary>
/// Send initial scene data to the client controlling this agent /// Send initial scene data to the client controlling this agent
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This includes scene object data and the appearance data of other avatars. /// This includes scene object data and the appearance data of other avatars.
/// </remarks> /// </remarks>
void SendInitialDataToMe(); void SendInitialDataToClient();
/// <summary> /// <summary>
/// Direction in which the scene presence is looking. /// Direction in which the scene presence is looking.

View File

@ -141,19 +141,19 @@ namespace OpenSim.Framework.Monitoring
processorPercentPerfCounter = new PerfCounterControl(tempPC); processorPercentPerfCounter = new PerfCounterControl(tempPC);
// A long time bug in mono is that CPU percent is reported as CPU percent idle. Windows reports CPU percent busy. // A long time bug in mono is that CPU percent is reported as CPU percent idle. Windows reports CPU percent busy.
tempStat = new Stat(tempName, tempName, "", "percent", CategoryServer, ContainerProcessor, tempStat = new Stat(tempName, tempName, "", "percent", CategoryServer, ContainerProcessor,
StatType.Pull, (s) => { GetNextValue(s, processorPercentPerfCounter, Util.IsWindows() ? 1 : -1); }, StatType.Pull, (s) => { GetNextValue(s, processorPercentPerfCounter); },
StatVerbosity.Info); StatVerbosity.Info);
StatsManager.RegisterStat(tempStat); StatsManager.RegisterStat(tempStat);
RegisteredStats.Add(tempName, tempStat); RegisteredStats.Add(tempName, tempStat);
MakeStat("TotalProcessorTime", null, "sec", ContainerProcessor, MakeStat("TotalProcessorTime", null, "sec", ContainerProcessor,
(s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; }); (s) => { s.Value = Math.Round(Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds, 3); });
MakeStat("UserProcessorTime", null, "sec", ContainerProcessor, MakeStat("UserProcessorTime", null, "sec", ContainerProcessor,
(s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; }); (s) => { s.Value = Math.Round(Process.GetCurrentProcess().UserProcessorTime.TotalSeconds, 3); });
MakeStat("PrivilegedProcessorTime", null, "sec", ContainerProcessor, MakeStat("PrivilegedProcessorTime", null, "sec", ContainerProcessor,
(s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; }); (s) => { s.Value = Math.Round(Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds, 3); });
MakeStat("Threads", null, "threads", ContainerProcessor, MakeStat("Threads", null, "threads", ContainerProcessor,
(s) => { s.Value = Process.GetCurrentProcess().Threads.Count; }); (s) => { s.Value = Process.GetCurrentProcess().Threads.Count; });
@ -253,11 +253,8 @@ namespace OpenSim.Framework.Monitoring
// "How to get the CPU Usage in C#": http://stackoverflow.com/questions/278071/how-to-get-the-cpu-usage-in-c // "How to get the CPU Usage in C#": http://stackoverflow.com/questions/278071/how-to-get-the-cpu-usage-in-c
// "Mono Performance Counters": http://www.mono-project.com/Mono_Performance_Counters // "Mono Performance Counters": http://www.mono-project.com/Mono_Performance_Counters
private delegate double PerfCounterNextValue(); private delegate double PerfCounterNextValue();
private void GetNextValue(Stat stat, PerfCounterControl perfControl) private void GetNextValue(Stat stat, PerfCounterControl perfControl)
{
GetNextValue(stat, perfControl, 1.0);
}
private void GetNextValue(Stat stat, PerfCounterControl perfControl, double factor)
{ {
if (Util.EnvironmentTickCountSubtract(perfControl.lastFetch) > performanceCounterSampleInterval) if (Util.EnvironmentTickCountSubtract(perfControl.lastFetch) > performanceCounterSampleInterval)
{ {
@ -265,16 +262,13 @@ namespace OpenSim.Framework.Monitoring
{ {
try try
{ {
// Kludge for factor to run double duty. If -1, subtract the value from one stat.Value = Math.Round(perfControl.perfCounter.NextValue(), 3);
if (factor == -1)
stat.Value = 1 - perfControl.perfCounter.NextValue();
else
stat.Value = perfControl.perfCounter.NextValue() / factor;
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("{0} Exception on NextValue fetching {1}: {2}", LogHeader, stat.Name, e); m_log.ErrorFormat("{0} Exception on NextValue fetching {1}: {2}", LogHeader, stat.Name, e);
} }
perfControl.lastFetch = Util.EnvironmentTickCount(); perfControl.lastFetch = Util.EnvironmentTickCount();
} }
} }

View File

@ -70,18 +70,18 @@ namespace OpenSim.Framework.Monitoring
{ {
ICommandConsole con = MainConsole.Instance; ICommandConsole con = MainConsole.Instance;
if (cmd.Length != 4) if (cmd.Length != 3)
{ {
con.Output("Usage: debug stats record start|stop"); con.Output("Usage: stats record start|stop");
return; return;
} }
if (cmd[3] == "start") if (cmd[2] == "start")
{ {
Start(); Start();
con.OutputFormat("Now recording all stats to file every {0}ms", m_statsLogIntervalMs); con.OutputFormat("Now recording all stats to file every {0}ms", m_statsLogIntervalMs);
} }
else if (cmd[3] == "stop") else if (cmd[2] == "stop")
{ {
Stop(); Stop();
con.Output("Stopped recording stats to file."); con.Output("Stopped recording stats to file.");

View File

@ -101,7 +101,6 @@ namespace OpenSim.Framework
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[REGION INFO]"; private static readonly string LogHeader = "[REGION INFO]";
public bool commFailTF = false;
public string RegionFile = String.Empty; public string RegionFile = String.Empty;
public bool isSandbox = false; public bool isSandbox = false;
public bool Persistent = true; public bool Persistent = true;
@ -147,8 +146,29 @@ namespace OpenSim.Framework
public uint WorldLocX = 0; public uint WorldLocX = 0;
public uint WorldLocY = 0; public uint WorldLocY = 0;
public uint WorldLocZ = 0; public uint WorldLocZ = 0;
/// <summary>
/// X dimension of the region.
/// </summary>
/// <remarks>
/// If this is a varregion then the default size set here will be replaced when we load the region config.
/// </remarks>
public uint RegionSizeX = Constants.RegionSize; public uint RegionSizeX = Constants.RegionSize;
/// <summary>
/// X dimension of the region.
/// </summary>
/// <remarks>
/// If this is a varregion then the default size set here will be replaced when we load the region config.
/// </remarks>
public uint RegionSizeY = Constants.RegionSize; public uint RegionSizeY = Constants.RegionSize;
/// <summary>
/// Z dimension of the region.
/// </summary>
/// <remarks>
/// XXX: Unknown if this accounts for regions with negative Z.
/// </remarks>
public uint RegionSizeZ = Constants.RegionHeight; public uint RegionSizeZ = Constants.RegionHeight;
private Dictionary<String, String> m_extraSettings = new Dictionary<string, string>(); private Dictionary<String, String> m_extraSettings = new Dictionary<string, string>();
@ -860,11 +880,6 @@ namespace OpenSim.Framework
config.Set("MaptileStaticFile", MaptileStaticFile); config.Set("MaptileStaticFile", MaptileStaticFile);
} }
public bool ignoreIncomingConfiguration(string configuration_key, object configuration_result)
{
return true;
}
public void SaveRegionToFile(string description, string filename) public void SaveRegionToFile(string description, string filename)
{ {
if (filename.ToLower().EndsWith(".ini")) if (filename.ToLower().EndsWith(".ini"))

View File

@ -51,7 +51,7 @@ namespace OpenSim.Framework.Serialization.External
/// <param name="xtr"></param> /// <param name="xtr"></param>
/// <returns>true on successful, false if there were any processing failures</returns> /// <returns>true on successful, false if there were any processing failures</returns>
public static bool ExecuteReadProcessors<NodeType>( public static bool ExecuteReadProcessors<NodeType>(
NodeType nodeToFill, Dictionary<string, Action<NodeType, XmlTextReader>> processors, XmlTextReader xtr) NodeType nodeToFill, Dictionary<string, Action<NodeType, XmlReader>> processors, XmlReader xtr)
{ {
return ExecuteReadProcessors( return ExecuteReadProcessors(
nodeToFill, nodeToFill,
@ -75,8 +75,8 @@ namespace OpenSim.Framework.Serialization.External
/// <returns>true on successful, false if there were any processing failures</returns> /// <returns>true on successful, false if there were any processing failures</returns>
public static bool ExecuteReadProcessors<NodeType>( public static bool ExecuteReadProcessors<NodeType>(
NodeType nodeToFill, NodeType nodeToFill,
Dictionary<string, Action<NodeType, XmlTextReader>> processors, Dictionary<string, Action<NodeType, XmlReader>> processors,
XmlTextReader xtr, XmlReader xtr,
Action<NodeType, string, Exception> parseExceptionAction) Action<NodeType, string, Exception> parseExceptionAction)
{ {
bool errors = false; bool errors = false;
@ -88,7 +88,7 @@ namespace OpenSim.Framework.Serialization.External
// m_log.DebugFormat("[ExternalRepresentationUtils]: Processing: {0}", nodeName); // m_log.DebugFormat("[ExternalRepresentationUtils]: Processing: {0}", nodeName);
Action<NodeType, XmlTextReader> p = null; Action<NodeType, XmlReader> p = null;
if (processors.TryGetValue(xtr.Name, out p)) if (processors.TryGetValue(xtr.Name, out p))
{ {
// m_log.DebugFormat("[ExternalRepresentationUtils]: Found {0} processor, nodeName); // m_log.DebugFormat("[ExternalRepresentationUtils]: Found {0} processor, nodeName);

View File

@ -44,11 +44,11 @@ namespace OpenSim.Framework.Serialization.External
{ {
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static Dictionary<string, Action<LandData, XmlTextReader>> m_ldProcessors private static Dictionary<string, Action<LandData, XmlReader>> m_ldProcessors
= new Dictionary<string, Action<LandData, XmlTextReader>>(); = new Dictionary<string, Action<LandData, XmlReader>>();
private static Dictionary<string, Action<LandAccessEntry, XmlTextReader>> m_laeProcessors private static Dictionary<string, Action<LandAccessEntry, XmlReader>> m_laeProcessors
= new Dictionary<string, Action<LandAccessEntry, XmlTextReader>>(); = new Dictionary<string, Action<LandAccessEntry, XmlReader>>();
static LandDataSerializer() static LandDataSerializer()
{ {
@ -134,7 +134,7 @@ namespace OpenSim.Framework.Serialization.External
"AccessList", (lae, xtr) => lae.Flags = (AccessList)Convert.ToUInt32(xtr.ReadElementString("AccessList"))); "AccessList", (lae, xtr) => lae.Flags = (AccessList)Convert.ToUInt32(xtr.ReadElementString("AccessList")));
} }
public static void ProcessParcelAccessList(LandData ld, XmlTextReader xtr) public static void ProcessParcelAccessList(LandData ld, XmlReader xtr)
{ {
if (!xtr.IsEmptyElement) if (!xtr.IsEmptyElement)
{ {

View File

@ -46,8 +46,8 @@ namespace OpenSim.Framework.Serialization.External
{ {
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static Dictionary<string, Action<InventoryItemBase, XmlTextReader>> m_InventoryItemXmlProcessors private static Dictionary<string, Action<InventoryItemBase, XmlReader>> m_InventoryItemXmlProcessors
= new Dictionary<string, Action<InventoryItemBase, XmlTextReader>>(); = new Dictionary<string, Action<InventoryItemBase, XmlReader>>();
#region InventoryItemBase Processor initialization #region InventoryItemBase Processor initialization
static UserInventoryItemSerializer() static UserInventoryItemSerializer()
@ -76,103 +76,103 @@ namespace OpenSim.Framework.Serialization.External
#endregion #endregion
#region InventoryItemBase Processors #region InventoryItemBase Processors
private static void ProcessName(InventoryItemBase item, XmlTextReader reader) private static void ProcessName(InventoryItemBase item, XmlReader reader)
{ {
item.Name = reader.ReadElementContentAsString("Name", String.Empty); item.Name = reader.ReadElementContentAsString("Name", String.Empty);
} }
private static void ProcessID(InventoryItemBase item, XmlTextReader reader) private static void ProcessID(InventoryItemBase item, XmlReader reader)
{ {
item.ID = Util.ReadUUID(reader, "ID"); item.ID = Util.ReadUUID(reader, "ID");
} }
private static void ProcessInvType(InventoryItemBase item, XmlTextReader reader) private static void ProcessInvType(InventoryItemBase item, XmlReader reader)
{ {
item.InvType = reader.ReadElementContentAsInt("InvType", String.Empty); item.InvType = reader.ReadElementContentAsInt("InvType", String.Empty);
} }
private static void ProcessCreatorUUID(InventoryItemBase item, XmlTextReader reader) private static void ProcessCreatorUUID(InventoryItemBase item, XmlReader reader)
{ {
item.CreatorId = reader.ReadElementContentAsString("CreatorUUID", String.Empty); item.CreatorId = reader.ReadElementContentAsString("CreatorUUID", String.Empty);
} }
private static void ProcessCreatorID(InventoryItemBase item, XmlTextReader reader) private static void ProcessCreatorID(InventoryItemBase item, XmlReader reader)
{ {
// when it exists, this overrides the previous // when it exists, this overrides the previous
item.CreatorId = reader.ReadElementContentAsString("CreatorID", String.Empty); item.CreatorId = reader.ReadElementContentAsString("CreatorID", String.Empty);
} }
private static void ProcessCreationDate(InventoryItemBase item, XmlTextReader reader) private static void ProcessCreationDate(InventoryItemBase item, XmlReader reader)
{ {
item.CreationDate = reader.ReadElementContentAsInt("CreationDate", String.Empty); item.CreationDate = reader.ReadElementContentAsInt("CreationDate", String.Empty);
} }
private static void ProcessOwner(InventoryItemBase item, XmlTextReader reader) private static void ProcessOwner(InventoryItemBase item, XmlReader reader)
{ {
item.Owner = Util.ReadUUID(reader, "Owner"); item.Owner = Util.ReadUUID(reader, "Owner");
} }
private static void ProcessDescription(InventoryItemBase item, XmlTextReader reader) private static void ProcessDescription(InventoryItemBase item, XmlReader reader)
{ {
item.Description = reader.ReadElementContentAsString("Description", String.Empty); item.Description = reader.ReadElementContentAsString("Description", String.Empty);
} }
private static void ProcessAssetType(InventoryItemBase item, XmlTextReader reader) private static void ProcessAssetType(InventoryItemBase item, XmlReader reader)
{ {
item.AssetType = reader.ReadElementContentAsInt("AssetType", String.Empty); item.AssetType = reader.ReadElementContentAsInt("AssetType", String.Empty);
} }
private static void ProcessAssetID(InventoryItemBase item, XmlTextReader reader) private static void ProcessAssetID(InventoryItemBase item, XmlReader reader)
{ {
item.AssetID = Util.ReadUUID(reader, "AssetID"); item.AssetID = Util.ReadUUID(reader, "AssetID");
} }
private static void ProcessSaleType(InventoryItemBase item, XmlTextReader reader) private static void ProcessSaleType(InventoryItemBase item, XmlReader reader)
{ {
item.SaleType = (byte)reader.ReadElementContentAsInt("SaleType", String.Empty); item.SaleType = (byte)reader.ReadElementContentAsInt("SaleType", String.Empty);
} }
private static void ProcessSalePrice(InventoryItemBase item, XmlTextReader reader) private static void ProcessSalePrice(InventoryItemBase item, XmlReader reader)
{ {
item.SalePrice = reader.ReadElementContentAsInt("SalePrice", String.Empty); item.SalePrice = reader.ReadElementContentAsInt("SalePrice", String.Empty);
} }
private static void ProcessBasePermissions(InventoryItemBase item, XmlTextReader reader) private static void ProcessBasePermissions(InventoryItemBase item, XmlReader reader)
{ {
item.BasePermissions = (uint)reader.ReadElementContentAsInt("BasePermissions", String.Empty); item.BasePermissions = (uint)reader.ReadElementContentAsInt("BasePermissions", String.Empty);
} }
private static void ProcessCurrentPermissions(InventoryItemBase item, XmlTextReader reader) private static void ProcessCurrentPermissions(InventoryItemBase item, XmlReader reader)
{ {
item.CurrentPermissions = (uint)reader.ReadElementContentAsInt("CurrentPermissions", String.Empty); item.CurrentPermissions = (uint)reader.ReadElementContentAsInt("CurrentPermissions", String.Empty);
} }
private static void ProcessEveryOnePermissions(InventoryItemBase item, XmlTextReader reader) private static void ProcessEveryOnePermissions(InventoryItemBase item, XmlReader reader)
{ {
item.EveryOnePermissions = (uint)reader.ReadElementContentAsInt("EveryOnePermissions", String.Empty); item.EveryOnePermissions = (uint)reader.ReadElementContentAsInt("EveryOnePermissions", String.Empty);
} }
private static void ProcessNextPermissions(InventoryItemBase item, XmlTextReader reader) private static void ProcessNextPermissions(InventoryItemBase item, XmlReader reader)
{ {
item.NextPermissions = (uint)reader.ReadElementContentAsInt("NextPermissions", String.Empty); item.NextPermissions = (uint)reader.ReadElementContentAsInt("NextPermissions", String.Empty);
} }
private static void ProcessFlags(InventoryItemBase item, XmlTextReader reader) private static void ProcessFlags(InventoryItemBase item, XmlReader reader)
{ {
item.Flags = (uint)reader.ReadElementContentAsInt("Flags", String.Empty); item.Flags = (uint)reader.ReadElementContentAsInt("Flags", String.Empty);
} }
private static void ProcessGroupID(InventoryItemBase item, XmlTextReader reader) private static void ProcessGroupID(InventoryItemBase item, XmlReader reader)
{ {
item.GroupID = Util.ReadUUID(reader, "GroupID"); item.GroupID = Util.ReadUUID(reader, "GroupID");
} }
private static void ProcessGroupOwned(InventoryItemBase item, XmlTextReader reader) private static void ProcessGroupOwned(InventoryItemBase item, XmlReader reader)
{ {
item.GroupOwned = Util.ReadBoolean(reader); item.GroupOwned = Util.ReadBoolean(reader);
} }
private static void ProcessCreatorData(InventoryItemBase item, XmlTextReader reader) private static void ProcessCreatorData(InventoryItemBase item, XmlReader reader)
{ {
item.CreatorData = reader.ReadElementContentAsString("CreatorData", String.Empty); item.CreatorData = reader.ReadElementContentAsString("CreatorData", String.Empty);
} }

View File

@ -45,6 +45,7 @@ using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using Timer=System.Timers.Timer; using Timer=System.Timers.Timer;
using Nini.Config;
namespace OpenSim.Framework.Servers namespace OpenSim.Framework.Servers
{ {
@ -55,10 +56,16 @@ namespace OpenSim.Framework.Servers
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Used by tests to suppress Environment.Exit(0) so that post-run operations are possible.
/// </summary>
public bool SuppressExit { get; set; }
/// <summary> /// <summary>
/// This will control a periodic log printout of the current 'show stats' (if they are active) for this /// This will control a periodic log printout of the current 'show stats' (if they are active) for this
/// server. /// server.
/// </summary> /// </summary>
private int m_periodDiagnosticTimerMS = 60 * 60 * 1000;
private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000); private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000);
/// <summary> /// <summary>
@ -77,8 +84,6 @@ namespace OpenSim.Framework.Servers
// Random uuid for private data // Random uuid for private data
m_osSecret = UUID.Random().ToString(); m_osSecret = UUID.Random().ToString();
m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics);
m_periodicDiagnosticsTimer.Enabled = true;
} }
/// <summary> /// <summary>
@ -89,6 +94,16 @@ namespace OpenSim.Framework.Servers
StatsManager.SimExtraStats = new SimExtraStatsCollector(); StatsManager.SimExtraStats = new SimExtraStatsCollector();
RegisterCommonCommands(); RegisterCommonCommands();
RegisterCommonComponents(Config); RegisterCommonComponents(Config);
IConfig startupConfig = Config.Configs["Startup"];
int logShowStatsSeconds = startupConfig.GetInt("LogShowStatsSeconds", m_periodDiagnosticTimerMS / 1000);
m_periodDiagnosticTimerMS = logShowStatsSeconds * 1000;
m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics);
if (m_periodDiagnosticTimerMS != 0)
{
m_periodicDiagnosticsTimer.Interval = m_periodDiagnosticTimerMS;
m_periodicDiagnosticsTimer.Enabled = true;
}
} }
protected override void ShutdownSpecific() protected override void ShutdownSpecific()
@ -99,6 +114,7 @@ namespace OpenSim.Framework.Servers
base.ShutdownSpecific(); base.ShutdownSpecific();
if (!SuppressExit)
Environment.Exit(0); Environment.Exit(0);
} }

View File

@ -832,9 +832,14 @@ namespace OpenSim.Framework.Servers.HttpServer
return; // never log these; they're just binary data return; // never log these; they're just binary data
Stream inputStream = Util.Copy(request.InputStream); Stream inputStream = Util.Copy(request.InputStream);
Stream innerStream = null;
try
{
if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip")) if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip"))
inputStream = new GZipStream(inputStream, System.IO.Compression.CompressionMode.Decompress); {
innerStream = inputStream;
inputStream = new GZipStream(innerStream, System.IO.Compression.CompressionMode.Decompress);
}
using (StreamReader reader = new StreamReader(inputStream, Encoding.UTF8)) using (StreamReader reader = new StreamReader(inputStream, Encoding.UTF8))
{ {
@ -856,6 +861,13 @@ namespace OpenSim.Framework.Servers.HttpServer
m_log.DebugFormat("[LOGHTTP] {0}", Util.BinaryToASCII(output)); m_log.DebugFormat("[LOGHTTP] {0}", Util.BinaryToASCII(output));
} }
} }
finally
{
if (innerStream != null)
innerStream.Dispose();
inputStream.Dispose();
}
}
private readonly string HANDLER_SEPARATORS = "/?&#-"; private readonly string HANDLER_SEPARATORS = "/?&#-";
@ -981,19 +993,33 @@ namespace OpenSim.Framework.Servers.HttpServer
/// <param name="response"></param> /// <param name="response"></param>
private byte[] HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response) private byte[] HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response)
{ {
String requestBody;
Stream requestStream = request.InputStream; Stream requestStream = request.InputStream;
Stream innerStream = null;
try
{
if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip")) if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip"))
requestStream = new GZipStream(requestStream, System.IO.Compression.CompressionMode.Decompress); {
innerStream = requestStream;
requestStream = new GZipStream(innerStream, System.IO.Compression.CompressionMode.Decompress);
}
Encoding encoding = Encoding.UTF8; using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8))
StreamReader reader = new StreamReader(requestStream, encoding); {
requestBody = reader.ReadToEnd();
}
}
finally
{
if (innerStream != null)
innerStream.Dispose();
requestStream.Dispose();
}
string requestBody = reader.ReadToEnd();
reader.Close();
requestStream.Close();
//m_log.Debug(requestBody); //m_log.Debug(requestBody);
requestBody = requestBody.Replace("<base64></base64>", ""); requestBody = requestBody.Replace("<base64></base64>", "");
string responseString = String.Empty; string responseString = String.Empty;
XmlRpcRequest xmlRprcRequest = null; XmlRpcRequest xmlRprcRequest = null;
@ -1089,7 +1115,6 @@ namespace OpenSim.Framework.Servers.HttpServer
response.ContentType = "text/xml"; response.ContentType = "text/xml";
using (MemoryStream outs = new MemoryStream()) using (MemoryStream outs = new MemoryStream())
{
using (XmlTextWriter writer = new XmlTextWriter(outs, Encoding.UTF8)) using (XmlTextWriter writer = new XmlTextWriter(outs, Encoding.UTF8))
{ {
writer.Formatting = Formatting.None; writer.Formatting = Formatting.None;
@ -1103,7 +1128,6 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
} }
} }
}
else else
{ {
//HandleLLSDRequests(request, response); //HandleLLSDRequests(request, response);

View File

@ -26,6 +26,7 @@
*/ */
using System; using System;
using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers.HttpServer namespace OpenSim.Framework.Servers.HttpServer
{ {
@ -61,6 +62,24 @@ namespace OpenSim.Framework.Servers.HttpServer
Description = description; Description = description;
m_httpMethod = httpMethod; m_httpMethod = httpMethod;
m_path = path; m_path = path;
// FIXME: A very temporary measure to stop the simulator stats being overwhelmed with user CAPS info.
// Needs to be fixed properly in stats display
if (!path.StartsWith("/CAPS/"))
{
StatsManager.RegisterStat(
new Stat(
"requests",
"requests",
"Number of requests received by this service endpoint",
"requests",
"service",
string.Format("{0}:{1}", httpMethod, path),
StatType.Pull,
MeasuresOfInterest.AverageChangeOverTime,
s => s.Value = RequestsReceived,
StatVerbosity.Debug));
}
} }
public virtual string Path public virtual string Path

View File

@ -52,8 +52,8 @@ namespace OpenSim.Framework.Servers.HttpServer
request.Method = verb; request.Method = verb;
request.ContentType = "text/xml"; request.ContentType = "text/xml";
MemoryStream buffer = new MemoryStream(); using (MemoryStream buffer = new MemoryStream())
{
XmlWriterSettings settings = new XmlWriterSettings(); XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8; settings.Encoding = Encoding.UTF8;
@ -64,11 +64,13 @@ namespace OpenSim.Framework.Servers.HttpServer
writer.Flush(); writer.Flush();
} }
int length = (int) buffer.Length; int length = (int)buffer.Length;
request.ContentLength = length; request.ContentLength = length;
Stream requestStream = request.GetRequestStream(); using (Stream requestStream = request.GetRequestStream())
requestStream.Write(buffer.ToArray(), 0, length); requestStream.Write(buffer.ToArray(), 0, length);
}
// IAsyncResult result = request.BeginGetResponse(AsyncCallback, request); // IAsyncResult result = request.BeginGetResponse(AsyncCallback, request);
request.BeginGetResponse(AsyncCallback, request); request.BeginGetResponse(AsyncCallback, request);
} }

View File

@ -60,8 +60,8 @@ namespace OpenSim.Framework.Servers.HttpServer
request.ContentType = "text/xml"; request.ContentType = "text/xml";
request.Timeout = 10000; request.Timeout = 10000;
MemoryStream buffer = new MemoryStream(); using (MemoryStream buffer = new MemoryStream())
{
XmlWriterSettings settings = new XmlWriterSettings(); XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8; settings.Encoding = Encoding.UTF8;
@ -72,12 +72,13 @@ namespace OpenSim.Framework.Servers.HttpServer
writer.Flush(); writer.Flush();
} }
int length = (int) buffer.Length; int length = (int)buffer.Length;
request.ContentLength = length; request.ContentLength = length;
Stream requestStream = request.GetRequestStream(); using (Stream requestStream = request.GetRequestStream())
requestStream.Write(buffer.ToArray(), 0, length); requestStream.Write(buffer.ToArray(), 0, length);
requestStream.Close(); }
// IAsyncResult result = request.BeginGetResponse(AsyncCallback, request); // IAsyncResult result = request.BeginGetResponse(AsyncCallback, request);
request.BeginGetResponse(AsyncCallback, request); request.BeginGetResponse(AsyncCallback, request);
} }

View File

@ -77,8 +77,8 @@ namespace OpenSim.Framework.Servers.HttpServer
request.ContentType = "text/xml"; request.ContentType = "text/xml";
request.Timeout = 20000; request.Timeout = 20000;
MemoryStream buffer = new MemoryStream(); using (MemoryStream buffer = new MemoryStream())
{
XmlWriterSettings settings = new XmlWriterSettings(); XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8; settings.Encoding = Encoding.UTF8;
@ -92,10 +92,9 @@ namespace OpenSim.Framework.Servers.HttpServer
int length = (int)buffer.Length; int length = (int)buffer.Length;
request.ContentLength = length; request.ContentLength = length;
Stream requestStream = request.GetRequestStream(); using (Stream requestStream = request.GetRequestStream())
requestStream.Write(buffer.ToArray(), 0, length); requestStream.Write(buffer.ToArray(), 0, length);
buffer.Close(); }
requestStream.Close();
TResponse deserial = default(TResponse); TResponse deserial = default(TResponse);
using (WebResponse resp = request.GetResponse()) using (WebResponse resp = request.GetResponse())
@ -133,8 +132,8 @@ namespace OpenSim.Framework.Servers.HttpServer
request.ContentType = "text/xml"; request.ContentType = "text/xml";
request.Timeout = 10000; request.Timeout = 10000;
MemoryStream buffer = new MemoryStream(); using (MemoryStream buffer = new MemoryStream())
{
XmlWriterSettings settings = new XmlWriterSettings(); XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8; settings.Encoding = Encoding.UTF8;
@ -144,14 +143,14 @@ namespace OpenSim.Framework.Servers.HttpServer
serializer.Serialize(writer, sobj); serializer.Serialize(writer, sobj);
writer.Flush(); writer.Flush();
} }
buffer.Close();
int length = (int)buffer.Length; int length = (int)buffer.Length;
request.ContentLength = length; request.ContentLength = length;
Stream requestStream = request.GetRequestStream(); using (Stream requestStream = request.GetRequestStream())
requestStream.Write(buffer.ToArray(), 0, length); requestStream.Write(buffer.ToArray(), 0, length);
requestStream.Close(); }
// IAsyncResult result = request.BeginGetResponse(AsyncCallback, request); // IAsyncResult result = request.BeginGetResponse(AsyncCallback, request);
request.BeginGetResponse(AsyncCallback, request); request.BeginGetResponse(AsyncCallback, request);
} }

View File

@ -29,8 +29,8 @@ namespace OpenSim
{ {
public class VersionInfo public class VersionInfo
{ {
private const string VERSION_NUMBER = "0.8.0"; private const string VERSION_NUMBER = "0.8.0.2";
private const Flavour VERSION_FLAVOUR = Flavour.Dev; private const Flavour VERSION_FLAVOUR = Flavour.Post_Fixes;
public enum Flavour public enum Flavour
{ {
@ -38,6 +38,7 @@ namespace OpenSim
Dev, Dev,
RC1, RC1,
RC2, RC2,
RC3,
Release, Release,
Post_Fixes, Post_Fixes,
Extended Extended

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
namespace OpenSim.Framework
{
/// <summary>
/// A thread-safe Random since the .NET version is not.
/// See http://msdn.microsoft.com/en-us/library/system.random%28v=vs.100%29.aspx
/// </summary>
public class ThreadSafeRandom : Random
{
public ThreadSafeRandom() : base() {}
public ThreadSafeRandom(int seed): base (seed) {}
public override int Next()
{
lock (this)
return base.Next();
}
public override int Next(int maxValue)
{
lock (this)
return base.Next(maxValue);
}
public override int Next(int minValue, int maxValue)
{
lock (this)
return base.Next(minValue, maxValue);
}
public override void NextBytes(byte[] buffer)
{
lock (this)
base.NextBytes(buffer);
}
public override double NextDouble()
{
lock (this)
return base.NextDouble();
}
}
}

View File

@ -138,7 +138,7 @@ namespace OpenSim.Framework
} }
private static uint nextXferID = 5000; private static uint nextXferID = 5000;
private static Random randomClass = new Random(); private static Random randomClass = new ThreadSafeRandom();
// Get a list of invalid file characters (OS dependent) // Get a list of invalid file characters (OS dependent)
private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]"; private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
@ -509,6 +509,19 @@ namespace OpenSim.Framework
return sb.ToString(); return sb.ToString();
} }
public static byte[] DocToBytes(XmlDocument doc)
{
using (MemoryStream ms = new MemoryStream())
using (XmlTextWriter xw = new XmlTextWriter(ms, null))
{
xw.Formatting = Formatting.Indented;
doc.WriteTo(xw);
xw.Flush();
return ms.ToArray();
}
}
/// <summary> /// <summary>
/// Is the platform Windows? /// Is the platform Windows?
/// </summary> /// </summary>
@ -1307,46 +1320,6 @@ namespace OpenSim.Framework
return ret; return ret;
} }
public static string Compress(string text)
{
byte[] buffer = Util.UTF8.GetBytes(text);
MemoryStream memory = new MemoryStream();
using (GZipStream compressor = new GZipStream(memory, CompressionMode.Compress, true))
{
compressor.Write(buffer, 0, buffer.Length);
}
memory.Position = 0;
byte[] compressed = new byte[memory.Length];
memory.Read(compressed, 0, compressed.Length);
byte[] compressedBuffer = new byte[compressed.Length + 4];
Buffer.BlockCopy(compressed, 0, compressedBuffer, 4, compressed.Length);
Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, compressedBuffer, 0, 4);
return Convert.ToBase64String(compressedBuffer);
}
public static string Decompress(string compressedText)
{
byte[] compressedBuffer = Convert.FromBase64String(compressedText);
using (MemoryStream memory = new MemoryStream())
{
int msgLength = BitConverter.ToInt32(compressedBuffer, 0);
memory.Write(compressedBuffer, 4, compressedBuffer.Length - 4);
byte[] buffer = new byte[msgLength];
memory.Position = 0;
using (GZipStream decompressor = new GZipStream(memory, CompressionMode.Decompress))
{
decompressor.Read(buffer, 0, buffer.Length);
}
return Util.UTF8.GetString(buffer);
}
}
/// <summary> /// <summary>
/// Copy data from one stream to another, leaving the read position of both streams at the beginning. /// Copy data from one stream to another, leaving the read position of both streams at the beginning.
/// </summary> /// </summary>
@ -1964,10 +1937,15 @@ namespace OpenSim.Framework
{ {
if (maxThreads < 2) if (maxThreads < 2)
throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2"); throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2");
if (minThreads > maxThreads || minThreads < 2) if (minThreads > maxThreads || minThreads < 2)
throw new ArgumentOutOfRangeException("minThreads", "minThreads must be greater than 2 and less than or equal to maxThreads"); throw new ArgumentOutOfRangeException("minThreads", "minThreads must be greater than 2 and less than or equal to maxThreads");
if (m_ThreadPool != null) if (m_ThreadPool != null)
throw new InvalidOperationException("SmartThreadPool is already initialized"); {
m_log.Warn("SmartThreadPool is already initialized. Ignoring request.");
return;
}
STPStartInfo startInfo = new STPStartInfo(); STPStartInfo startInfo = new STPStartInfo();
startInfo.ThreadPoolName = "Util"; startInfo.ThreadPoolName = "Util";
@ -2621,7 +2599,7 @@ namespace OpenSim.Framework
} }
#region Xml Serialization Utilities #region Xml Serialization Utilities
public static bool ReadBoolean(XmlTextReader reader) public static bool ReadBoolean(XmlReader reader)
{ {
// AuroraSim uses "int" for some fields that are boolean in OpenSim, e.g. "PassCollisions". Don't fail because of this. // AuroraSim uses "int" for some fields that are boolean in OpenSim, e.g. "PassCollisions". Don't fail because of this.
reader.ReadStartElement(); reader.ReadStartElement();
@ -2632,7 +2610,7 @@ namespace OpenSim.Framework
return result; return result;
} }
public static UUID ReadUUID(XmlTextReader reader, string name) public static UUID ReadUUID(XmlReader reader, string name)
{ {
UUID id; UUID id;
string idStr; string idStr;
@ -2651,7 +2629,7 @@ namespace OpenSim.Framework
return id; return id;
} }
public static Vector3 ReadVector(XmlTextReader reader, string name) public static Vector3 ReadVector(XmlReader reader, string name)
{ {
Vector3 vec; Vector3 vec;
@ -2664,7 +2642,7 @@ namespace OpenSim.Framework
return vec; return vec;
} }
public static Quaternion ReadQuaternion(XmlTextReader reader, string name) public static Quaternion ReadQuaternion(XmlReader reader, string name)
{ {
Quaternion quat = new Quaternion(); Quaternion quat = new Quaternion();
@ -2693,7 +2671,7 @@ namespace OpenSim.Framework
return quat; return quat;
} }
public static T ReadEnum<T>(XmlTextReader reader, string name) public static T ReadEnum<T>(XmlReader reader, string name)
{ {
string value = reader.ReadElementContentAsString(name, String.Empty); string value = reader.ReadElementContentAsString(name, String.Empty);
// !!!!! to deal with flags without commas // !!!!! to deal with flags without commas

View File

@ -69,7 +69,7 @@ namespace OpenSim.Framework
/// <summary> /// <summary>
/// Request number for diagnostic purposes. /// Request number for diagnostic purposes.
/// </summary> /// </summary>
public static int RequestNumber { get; internal set; } public static int RequestNumber { get; set; }
/// <summary> /// <summary>
/// Control where OSD requests should be serialized per endpoint. /// Control where OSD requests should be serialized per endpoint.
@ -176,7 +176,8 @@ namespace OpenSim.Framework
public static void LogOutgoingDetail(string context, Stream outputStream) public static void LogOutgoingDetail(string context, Stream outputStream)
{ {
using (StreamReader reader = new StreamReader(Util.Copy(outputStream), Encoding.UTF8)) using (Stream stream = Util.Copy(outputStream))
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{ {
string output; string output;
@ -262,12 +263,12 @@ namespace OpenSim.Framework
using (MemoryStream ms = new MemoryStream()) using (MemoryStream ms = new MemoryStream())
{ {
using (GZipStream comp = new GZipStream(ms, CompressionMode.Compress)) using (GZipStream comp = new GZipStream(ms, CompressionMode.Compress, true))
{ {
comp.Write(buffer, 0, buffer.Length); comp.Write(buffer, 0, buffer.Length);
// We need to close the gzip stream before we write it anywhere // We need to close the gzip stream before we write it anywhere
// because apparently something important related to gzip compression // because apparently something important related to gzip compression
// gets written on the strteam upon Dispose() // gets written on the stream upon Dispose()
} }
byte[] buf = ms.ToArray(); byte[] buf = ms.ToArray();
request.ContentLength = buf.Length; //Count bytes to send request.ContentLength = buf.Length; //Count bytes to send

View File

@ -921,7 +921,7 @@ namespace OpenSim
foreach (IRegionModuleBase module in scene.RegionModules.Values) foreach (IRegionModuleBase module in scene.RegionModules.Values)
{ {
if (module.GetType().GetInterface("ISharedRegionModule") != null) if (module.GetType().GetInterface("ISharedRegionModule") == null)
nonSharedModules.Add(module); nonSharedModules.Add(module);
else else
sharedModules.Add(module); sharedModules.Add(module);
@ -943,6 +943,7 @@ namespace OpenSim
cdt.AddColumn("Name", ConsoleDisplayUtil.RegionNameSize); cdt.AddColumn("Name", ConsoleDisplayUtil.RegionNameSize);
cdt.AddColumn("ID", ConsoleDisplayUtil.UuidSize); cdt.AddColumn("ID", ConsoleDisplayUtil.UuidSize);
cdt.AddColumn("Position", ConsoleDisplayUtil.CoordTupleSize); cdt.AddColumn("Position", ConsoleDisplayUtil.CoordTupleSize);
cdt.AddColumn("Size", 11);
cdt.AddColumn("Port", ConsoleDisplayUtil.PortSize); cdt.AddColumn("Port", ConsoleDisplayUtil.PortSize);
cdt.AddColumn("Ready?", 6); cdt.AddColumn("Ready?", 6);
cdt.AddColumn("Estate", ConsoleDisplayUtil.EstateNameSize); cdt.AddColumn("Estate", ConsoleDisplayUtil.EstateNameSize);
@ -951,8 +952,13 @@ namespace OpenSim
{ {
RegionInfo ri = scene.RegionInfo; RegionInfo ri = scene.RegionInfo;
cdt.AddRow( cdt.AddRow(
ri.RegionName, ri.RegionID, string.Format("{0},{1}", ri.RegionLocX, ri.RegionLocY), ri.RegionName,
ri.InternalEndPoint.Port, scene.Ready ? "Yes" : "No", ri.EstateSettings.EstateName); ri.RegionID,
string.Format("{0},{1}", ri.RegionLocX, ri.RegionLocY),
string.Format("{0}x{1}", ri.RegionSizeX, ri.RegionSizeY),
ri.InternalEndPoint.Port,
scene.Ready ? "Yes" : "No",
ri.EstateSettings.EstateName);
} }
); );

View File

@ -71,6 +71,20 @@ namespace OpenSim
// OpenSim.ini Section name for ESTATES Settings // OpenSim.ini Section name for ESTATES Settings
public const string ESTATE_SECTION_NAME = "Estates"; public const string ESTATE_SECTION_NAME = "Estates";
/// <summary>
/// Allow all plugin loading to be disabled for tests/debug.
/// </summary>
/// <remarks>
/// true by default
/// </remarks>
public bool EnableInitialPluginLoad { get; set; }
/// <summary>
/// Control whether we attempt to load an estate data service.
/// </summary>
/// <remarks>For tests/debugging</remarks>
public bool LoadEstateDataService { get; set; }
protected string proxyUrl; protected string proxyUrl;
protected int proxyOffset = 0; protected int proxyOffset = 0;
@ -96,7 +110,7 @@ namespace OpenSim
public ConsoleCommand CreateAccount = null; public ConsoleCommand CreateAccount = null;
protected List<IApplicationPlugin> m_plugins = new List<IApplicationPlugin>(); public List<IApplicationPlugin> m_plugins = new List<IApplicationPlugin>();
/// <value> /// <value>
/// The config information passed into the OpenSimulator region server. /// The config information passed into the OpenSimulator region server.
@ -135,6 +149,8 @@ namespace OpenSim
/// <param name="configSource"></param> /// <param name="configSource"></param>
public OpenSimBase(IConfigSource configSource) : base() public OpenSimBase(IConfigSource configSource) : base()
{ {
EnableInitialPluginLoad = true;
LoadEstateDataService = true;
LoadConfigSettings(configSource); LoadConfigSettings(configSource);
} }
@ -240,20 +256,25 @@ namespace OpenSim
if (String.IsNullOrEmpty(module)) if (String.IsNullOrEmpty(module))
throw new Exception("Configuration file is missing the LocalServiceModule parameter in the [EstateDataStore] section"); throw new Exception("Configuration file is missing the LocalServiceModule parameter in the [EstateDataStore] section");
if (LoadEstateDataService)
{
m_estateDataService = ServerUtils.LoadPlugin<IEstateDataService>(module, new object[] { Config }); m_estateDataService = ServerUtils.LoadPlugin<IEstateDataService>(module, new object[] { Config });
if (m_estateDataService == null) if (m_estateDataService == null)
throw new Exception( throw new Exception(
string.Format( string.Format(
"Could not load an IEstateDataService implementation from {0}, as configured in the LocalServiceModule parameter of the [EstateDataStore] config section.", "Could not load an IEstateDataService implementation from {0}, as configured in the LocalServiceModule parameter of the [EstateDataStore] config section.",
module)); module));
}
base.StartupSpecific(); base.StartupSpecific();
if (EnableInitialPluginLoad)
LoadPlugins(); LoadPlugins();
// We still want to post initalize any plugins even if loading has been disabled since a test may have
// inserted them manually.
foreach (IApplicationPlugin plugin in m_plugins) foreach (IApplicationPlugin plugin in m_plugins)
{
plugin.PostInitialise(); plugin.PostInitialise();
}
if (m_console != null) if (m_console != null)
AddPluginCommands(m_console); AddPluginCommands(m_console);
@ -713,8 +734,6 @@ namespace OpenSim
clientServer = clientNetworkServers; clientServer = clientNetworkServers;
scene.LoadWorldMap(); scene.LoadWorldMap();
Vector3 regionExtent = new Vector3(regionInfo.RegionSizeX, regionInfo.RegionSizeY, regionInfo.RegionSizeZ);
scene.PhysicsScene = GetPhysicsScene(scene.RegionInfo.RegionName, regionExtent);
scene.PhysicsScene.RequestAssetMethod = scene.PhysicsRequestAsset; scene.PhysicsScene.RequestAssetMethod = scene.PhysicsRequestAsset;
scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
scene.PhysicsScene.SetWaterLevel((float) regionInfo.RegionSettings.WaterHeight); scene.PhysicsScene.SetWaterLevel((float) regionInfo.RegionSettings.WaterHeight);
@ -730,10 +749,13 @@ namespace OpenSim
protected override Scene CreateScene(RegionInfo regionInfo, ISimulationDataService simDataService, protected override Scene CreateScene(RegionInfo regionInfo, ISimulationDataService simDataService,
IEstateDataService estateDataService, AgentCircuitManager circuitManager) IEstateDataService estateDataService, AgentCircuitManager circuitManager)
{ {
Vector3 regionExtent = new Vector3(regionInfo.RegionSizeX, regionInfo.RegionSizeY, regionInfo.RegionSizeZ);
PhysicsScene physicsScene = GetPhysicsScene(regionInfo.RegionName, regionExtent);
SceneCommunicationService sceneGridService = new SceneCommunicationService(); SceneCommunicationService sceneGridService = new SceneCommunicationService();
return new Scene( return new Scene(
regionInfo, circuitManager, sceneGridService, regionInfo, circuitManager, physicsScene, sceneGridService,
simDataService, estateDataService, simDataService, estateDataService,
Config, m_version); Config, m_version);
} }
@ -878,6 +900,9 @@ namespace OpenSim
try try
{ {
SceneManager.Close(); SceneManager.Close();
foreach (IApplicationPlugin plugin in m_plugins)
plugin.Dispose();
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -44,6 +44,7 @@ using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Framework.Client;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps; using Caps = OpenSim.Framework.Capabilities.Caps;
@ -536,6 +537,42 @@ namespace OpenSim.Region.ClientStack.Linden
OSDArray texture_list = (OSDArray)request["texture_list"]; OSDArray texture_list = (OSDArray)request["texture_list"];
SceneObjectGroup grp = null; SceneObjectGroup grp = null;
InventoryFolderBase textureUploadFolder = null;
List<InventoryFolderBase> foldersToUpdate = new List<InventoryFolderBase>();
List<InventoryItemBase> itemsToUpdate = new List<InventoryItemBase>();
IClientInventory clientInv = null;
if (texture_list.Count > 0)
{
ScenePresence avatar = null;
IClientAPI client = null;
m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
if (avatar != null)
{
IClientCore core = (IClientCore)avatar.ControllingClient;
if (core.TryGet<IClientInventory>(out clientInv))
{
var systemTextureFolder = m_Scene.InventoryService.GetFolderForType(m_HostCapsObj.AgentID, AssetType.Texture);
textureUploadFolder = new InventoryFolderBase(UUID.Random(), assetName, m_HostCapsObj.AgentID, (short)AssetType.Unknown, systemTextureFolder.ID, 1);
if (m_Scene.InventoryService.AddFolder(textureUploadFolder))
{
foldersToUpdate.Add(textureUploadFolder);
m_log.DebugFormat(
"[BUNCH OF CAPS]: Created new folder '{0}' ({1}) for textures uploaded with mesh object {2}",
textureUploadFolder.Name, textureUploadFolder.ID, assetName);
}
else
{
textureUploadFolder = null;
}
}
}
}
List<UUID> textures = new List<UUID>(); List<UUID> textures = new List<UUID>();
for (int i = 0; i < texture_list.Count; i++) for (int i = 0; i < texture_list.Count; i++)
{ {
@ -543,6 +580,38 @@ namespace OpenSim.Region.ClientStack.Linden
textureAsset.Data = texture_list[i].AsBinary(); textureAsset.Data = texture_list[i].AsBinary();
m_assetService.Store(textureAsset); m_assetService.Store(textureAsset);
textures.Add(textureAsset.FullID); textures.Add(textureAsset.FullID);
if (textureUploadFolder != null)
{
InventoryItemBase textureItem = new InventoryItemBase();
textureItem.Owner = m_HostCapsObj.AgentID;
textureItem.CreatorId = m_HostCapsObj.AgentID.ToString();
textureItem.CreatorData = String.Empty;
textureItem.ID = UUID.Random();
textureItem.AssetID = textureAsset.FullID;
textureItem.Description = assetDescription;
textureItem.Name = assetName + " - Texture " + (i + 1).ToString();
textureItem.AssetType = (int)AssetType.Texture;
textureItem.InvType = (int)InventoryType.Texture;
textureItem.Folder = textureUploadFolder.ID;
textureItem.CurrentPermissions
= (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export);
textureItem.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
textureItem.EveryOnePermissions = 0;
textureItem.NextPermissions = (uint)PermissionMask.All;
textureItem.CreationDate = Util.UnixTimeSinceEpoch();
m_Scene.InventoryService.AddItem(textureItem);
itemsToUpdate.Add(textureItem);
m_log.DebugFormat(
"[BUNCH OF CAPS]: Created new inventory item '{0}' ({1}) for texture uploaded with mesh object {2}",
textureItem.Name, textureItem.ID, assetName);
}
}
if (clientInv != null && (foldersToUpdate.Count > 0 || itemsToUpdate.Count > 0))
{
clientInv.SendBulkUpdateInventory(foldersToUpdate.ToArray(), itemsToUpdate.ToArray());
} }
for (int i = 0; i < mesh_list.Count; i++) for (int i = 0; i < mesh_list.Count; i++)

View File

@ -101,7 +101,7 @@ namespace OpenSim.Region.ClientStack.Linden
"debug eq [0|1|2]", "debug eq [0|1|2]",
"Turn on event queue debugging\n" "Turn on event queue debugging\n"
+ " <= 0 - turns off all event queue logging\n" + " <= 0 - turns off all event queue logging\n"
+ " >= 1 - turns on outgoing event logging\n" + " >= 1 - turns on event queue setup and outgoing event logging\n"
+ " >= 2 - turns on poll notification", + " >= 2 - turns on poll notification",
HandleDebugEq); HandleDebugEq);
@ -188,9 +188,11 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
if (!queues.ContainsKey(agentId)) if (!queues.ContainsKey(agentId))
{ {
if (DebugLevel > 0)
m_log.DebugFormat( m_log.DebugFormat(
"[EVENTQUEUE]: Adding new queue for agent {0} in region {1}", "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
agentId, m_scene.RegionInfo.RegionName); agentId, m_scene.RegionInfo.RegionName);
queues[agentId] = new Queue<OSD>(); queues[agentId] = new Queue<OSD>();
} }
@ -302,6 +304,7 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
// Register an event queue for the client // Register an event queue for the client
if (DebugLevel > 0)
m_log.DebugFormat( m_log.DebugFormat(
"[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}", "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
agentID, caps, m_scene.RegionInfo.RegionName); agentID, caps, m_scene.RegionInfo.RegionName);
@ -720,8 +723,9 @@ namespace OpenSim.Region.ClientStack.Linden
public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY) public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY)
{ {
m_log.DebugFormat("{0} EnableSimulator. handle={1}, avatarID={2}, regionSize={3},{4}>", if (DebugLevel > 0)
LogHeader, handle, avatarID, regionSizeX, regionSizeY); m_log.DebugFormat("{0} EnableSimulator. handle={1}, endPoint={2}, avatarID={3}",
LogHeader, handle, endPoint, avatarID, regionSizeX, regionSizeY);
OSD item = EventQueueHelper.EnableSimulator(handle, endPoint, regionSizeX, regionSizeY); OSD item = EventQueueHelper.EnableSimulator(handle, endPoint, regionSizeX, regionSizeY);
Enqueue(item, avatarID); Enqueue(item, avatarID);
@ -730,8 +734,10 @@ namespace OpenSim.Region.ClientStack.Linden
public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath, public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath,
ulong regionHandle, int regionSizeX, int regionSizeY) ulong regionHandle, int regionSizeX, int regionSizeY)
{ {
m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, avatarID={2}, regionSize={3},{4}>", if (DebugLevel > 0)
LogHeader, regionHandle, avatarID, regionSizeX, regionSizeY); m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, endPoint={2}, avatarID={3}",
LogHeader, regionHandle, endPoint, avatarID, regionSizeX, regionSizeY);
OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath, regionHandle, regionSizeX, regionSizeY); OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath, regionHandle, regionSizeX, regionSizeY);
Enqueue(item, avatarID); Enqueue(item, avatarID);
} }
@ -741,8 +747,9 @@ namespace OpenSim.Region.ClientStack.Linden
uint locationID, uint flags, string capsURL, uint locationID, uint flags, string capsURL,
UUID avatarID, int regionSizeX, int regionSizeY) UUID avatarID, int regionSizeX, int regionSizeY)
{ {
m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, avatarID={2}, regionSize=<{3},{4}>", if (DebugLevel > 0)
LogHeader, regionHandle, avatarID, regionSizeX, regionSizeY); m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, endPoint={2}, avatarID={3}",
LogHeader, regionHandle, regionExternalEndPoint, avatarID, regionSizeX, regionSizeY);
OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint, OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint,
locationID, flags, capsURL, avatarID, regionSizeX, regionSizeY); locationID, flags, capsURL, avatarID, regionSizeX, regionSizeY);
@ -753,6 +760,7 @@ namespace OpenSim.Region.ClientStack.Linden
IPEndPoint newRegionExternalEndPoint, IPEndPoint newRegionExternalEndPoint,
string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY) string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY)
{ {
if (DebugLevel > 0)
m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>", m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
LogHeader, handle, avatarID, regionSizeX, regionSizeY); LogHeader, handle, avatarID, regionSizeX, regionSizeY);

View File

@ -63,8 +63,7 @@ namespace OpenSim.Region.ClientStack.Linden
public List<UUID> folders; public List<UUID> folders;
} }
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary> /// <summary>
/// Control whether requests will be processed asynchronously. /// Control whether requests will be processed asynchronously.
@ -438,7 +437,18 @@ namespace OpenSim.Region.ClientStack.Linden
aPollRequest poolreq = m_queue.Dequeue(); aPollRequest poolreq = m_queue.Dequeue();
if (poolreq != null && poolreq.thepoll != null) if (poolreq != null && poolreq.thepoll != null)
{
try
{
poolreq.thepoll.Process(poolreq); poolreq.thepoll.Process(poolreq);
} }
catch (Exception e)
{
m_log.ErrorFormat(
"[INVENTORY]: Failed to process queued inventory request {0} for {1} in {2}. Exception {3}",
poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", Scene.Name, e);
}
}
}
} }
} }

View File

@ -1467,10 +1467,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
mapReply.Data[i].Access = mapBlocks2[i].Access; mapReply.Data[i].Access = mapBlocks2[i].Access;
mapReply.Data[i].Agents = mapBlocks2[i].Agents; mapReply.Data[i].Agents = mapBlocks2[i].Agents;
// TODO: hookup varregion sim size here
mapReply.Size[i] = new MapBlockReplyPacket.SizeBlock(); mapReply.Size[i] = new MapBlockReplyPacket.SizeBlock();
mapReply.Size[i].SizeX = 256; mapReply.Size[i].SizeX = mapBlocks2[i].SizeX;
mapReply.Size[i].SizeY = 256; mapReply.Size[i].SizeY = mapBlocks2[i].SizeY;
} }
OutPacket(mapReply, ThrottleOutPacketType.Land); OutPacket(mapReply, ThrottleOutPacketType.Land);
} }
@ -4126,6 +4125,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
} }
// m_log.DebugFormat(
// "[LLCLIENTVIEW]: Sent {0} updates in ProcessEntityUpdates() for {1} {2} in {3}",
// updatesThisCall, Name, SceneAgent.IsChildAgent ? "child" : "root", Scene.Name);
//
#endregion Packet Sending #endregion Packet Sending
} }
@ -11773,7 +11776,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <returns></returns> /// <returns></returns>
protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
{ {
//m_log.Debug("texture cached: " + packet.ToString());
AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse); AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
@ -11789,24 +11791,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
cachedresp.WearableData = cachedresp.WearableData =
new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
//IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
// var item = fac.GetBakedTextureFaces(AgentId);
//WearableCacheItem[] items = fac.GetCachedItems(AgentId);
IAssetService cache = m_scene.AssetService;
IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
//bakedTextureModule = null;
int maxWearablesLoop = cachedtex.WearableData.Length; int maxWearablesLoop = cachedtex.WearableData.Length;
if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES) if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
maxWearablesLoop = AvatarWearable.MAX_WEARABLES; maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
if (bakedTextureModule != null && cache != null) // Find the cached baked textures for this user, if they're available
{
// We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid IAssetService cache = m_scene.AssetService;
IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
WearableCacheItem[] cacheItems = null; WearableCacheItem[] cacheItems = null;
if (bakedTextureModule != null && cache != null)
{
ScenePresence p = m_scene.GetScenePresence(AgentId); ScenePresence p = m_scene.GetScenePresence(AgentId);
if (p.Appearance != null) if (p.Appearance != null)
{
if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty) if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
{ {
try try
@ -11815,22 +11815,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
p.Appearance.WearableCacheItems = cacheItems; p.Appearance.WearableCacheItems = cacheItems;
p.Appearance.WearableCacheItemsDirty = false; p.Appearance.WearableCacheItemsDirty = false;
} }
/*
* The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
*
catch (System.Net.Sockets.SocketException)
{
cacheItems = null;
}
catch (WebException)
{
cacheItems = null;
}
catch (InvalidOperationException)
{
cacheItems = null;
} */
catch (Exception) catch (Exception)
{ {
cacheItems = null; cacheItems = null;
@ -11841,35 +11825,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
cacheItems = p.Appearance.WearableCacheItems; cacheItems = p.Appearance.WearableCacheItems;
} }
}
}
if (cache != null && cacheItems != null) if (cacheItems != null)
{ {
// We need to make sure the asset stored in the bake is available on this server also by its assetid before we map it to a Cacheid.
// Copy the baked textures to the sim's assets cache (local only).
foreach (WearableCacheItem item in cacheItems) foreach (WearableCacheItem item in cacheItems)
{ {
if (cache.GetCached(item.TextureID.ToString()) == null) if (cache.GetCached(item.TextureID.ToString()) == null)
{ {
item.TextureAsset.Temporary = true; item.TextureAsset.Temporary = true;
item.TextureAsset.Local = true;
cache.Store(item.TextureAsset); cache.Store(item.TextureAsset);
} }
} }
}
if (cacheItems != null)
{
// Return the cached textures
for (int i = 0; i < maxWearablesLoop; i++) for (int i = 0; i < maxWearablesLoop; i++)
{ {
WearableCacheItem item = WearableCacheItem item =
WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems); WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex, cacheItems);
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex; cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
cachedresp.WearableData[i].HostName = new byte[0]; cachedresp.WearableData[i].HostName = new byte[0];
if (item != null && cachedtex.WearableData[i].ID == item.CacheId) if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
{ {
cachedresp.WearableData[i].TextureID = item.TextureID; cachedresp.WearableData[i].TextureID = item.TextureID;
} }
else else
@ -11880,48 +11863,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
else else
{ {
// Cached textures not available
for (int i = 0; i < maxWearablesLoop; i++) for (int i = 0; i < maxWearablesLoop; i++)
{ {
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
cachedresp.WearableData[i].TextureID = UUID.Zero; cachedresp.WearableData[i].TextureID = UUID.Zero;
//UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
cachedresp.WearableData[i].HostName = new byte[0]; cachedresp.WearableData[i].HostName = new byte[0];
} }
} }
}
else
{
if (cache == null)
{
for (int i = 0; i < maxWearablesLoop; i++)
{
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
cachedresp.WearableData[i].TextureID = UUID.Zero;
//UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
cachedresp.WearableData[i].HostName = new byte[0];
}
}
else
{
for (int i = 0; i < maxWearablesLoop; i++)
{
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
cachedresp.WearableData[i].TextureID = UUID.Zero;
//UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
else
cachedresp.WearableData[i].TextureID = UUID.Zero;
// UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
cachedresp.WearableData[i].HostName = new byte[0];
}
}
}
cachedresp.Header.Zerocoded = true; cachedresp.Header.Zerocoded = true;
OutPacket(cachedresp, ThrottleOutPacketType.Task); OutPacket(cachedresp, ThrottleOutPacketType.Task);
@ -12314,6 +12265,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// provide your own method.</param> /// provide your own method.</param>
protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method) protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method)
{ {
if (m_outPacketsToDrop != null)
if (m_outPacketsToDrop.Contains(packet.Type.ToString()))
return;
if (DebugPacketLevel > 0) if (DebugPacketLevel > 0)
{ {
bool logPacket = true; bool logPacket = true;
@ -12372,6 +12327,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name="Pack">OpenMetaverse.packet</param> /// <param name="Pack">OpenMetaverse.packet</param>
public void ProcessInPacket(Packet packet) public void ProcessInPacket(Packet packet)
{ {
if (m_inPacketsToDrop != null)
if (m_inPacketsToDrop.Contains(packet.Type.ToString()))
return;
if (DebugPacketLevel > 0) if (DebugPacketLevel > 0)
{ {
bool logPacket = true; bool logPacket = true;
@ -13096,5 +13055,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP
eq.Enqueue(BuildEvent("BulkUpdateInventory", eq.Enqueue(BuildEvent("BulkUpdateInventory",
llsd), AgentId); llsd), AgentId);
} }
private HashSet<string> m_outPacketsToDrop;
public bool AddOutPacketToDropSet(string packetName)
{
if (m_outPacketsToDrop == null)
m_outPacketsToDrop = new HashSet<string>();
return m_outPacketsToDrop.Add(packetName);
}
public bool RemoveOutPacketFromDropSet(string packetName)
{
if (m_outPacketsToDrop == null)
return false;
return m_outPacketsToDrop.Remove(packetName);
}
public HashSet<string> GetOutPacketDropSet()
{
return new HashSet<string>(m_outPacketsToDrop);
}
private HashSet<string> m_inPacketsToDrop;
public bool AddInPacketToDropSet(string packetName)
{
if (m_inPacketsToDrop == null)
m_inPacketsToDrop = new HashSet<string>();
return m_inPacketsToDrop.Add(packetName);
}
public bool RemoveInPacketFromDropSet(string packetName)
{
if (m_inPacketsToDrop == null)
return false;
return m_inPacketsToDrop.Remove(packetName);
}
public HashSet<string> GetInPacketDropSet()
{
return new HashSet<string>(m_inPacketsToDrop);
}
} }
} }

View File

@ -202,7 +202,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Create a token bucket throttle for this client that has the scene token bucket as a parent // Create a token bucket throttle for this client that has the scene token bucket as a parent
m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled); m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled);
// Create a token bucket throttle for the total categary with the client bucket as a throttle // Create a token bucket throttle for the total category with the client bucket as a throttle
m_throttleCategory = new TokenBucket(m_throttleClient, 0); m_throttleCategory = new TokenBucket(m_throttleClient, 0);
// Create an array of token buckets for this clients different throttle categories // Create an array of token buckets for this clients different throttle categories
m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
@ -262,6 +262,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate;
m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate;
m_info.totalThrottle = (int)m_throttleCategory.DripRate; m_info.totalThrottle = (int)m_throttleCategory.DripRate;
m_info.maxThrottle = (int)m_throttleClient.MaxDripRate;
return m_info; return m_info;
} }
@ -648,11 +649,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_categories = categories; m_categories = categories;
if (HasUpdates(m_categories)) if (HasUpdates(m_categories))
{
if (!m_udpServer.OqrEngine.IsRunning)
{ {
// Asynchronously run the callback // Asynchronously run the callback
Util.FireAndForget(FireQueueEmpty, categories); Util.FireAndForget(FireQueueEmpty, categories);
} }
else else
{
m_udpServer.OqrEngine.QueueRequest(this, categories);
}
}
else
{ {
m_isQueueEmptyRunning = false; m_isQueueEmptyRunning = false;
} }
@ -669,8 +677,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name="o">Throttle categories to fire the callback for, /// <param name="o">Throttle categories to fire the callback for,
/// stored as an object to match the WaitCallback delegate /// stored as an object to match the WaitCallback delegate
/// signature</param> /// signature</param>
private void FireQueueEmpty(object o) public void FireQueueEmpty(object o)
{ {
// m_log.DebugFormat("[LLUDPCLIENT]: FireQueueEmpty for {0} in {1}", AgentID, m_udpServer.Scene.Name);
// int start = Environment.TickCount & Int32.MaxValue; // int start = Environment.TickCount & Int32.MaxValue;
// const int MIN_CALLBACK_MS = 30; // const int MIN_CALLBACK_MS = 30;

View File

@ -250,7 +250,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private AgentCircuitManager m_circuitManager; private AgentCircuitManager m_circuitManager;
/// <summary>Reference to the scene this UDP server is attached to</summary> /// <summary>Reference to the scene this UDP server is attached to</summary>
protected Scene m_scene; public Scene Scene { get; private set; }
/// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary> /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary>
private Location m_location; private Location m_location;
@ -355,6 +355,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary> /// </summary>
private IClientAPI m_currentIncomingClient; private IClientAPI m_currentIncomingClient;
/// <summary>
/// Experimental facility to run queue empty processing within a controlled number of threads rather than
/// requiring massive numbers of short-lived threads from the threadpool when there are a high number of
/// connections.
/// </summary>
public OutgoingQueueRefillEngine OqrEngine { get; private set; }
public LLUDPServer( public LLUDPServer(
IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port,
IConfigSource configSource, AgentCircuitManager circuitManager) IConfigSource configSource, AgentCircuitManager circuitManager)
@ -432,12 +439,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (usePools) if (usePools)
EnablePools(); EnablePools();
OqrEngine = new OutgoingQueueRefillEngine(this);
} }
public void Start() public void Start()
{ {
StartInbound(); StartInbound();
StartOutbound(); StartOutbound();
OqrEngine.Start();
m_elapsedMSSinceLastStatReport = Environment.TickCount; m_elapsedMSSinceLastStatReport = Environment.TickCount;
} }
@ -453,7 +463,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// This thread will process the packets received that are placed on the packetInbox // This thread will process the packets received that are placed on the packetInbox
Watchdog.StartThread( Watchdog.StartThread(
IncomingPacketHandler, IncomingPacketHandler,
string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName), string.Format("Incoming Packets ({0})", Scene.Name),
ThreadPriority.Normal, ThreadPriority.Normal,
false, false,
true, true,
@ -469,7 +479,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Watchdog.StartThread( Watchdog.StartThread(
OutgoingPacketHandler, OutgoingPacketHandler,
string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName), string.Format("Outgoing Packets ({0})", Scene.Name),
ThreadPriority.Normal, ThreadPriority.Normal,
false, false,
true, true,
@ -479,9 +489,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void Stop() public void Stop()
{ {
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + Scene.Name);
base.StopOutbound(); base.StopOutbound();
base.StopInbound(); base.StopInbound();
OqrEngine.Stop();
} }
protected override bool EnablePools() protected override bool EnablePools()
@ -527,7 +538,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"The number of objects currently stored within the UDPPacketBuffer pool", "The number of objects currently stored within the UDPPacketBuffer pool",
"", "",
"clientstack", "clientstack",
m_scene.Name, Scene.Name,
StatType.Pull, StatType.Pull,
stat => stat.Value = Pool.Count, stat => stat.Value = Pool.Count,
StatVerbosity.Debug); StatVerbosity.Debug);
@ -541,7 +552,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"The number of objects currently stored within the incoming packet pool", "The number of objects currently stored within the incoming packet pool",
"", "",
"clientstack", "clientstack",
m_scene.Name, Scene.Name,
StatType.Pull, StatType.Pull,
stat => stat.Value = m_incomingPacketPool.Count, stat => stat.Value = m_incomingPacketPool.Count,
StatVerbosity.Debug); StatVerbosity.Debug);
@ -585,7 +596,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void AddScene(IScene scene) public void AddScene(IScene scene)
{ {
if (m_scene != null) if (Scene != null)
{ {
m_log.Error("[LLUDPSERVER]: AddScene() called on an LLUDPServer that already has a scene"); m_log.Error("[LLUDPSERVER]: AddScene() called on an LLUDPServer that already has a scene");
return; return;
@ -597,8 +608,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return; return;
} }
m_scene = (Scene)scene; Scene = (Scene)scene;
m_location = new Location(m_scene.RegionInfo.RegionHandle); m_location = new Location(Scene.RegionInfo.RegionHandle);
StatsManager.RegisterStat( StatsManager.RegisterStat(
new Stat( new Stat(
@ -621,7 +632,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"Packets reused", "Packets reused",
"Number of packets reused out of all requests to the packet pool", "Number of packets reused out of all requests to the packet pool",
"clientstack", "clientstack",
m_scene.Name, Scene.Name,
StatType.Pull, StatType.Pull,
stat => stat =>
{ PercentageStat pstat = (PercentageStat)stat; { PercentageStat pstat = (PercentageStat)stat;
@ -635,7 +646,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"Packet data blocks reused", "Packet data blocks reused",
"Number of data blocks reused out of all requests to the packet pool", "Number of data blocks reused out of all requests to the packet pool",
"clientstack", "clientstack",
m_scene.Name, Scene.Name,
StatType.Pull, StatType.Pull,
stat => stat =>
{ PercentageStat pstat = (PercentageStat)stat; { PercentageStat pstat = (PercentageStat)stat;
@ -650,7 +661,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"The number of objects currently stored within the packet pool", "The number of objects currently stored within the packet pool",
"", "",
"clientstack", "clientstack",
m_scene.Name, Scene.Name,
StatType.Pull, StatType.Pull,
stat => stat.Value = PacketPool.Instance.PacketsPooled, stat => stat.Value = PacketPool.Instance.PacketsPooled,
StatVerbosity.Debug)); StatVerbosity.Debug));
@ -662,7 +673,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"The number of objects currently stored within the packet data block pool", "The number of objects currently stored within the packet data block pool",
"", "",
"clientstack", "clientstack",
m_scene.Name, Scene.Name,
StatType.Pull, StatType.Pull,
stat => stat.Value = PacketPool.Instance.BlocksPooled, stat => stat.Value = PacketPool.Instance.BlocksPooled,
StatVerbosity.Debug)); StatVerbosity.Debug));
@ -674,7 +685,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
MainConsole.Instance.Commands.AddCommand( MainConsole.Instance.Commands.AddCommand(
"Debug", false, "debug lludp packet", "Debug", false, "debug lludp packet",
"debug lludp packet [--default] <level> [<avatar-first-name> <avatar-last-name>]", "debug lludp packet [--default | --all] <level> [<avatar-first-name> <avatar-last-name>]",
"Turn on packet debugging", "Turn on packet debugging",
"If level > 255 then all incoming and outgoing packets are logged.\n" "If level > 255 then all incoming and outgoing packets are logged.\n"
+ "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n" + "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
@ -683,10 +694,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
+ "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n" + "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
+ "If level <= 0 then no packets are logged.\n" + "If level <= 0 then no packets are logged.\n"
+ "If --default is specified then the level becomes the default logging level for all subsequent agents.\n" + "If --default is specified then the level becomes the default logging level for all subsequent agents.\n"
+ "In this case, you cannot also specify an avatar name.\n" + "If --all is specified then the level becomes the default logging level for all current and subsequent agents.\n"
+ "In these cases, you cannot also specify an avatar name.\n"
+ "If an avatar name is given then only packets from that avatar are logged.", + "If an avatar name is given then only packets from that avatar are logged.",
HandlePacketCommand); HandlePacketCommand);
MainConsole.Instance.Commands.AddCommand(
"Debug", false, "debug lludp drop",
"debug lludp drop <in|out> <add|remove> <packet-name>",
"Drop all in or outbound packets that match the given name",
"For test purposes.",
HandleDropCommand);
MainConsole.Instance.Commands.AddCommand( MainConsole.Instance.Commands.AddCommand(
"Debug", "Debug",
false, false,
@ -738,24 +757,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private void HandlePacketCommand(string module, string[] args) private void HandlePacketCommand(string module, string[] args)
{ {
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
return; return;
bool setAsDefaultLevel = false; bool setAsDefaultLevel = false;
OptionSet optionSet = new OptionSet().Add("default", o => setAsDefaultLevel = o != null); bool setAll = false;
OptionSet optionSet = new OptionSet()
.Add("default", o => setAsDefaultLevel = (o != null))
.Add("all", o => setAll = (o != null));
List<string> filteredArgs = optionSet.Parse(args); List<string> filteredArgs = optionSet.Parse(args);
string name = null; string name = null;
if (filteredArgs.Count == 6) if (filteredArgs.Count == 6)
{ {
if (!setAsDefaultLevel) if (!(setAsDefaultLevel || setAll))
{ {
name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]); name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]);
} }
else else
{ {
MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default logging level"); MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default/all logging level");
return; return;
} }
} }
@ -765,21 +787,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int newDebug; int newDebug;
if (int.TryParse(filteredArgs[3], out newDebug)) if (int.TryParse(filteredArgs[3], out newDebug))
{ {
if (setAsDefaultLevel) if (setAsDefaultLevel || setAll)
{ {
DefaultClientPacketDebugLevel = newDebug; DefaultClientPacketDebugLevel = newDebug;
MainConsole.Instance.OutputFormat( MainConsole.Instance.OutputFormat(
"Debug packet debug for new clients set to {0} in {1}", DefaultClientPacketDebugLevel, m_scene.Name); "Packet debug for {0} clients set to {1} in {2}",
(setAll ? "all" : "future"), DefaultClientPacketDebugLevel, Scene.Name);
if (setAll)
{
Scene.ForEachScenePresence(sp =>
{
MainConsole.Instance.OutputFormat(
"Packet debug for {0} ({1}) set to {2} in {3}",
sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, Scene.Name);
sp.ControllingClient.DebugPacketLevel = newDebug;
});
}
} }
else else
{ {
m_scene.ForEachScenePresence(sp => Scene.ForEachScenePresence(sp =>
{ {
if (name == null || sp.Name == name) if (name == null || sp.Name == name)
{ {
MainConsole.Instance.OutputFormat( MainConsole.Instance.OutputFormat(
"Packet debug for {0} ({1}) set to {2} in {3}", "Packet debug for {0} ({1}) set to {2} in {3}",
sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_scene.Name); sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, Scene.Name);
sp.ControllingClient.DebugPacketLevel = newDebug; sp.ControllingClient.DebugPacketLevel = newDebug;
} }
@ -788,14 +824,65 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
else else
{ {
MainConsole.Instance.Output("Usage: debug lludp packet [--default] 0..255 [<first-name> <last-name>]"); MainConsole.Instance.Output("Usage: debug lludp packet [--default | --all] 0..255 [<first-name> <last-name>]");
} }
} }
} }
private void HandleDropCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
return;
if (args.Length != 6)
{
MainConsole.Instance.Output("Usage: debug lludp drop <in|out> <add|remove> <packet-name>");
return;
}
string direction = args[3];
string subCommand = args[4];
string packetName = args[5];
if (subCommand == "add")
{
MainConsole.Instance.OutputFormat(
"Adding packet {0} to {1} drop list for all connections in {2}", direction, packetName, Scene.Name);
Scene.ForEachScenePresence(
sp =>
{
LLClientView llcv = (LLClientView)sp.ControllingClient;
if (direction == "in")
llcv.AddInPacketToDropSet(packetName);
else if (direction == "out")
llcv.AddOutPacketToDropSet(packetName);
}
);
}
else if (subCommand == "remove")
{
MainConsole.Instance.OutputFormat(
"Removing packet {0} from {1} drop list for all connections in {2}", direction, packetName, Scene.Name);
Scene.ForEachScenePresence(
sp =>
{
LLClientView llcv = (LLClientView)sp.ControllingClient;
if (direction == "in")
llcv.RemoveInPacketFromDropSet(packetName);
else if (direction == "out")
llcv.RemoveOutPacketFromDropSet(packetName);
}
);
}
}
private void HandleStartCommand(string module, string[] args) private void HandleStartCommand(string module, string[] args)
{ {
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
return; return;
if (args.Length != 4) if (args.Length != 4)
@ -815,7 +902,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private void HandleStopCommand(string module, string[] args) private void HandleStopCommand(string module, string[] args)
{ {
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
return; return;
if (args.Length != 4) if (args.Length != 4)
@ -835,7 +922,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private void HandlePoolCommand(string module, string[] args) private void HandlePoolCommand(string module, string[] args)
{ {
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
return; return;
if (args.Length != 4) if (args.Length != 4)
@ -851,7 +938,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (EnablePools()) if (EnablePools())
{ {
EnablePoolStats(); EnablePoolStats();
MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name); MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", Scene.Name);
} }
} }
else if (enabled == "off") else if (enabled == "off")
@ -859,7 +946,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (DisablePools()) if (DisablePools())
{ {
DisablePoolStats(); DisablePoolStats();
MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name); MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", Scene.Name);
} }
} }
else else
@ -872,27 +959,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private void HandleAgentUpdateCommand(string module, string[] args) private void HandleAgentUpdateCommand(string module, string[] args)
{ {
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
return; return;
m_discardAgentUpdates = !m_discardAgentUpdates; m_discardAgentUpdates = !m_discardAgentUpdates;
MainConsole.Instance.OutputFormat( MainConsole.Instance.OutputFormat(
"Discard AgentUpdates now {0} for {1}", m_discardAgentUpdates, m_scene.Name); "Discard AgentUpdates now {0} for {1}", m_discardAgentUpdates, Scene.Name);
} }
private void HandleStatusCommand(string module, string[] args) private void HandleStatusCommand(string module, string[] args)
{ {
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
return; return;
MainConsole.Instance.OutputFormat( MainConsole.Instance.OutputFormat(
"IN LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningInbound ? "enabled" : "disabled"); "IN LLUDP packet processing for {0} is {1}", Scene.Name, IsRunningInbound ? "enabled" : "disabled");
MainConsole.Instance.OutputFormat( MainConsole.Instance.OutputFormat(
"OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled"); "OUT LLUDP packet processing for {0} is {1}", Scene.Name, IsRunningOutbound ? "enabled" : "disabled");
MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_scene.Name, UsePools ? "on" : "off"); MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", Scene.Name, UsePools ? "on" : "off");
MainConsole.Instance.OutputFormat( MainConsole.Instance.OutputFormat(
"Packet debug level for new clients is {0}", DefaultClientPacketDebugLevel); "Packet debug level for new clients is {0}", DefaultClientPacketDebugLevel);
@ -973,7 +1060,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
for (int i = 0; i < packetCount; i++) for (int i = 0; i < packetCount; i++)
{ {
byte[] data = datas[i]; byte[] data = datas[i];
if (!SendPacketData(udpClient, data, packet.Type, category, method)) if (!SendPacketData(udpClient, data, packet.Type, category, method))
packetQueued = true; packetQueued = true;
} }
@ -981,7 +1067,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
else else
{ {
byte[] data = packet.ToBytes(); byte[] data = packet.ToBytes();
packetQueued = SendPacketData(udpClient, data, packet.Type, category, method); if (!SendPacketData(udpClient, data, packet.Type, category, method))
packetQueued = true;
} }
PacketPool.Instance.ReturnPacket(packet); PacketPool.Instance.ReturnPacket(packet);
@ -1059,14 +1146,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Queue or Send #region Queue or Send
OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
// If we were not provided a method for handling unacked, use the UDPServer default method // If we were not provided a method for handling unacked, use the UDPServer default method
if ((outgoingPacket.Buffer.Data[0] & Helpers.MSG_RELIABLE) != 0)
outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
// If a Linden Lab 1.23.5 client receives an update packet after a kill packet for an object, it will // If a Linden Lab 1.23.5 client receives an update packet after a kill packet for an object, it will
// continue to display the deleted object until relog. Therefore, we need to always queue a kill object // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
// packet so that it isn't sent before a queued update packet. // packet so that it isn't sent before a queued update packet.
bool requestQueue = type == PacketType.KillObject; bool forceQueue = (type == PacketType.KillObject);
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue))
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forceQueue))
{ {
SendPacketFinal(outgoingPacket); SendPacketFinal(outgoingPacket);
return true; return true;
@ -1399,7 +1489,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Determine which agent this packet came from // Determine which agent this packet came from
IClientAPI client; IClientAPI client;
if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView)) if (!Scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
{ {
//m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
@ -1694,7 +1784,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.DebugFormat( m_log.DebugFormat(
"[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}", "[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}",
uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, endPoint); uccp.CircuitCode.Code, Scene.RegionInfo.RegionName, endPoint);
AuthenticateResponse sessionInfo; AuthenticateResponse sessionInfo;
if (IsClientAuthorized(uccp, out sessionInfo)) if (IsClientAuthorized(uccp, out sessionInfo))
@ -1716,11 +1806,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// We only want to send initial data to new clients, not ones which are being converted from child to root. // We only want to send initial data to new clients, not ones which are being converted from child to root.
if (client != null) if (client != null)
{ {
AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
bool tp = (aCircuit.teleportFlags > 0); bool tp = (aCircuit.teleportFlags > 0);
// Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from
if (!tp) if (!tp && !client.SceneAgent.SentInitialDataToClient)
client.SceneAgent.SendInitialDataToMe(); client.SceneAgent.SendInitialDataToClient();
} }
} }
else else
@ -1728,7 +1818,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Don't create clients for unauthorized requesters. // Don't create clients for unauthorized requesters.
m_log.WarnFormat( m_log.WarnFormat(
"[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); uccp.CircuitCode.ID, Scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
} }
// m_log.DebugFormat( // m_log.DebugFormat(
@ -1760,7 +1850,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1]; CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1];
m_log.DebugFormat( m_log.DebugFormat(
"[LLUDPSERVER]: Handling CompleteAgentMovement request from {0} in {1}", endPoint, m_scene.Name); "[LLUDPSERVER]: Handling CompleteAgentMovement request from {0} in {1}", endPoint, Scene.Name);
// Determine which agent this packet came from // Determine which agent this packet came from
// We need to wait here because in when using the OpenSimulator V2 teleport protocol to travel to a destination // We need to wait here because in when using the OpenSimulator V2 teleport protocol to travel to a destination
@ -1771,7 +1861,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int count = 40; int count = 40;
while (count-- > 0) while (count-- > 0)
{ {
if (m_scene.TryGetClient(endPoint, out client)) if (Scene.TryGetClient(endPoint, out client))
{ {
if (!client.IsActive) if (!client.IsActive)
{ {
@ -1780,7 +1870,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// not yet been established). // not yet been established).
m_log.DebugFormat( m_log.DebugFormat(
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active yet. Waiting.", "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active yet. Waiting.",
endPoint, client.Name, m_scene.Name); endPoint, client.Name, Scene.Name);
} }
else if (client.SceneAgent == null) else if (client.SceneAgent == null)
{ {
@ -1792,7 +1882,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// the client manager // the client manager
m_log.DebugFormat( m_log.DebugFormat(
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client SceneAgent not set yet. Waiting.", "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client SceneAgent not set yet. Waiting.",
endPoint, client.Name, m_scene.Name); endPoint, client.Name, Scene.Name);
} }
else else
{ {
@ -1803,7 +1893,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
m_log.DebugFormat( m_log.DebugFormat(
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} in {1} but no client exists yet. Waiting.", "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} in {1} but no client exists yet. Waiting.",
endPoint, m_scene.Name); endPoint, Scene.Name);
} }
Thread.Sleep(200); Thread.Sleep(200);
@ -1813,7 +1903,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
m_log.DebugFormat( m_log.DebugFormat(
"[LLUDPSERVER]: No client found for CompleteAgentMovement from {0} in {1} after wait. Dropping.", "[LLUDPSERVER]: No client found for CompleteAgentMovement from {0} in {1} after wait. Dropping.",
endPoint, m_scene.Name); endPoint, Scene.Name);
return; return;
} }
@ -1825,7 +1915,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// purposes. // purposes.
m_log.DebugFormat( m_log.DebugFormat(
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active after wait. Dropping.", "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active after wait. Dropping.",
endPoint, client.Name, m_scene.Name); endPoint, client.Name, Scene.Name);
return; return;
} }
@ -1920,11 +2010,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// consistently, this lock could probably be removed. // consistently, this lock could probably be removed.
lock (this) lock (this)
{ {
if (!m_scene.TryGetClient(agentID, out client)) if (!Scene.TryGetClient(agentID, out client))
{ {
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); client = new LLClientView(Scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client.OnLogout += LogoutHandler; client.OnLogout += LogoutHandler;
client.DebugPacketLevel = DefaultClientPacketDebugLevel; client.DebugPacketLevel = DefaultClientPacketDebugLevel;
@ -1954,13 +2044,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.WarnFormat( m_log.WarnFormat(
"[LLUDPSERVER]: No packets received from {0} agent of {1} for {2}ms in {3}. Disconnecting.", "[LLUDPSERVER]: No packets received from {0} agent of {1} for {2}ms in {3}. Disconnecting.",
client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, timeoutTicks, m_scene.Name); client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, timeoutTicks, Scene.Name);
if (!client.SceneAgent.IsChildAgent) if (!client.SceneAgent.IsChildAgent)
client.Kick("Simulator logged you out due to connection timeout."); client.Kick("Simulator logged you out due to connection timeout.");
} }
m_scene.CloseAgent(client.AgentId, true); Scene.CloseAgent(client.AgentId, true);
} }
private void IncomingPacketHandler() private void IncomingPacketHandler()
@ -2072,7 +2162,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Handle outgoing packets, resends, acknowledgements, and pings for each // Handle outgoing packets, resends, acknowledgements, and pings for each
// client. m_packetSent will be set to true if a packet is sent // client. m_packetSent will be set to true if a packet is sent
m_scene.ForEachClient(clientPacketHandler); Scene.ForEachClient(clientPacketHandler);
m_currentOutgoingClient = null; m_currentOutgoingClient = null;
@ -2239,7 +2329,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
watch1.Reset(); watch1.Reset();
// reuse this -- it's every ~100ms // reuse this -- it's every ~100ms
if (m_scene.EmergencyMonitoring && nticks % 100 == 0) if (Scene.EmergencyMonitoring && nticks % 100 == 0)
{ {
m_log.InfoFormat("[LLUDPSERVER]: avg processing ticks: {0} avg unacked: {1} avg acks: {2} avg ping: {3} avg dequeue: {4} (TickCountRes: {5} sent: {6} notsent: {7})", m_log.InfoFormat("[LLUDPSERVER]: avg processing ticks: {0} avg unacked: {1} avg acks: {2} avg ping: {3} avg dequeue: {4} (TickCountRes: {5} sent: {6} notsent: {7})",
avgProcessingTicks, avgResendUnackedTicks, avgSendAcksTicks, avgSendPingTicks, avgDequeueTicks, TickCountResolution, npacksSent, npackNotSent); avgProcessingTicks, avgResendUnackedTicks, avgSendAcksTicks, avgSendPingTicks, avgDequeueTicks, TickCountResolution, npacksSent, npackNotSent);
@ -2288,7 +2378,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
m_log.DebugFormat( m_log.DebugFormat(
"[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
packet.Type, client.Name, m_scene.RegionInfo.RegionName); packet.Type, client.Name, Scene.RegionInfo.RegionName);
} }
IncomingPacketsProcessed++; IncomingPacketsProcessed++;
@ -2301,7 +2391,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (!client.IsLoggingOut) if (!client.IsLoggingOut)
{ {
client.IsLoggingOut = true; client.IsLoggingOut = true;
m_scene.CloseAgent(client.AgentId, false); Scene.CloseAgent(client.AgentId, false);
} }
} }
} }

View File

@ -0,0 +1,286 @@
/*
* 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.Concurrent;
using System.Reflection;
using System.Threading;
using log4net;
using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.ClientStack.LindenUDP
{
public struct RefillRequest
{
public LLUDPClient Client;
public ThrottleOutPacketTypeFlags Categories;
public RefillRequest(LLUDPClient client, ThrottleOutPacketTypeFlags categories)
{
Client = client;
Categories = categories;
}
}
public class OutgoingQueueRefillEngine
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public bool IsRunning { get; private set; }
/// <summary>
/// The timeout in milliseconds to wait for at least one event to be written when the recorder is stopping.
/// </summary>
public int RequestProcessTimeoutOnStop { get; set; }
/// <summary>
/// Controls whether we need to warn in the log about exceeding the max queue size.
/// </summary>
/// <remarks>
/// This is flipped to false once queue max has been exceeded and back to true when it falls below max, in
/// order to avoid spamming the log with lots of warnings.
/// </remarks>
private bool m_warnOverMaxQueue = true;
private BlockingCollection<RefillRequest> m_requestQueue;
private CancellationTokenSource m_cancelSource = new CancellationTokenSource();
private LLUDPServer m_udpServer;
private Stat m_oqreRequestsWaitingStat;
/// <summary>
/// Used to signal that we are ready to complete stop.
/// </summary>
private ManualResetEvent m_finishedProcessingAfterStop = new ManualResetEvent(false);
public OutgoingQueueRefillEngine(LLUDPServer server)
{
RequestProcessTimeoutOnStop = 5000;
m_udpServer = server;
MainConsole.Instance.Commands.AddCommand(
"Debug",
false,
"debug lludp oqre",
"debug lludp oqre <start|stop|status>",
"Start, stop or get status of OutgoingQueueRefillEngine.",
"If stopped then refill requests are processed directly via the threadpool.",
HandleOqreCommand);
}
public void Start()
{
lock (this)
{
if (IsRunning)
return;
IsRunning = true;
m_finishedProcessingAfterStop.Reset();
m_requestQueue = new BlockingCollection<RefillRequest>(new ConcurrentQueue<RefillRequest>(), 5000);
m_oqreRequestsWaitingStat =
new Stat(
"OQRERequestsWaiting",
"Number of outgong queue refill requests waiting for processing.",
"",
"",
"clientstack",
m_udpServer.Scene.Name,
StatType.Pull,
MeasuresOfInterest.None,
stat => stat.Value = m_requestQueue.Count,
StatVerbosity.Debug);
StatsManager.RegisterStat(m_oqreRequestsWaitingStat);
Watchdog.StartThread(
ProcessRequests,
String.Format("OutgoingQueueRefillEngineThread ({0})", m_udpServer.Scene.Name),
ThreadPriority.Normal,
false,
true,
null,
int.MaxValue);
}
}
public void Stop()
{
lock (this)
{
try
{
if (!IsRunning)
return;
IsRunning = false;
int requestsLeft = m_requestQueue.Count;
if (requestsLeft <= 0)
{
m_cancelSource.Cancel();
}
else
{
m_log.InfoFormat("[OUTGOING QUEUE REFILL ENGINE]: Waiting to write {0} events after stop.", requestsLeft);
while (requestsLeft > 0)
{
if (!m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop))
{
// After timeout no events have been written
if (requestsLeft == m_requestQueue.Count)
{
m_log.WarnFormat(
"[OUTGOING QUEUE REFILL ENGINE]: No requests processed after {0} ms wait. Discarding remaining {1} requests",
RequestProcessTimeoutOnStop, requestsLeft);
break;
}
}
requestsLeft = m_requestQueue.Count;
}
}
}
finally
{
m_cancelSource.Dispose();
StatsManager.DeregisterStat(m_oqreRequestsWaitingStat);
m_oqreRequestsWaitingStat = null;
m_requestQueue = null;
}
}
}
public bool QueueRequest(LLUDPClient client, ThrottleOutPacketTypeFlags categories)
{
if (m_requestQueue.Count < m_requestQueue.BoundedCapacity)
{
// m_log.DebugFormat(
// "[OUTGOING QUEUE REFILL ENGINE]: Adding request for categories {0} for {1} in {2}",
// categories, client.AgentID, m_udpServer.Scene.Name);
m_requestQueue.Add(new RefillRequest(client, categories));
if (!m_warnOverMaxQueue)
m_warnOverMaxQueue = true;
return true;
}
else
{
if (m_warnOverMaxQueue)
{
m_log.WarnFormat(
"[OUTGOING QUEUE REFILL ENGINE]: Request queue at maximum capacity, not recording request from {0} in {1}",
client.AgentID, m_udpServer.Scene.Name);
m_warnOverMaxQueue = false;
}
return false;
}
}
private void ProcessRequests()
{
try
{
while (IsRunning || m_requestQueue.Count > 0)
{
RefillRequest req = m_requestQueue.Take(m_cancelSource.Token);
// QueueEmpty callback = req.Client.OnQueueEmpty;
//
// if (callback != null)
// {
// try
// {
// callback(req.Categories);
// }
// catch (Exception e)
// {
// m_log.Error("[OUTGOING QUEUE REFILL ENGINE]: ProcessRequests(" + req.Categories + ") threw an exception: " + e.Message, e);
// }
// }
req.Client.FireQueueEmpty(req.Categories);
}
}
catch (OperationCanceledException)
{
}
m_finishedProcessingAfterStop.Set();
}
private void HandleOqreCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
return;
if (args.Length != 4)
{
MainConsole.Instance.Output("Usage: debug lludp oqre <stop|start|status>");
return;
}
string subCommand = args[3];
if (subCommand == "stop")
{
Stop();
MainConsole.Instance.OutputFormat("Stopped OQRE for {0}", m_udpServer.Scene.Name);
}
else if (subCommand == "start")
{
Start();
MainConsole.Instance.OutputFormat("Started OQRE for {0}", m_udpServer.Scene.Name);
}
else if (subCommand == "status")
{
MainConsole.Instance.OutputFormat("OQRE in {0}", m_udpServer.Scene.Name);
MainConsole.Instance.OutputFormat("Running: {0}", IsRunning);
MainConsole.Instance.OutputFormat(
"Requests waiting: {0}", IsRunning ? m_requestQueue.Count.ToString() : "n/a");
}
else
{
MainConsole.Instance.OutputFormat("Unrecognized OQRE subcommand {0}", subCommand);
}
}
}
}

View File

@ -233,7 +233,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
// testLLUDPServer.RemoveClientCircuit(myCircuitCode); // testLLUDPServer.RemoveClientCircuit(myCircuitCode);
// Assert.IsFalse(testLLUDPServer.HasCircuit(myCircuitCode)); // Assert.IsFalse(testLLUDPServer.HasCircuit(myCircuitCode));
// //
// // Check that removing a non-existant circuit doesn't have any bad effects // // Check that removing a non-existent circuit doesn't have any bad effects
// testLLUDPServer.RemoveClientCircuit(101); // testLLUDPServer.RemoveClientCircuit(101);
// Assert.IsFalse(testLLUDPServer.HasCircuit(101)); // Assert.IsFalse(testLLUDPServer.HasCircuit(101));
// } // }

View File

@ -1,4 +1,4 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
@ -335,13 +335,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// greater than this. // greater than this.
// </summary> // </summary>
protected Int64 m_maxDripRate = 0; protected Int64 m_maxDripRate = 0;
protected Int64 MaxDripRate public Int64 MaxDripRate
{ {
get { return (m_maxDripRate == 0 ? m_totalDripRequest : m_maxDripRate); } get { return (m_maxDripRate == 0 ? m_totalDripRequest : m_maxDripRate); }
set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value,m_minimumFlow)); } protected set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value,m_minimumFlow)); }
} }
private bool m_enabled = false; public bool Enabled { get; private set; }
// <summary> // <summary>
// //
@ -362,9 +362,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// </summary> // </summary>
public AdaptiveTokenBucket(TokenBucket parent, Int64 maxDripRate, bool enabled) : base(parent,maxDripRate) public AdaptiveTokenBucket(TokenBucket parent, Int64 maxDripRate, bool enabled) : base(parent,maxDripRate)
{ {
m_enabled = enabled; Enabled = enabled;
if (m_enabled) if (Enabled)
{ {
// m_log.DebugFormat("[TOKENBUCKET] Adaptive throttle enabled"); // m_log.DebugFormat("[TOKENBUCKET] Adaptive throttle enabled");
MaxDripRate = maxDripRate; MaxDripRate = maxDripRate;
@ -378,7 +378,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void ExpirePackets(Int32 count) public void ExpirePackets(Int32 count)
{ {
// m_log.WarnFormat("[ADAPTIVEBUCKET] drop {0} by {1} expired packets",AdjustedDripRate,count); // m_log.WarnFormat("[ADAPTIVEBUCKET] drop {0} by {1} expired packets",AdjustedDripRate,count);
if (m_enabled) if (Enabled)
AdjustedDripRate = (Int64) (AdjustedDripRate / Math.Pow(2,count)); AdjustedDripRate = (Int64) (AdjustedDripRate / Math.Pow(2,count));
} }
@ -387,7 +387,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// </summary> // </summary>
public void AcknowledgePackets(Int32 count) public void AcknowledgePackets(Int32 count)
{ {
if (m_enabled) if (Enabled)
AdjustedDripRate = AdjustedDripRate + count; AdjustedDripRate = AdjustedDripRate + count;
} }
} }

View File

@ -39,6 +39,7 @@ using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Physics.Manager; using OpenSim.Region.Physics.Manager;
using OpenSim.Services.Interfaces;
namespace OpenSim.Region.ClientStack namespace OpenSim.Region.ClientStack
{ {

View File

@ -31,6 +31,7 @@ using System.Reflection;
using log4net; using log4net;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using PermissionMask = OpenSim.Framework.PermissionMask; using PermissionMask = OpenSim.Framework.PermissionMask;
@ -376,6 +377,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
m_Scene.AssetService.Store(m_asset); m_Scene.AssetService.Store(m_asset);
m_transactions.RemoveXferUploader(m_transactionID); m_transactions.RemoveXferUploader(m_transactionID);
m_Scene.EventManager.TriggerOnNewInventoryItemUploadComplete(ourClient.AgentId, (AssetType)type, m_asset.FullID, m_asset.Name, 0);
} }
/// <summary> /// <summary>
@ -422,5 +425,6 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
m_transactions.RemoveXferUploader(m_transactionID); m_transactions.RemoveXferUploader(m_transactionID);
} }
} }
} }

View File

@ -231,7 +231,11 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
{ {
try try
{ {
List<int> layerStarts = CSJ2K.J2kImage.GetLayerBoundaries(new MemoryStream(j2kData)); List<int> layerStarts;
using (MemoryStream ms = new MemoryStream(j2kData))
{
layerStarts = CSJ2K.J2kImage.GetLayerBoundaries(ms);
}
if (layerStarts != null && layerStarts.Count > 0) if (layerStarts != null && layerStarts.Count > 0)
{ {

View File

@ -315,11 +315,14 @@ namespace OpenSim.Region.CoreModules.Asset
/// Close region module. /// Close region module.
/// </summary> /// </summary>
public void Close() public void Close()
{
if (m_enabled)
{ {
m_enabled = false; m_enabled = false;
m_cache.Clear(); m_cache.Clear();
m_cache = null; m_cache = null;
} }
}
/// <summary> /// <summary>
/// Initialize region module. /// Initialize region module.

View File

@ -251,7 +251,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
private void SendAppearance(ScenePresence sp) private void SendAppearance(ScenePresence sp)
{ {
// Send the appearance to everyone in the scene // Send the appearance to everyone in the scene
sp.SendAppearanceToAllOtherAgents(); sp.SendAppearanceToAllOtherClients();
// Send animations back to the avatar as well // Send animations back to the avatar as well
sp.Animator.SendAnimPack(); sp.Animator.SendAnimPack();

View File

@ -135,7 +135,7 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures
sr.ReadEndElement(); sr.ReadEndElement();
} }
m_log.DebugFormat("[XBakes]: Ended reading"); m_log.DebugFormat("[XBakes]: read {0} textures for user {1}", ret.Count, id);
sr.Close(); sr.Close();
s.Close(); s.Close();
@ -186,6 +186,7 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures
delegate delegate
{ {
rc.Request(reqStream, m_Auth); rc.Request(reqStream, m_Auth);
m_log.DebugFormat("[XBakes]: stored {0} textures for user {1}", data.Length, agentId);
} }
); );
} }

View File

@ -1,4 +1,4 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
@ -289,18 +289,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
rootElement.AppendChild(result); rootElement.AppendChild(result);
return DocToBytes(doc); return Util.DocToBytes(doc);
}
private byte[] DocToBytes(XmlDocument doc)
{
MemoryStream ms = new MemoryStream();
XmlTextWriter xw = new XmlTextWriter(ms, null);
xw.Formatting = Formatting.Indented;
doc.WriteTo(xw);
xw.Flush();
return ms.ToArray();
} }
#endregion #endregion

View File

@ -1153,16 +1153,24 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
parameters = (OSDMap)Params; parameters = (OSDMap)Params;
if (parameters.ContainsKey("result"))
{
OSDArray list = (OSDArray)parameters["result"]; OSDArray list = (OSDArray)parameters["result"];
foreach(OSD asset in list) foreach (OSD asset in list)
{ {
OSDString assetId = (OSDString)asset; OSDString assetId = (OSDString)asset;
Scene.AssetService.Get(string.Format("{0}/{1}",assetServerURI, assetId.AsString())); Scene.AssetService.Get(string.Format("{0}/{1}", assetServerURI, assetId.AsString()));
} }
return true; return true;
} }
else
{
m_log.ErrorFormat("[PROFILES]: Problematic response for image_assets_request from {0}", profileServerURI);
return false;
}
}
/// <summary> /// <summary>
/// Gets the user account data. /// Gets the user account data.

View File

@ -208,7 +208,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
protected virtual void InitialiseCommon(IConfigSource source) protected virtual void InitialiseCommon(IConfigSource source)
{ {
string transferVersionName = "SIMULATION"; string transferVersionName = "SIMULATION";
float maxTransferVersion = 0.2f; float maxTransferVersion = 0.3f;
IConfig hypergridConfig = source.Configs["Hypergrid"]; IConfig hypergridConfig = source.Configs["Hypergrid"];
if (hypergridConfig != null) if (hypergridConfig != null)
@ -760,8 +760,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
string reason; string reason;
string version; string version;
string myversion = string.Format("{0}/{1}", OutgoingTransferVersionName, MaxOutgoingTransferVersion);
if (!Scene.SimulationService.QueryAccess( if (!Scene.SimulationService.QueryAccess(
finalDestination, sp.ControllingClient.AgentId, homeURI, true, position, out version, out reason)) finalDestination, sp.ControllingClient.AgentId, homeURI, true, position, myversion, out version, out reason))
{ {
sp.ControllingClient.SendTeleportFailed(reason); sp.ControllingClient.SendTeleportFailed(reason);
@ -820,7 +821,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agentCircuit.Id0 = currentAgentCircuit.Id0; agentCircuit.Id0 = currentAgentCircuit.Id0;
} }
if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) // if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance,
(float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY));
if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY))
{ {
// brand new agent, let's create a new caps seed // brand new agent, let's create a new caps seed
agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
@ -833,7 +837,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (versionComponents.Length >= 2) if (versionComponents.Length >= 2)
float.TryParse(versionComponents[1], out versionNumber); float.TryParse(versionComponents[1], out versionNumber);
if (versionNumber == 0.2f && MaxOutgoingTransferVersion >= versionNumber) if (versionNumber >= 0.2f && MaxOutgoingTransferVersion >= versionNumber)
TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason); TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
else else
TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason); TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
@ -894,7 +898,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
IClientIPEndpoint ipepClient; IClientIPEndpoint ipepClient;
string capsPath = String.Empty; string capsPath = String.Empty;
if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance,
(float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY));
if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY))
{ {
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}", "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}",
@ -1140,7 +1146,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
IClientIPEndpoint ipepClient; IClientIPEndpoint ipepClient;
string capsPath = String.Empty; string capsPath = String.Empty;
if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance,
(float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY));
if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY))
{ {
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}", "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}",
@ -1509,8 +1517,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
// Check to see if we have access to the target region. // Check to see if we have access to the target region.
string myversion = string.Format("{0}/{1}", OutgoingTransferVersionName, MaxOutgoingTransferVersion);
if (neighbourRegion != null if (neighbourRegion != null
&& !scene.SimulationService.QueryAccess(neighbourRegion, agentID, homeURI, false, newpos, out version, out failureReason)) && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, homeURI, false, newpos, myversion, out version, out failureReason))
{ {
// remember banned // remember banned
m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID); m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID);
@ -1520,7 +1529,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
else else
{ {
// The destination region just doesn't exist // The destination region just doesn't exist
failureReason = "Cannot cross into non-existant region"; failureReason = "Cannot cross into non-existent region";
} }
if (neighbourRegion == null) if (neighbourRegion == null)
@ -1777,8 +1786,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_entityTransferStateMachine.ResetFromTransit(agent.UUID); m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
// now we have a child agent in this region. Request all interesting data about other (root) agents // now we have a child agent in this region. Request all interesting data about other (root) agents
agent.SendOtherAgentsAvatarDataToMe(); agent.SendOtherAgentsAvatarDataToClient();
agent.SendOtherAgentsAppearanceToMe(); agent.SendOtherAgentsAppearanceToClient();
// Backwards compatibility. Best effort // Backwards compatibility. Best effort
if (version == "Unknown" || version == string.Empty) if (version == "Unknown" || version == string.Empty)
@ -1864,7 +1873,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
//foreach (ulong h in agent.ChildrenCapSeeds.Keys) //foreach (ulong h in agent.ChildrenCapSeeds.Keys)
// m_log.DebugFormat("[XXX] --> {0}", h); // m_log.DebugFormat("[XXX] --> {0}", h);
//m_log.DebugFormat("[XXX] Adding {0}", region.RegionHandle); //m_log.DebugFormat("[XXX] Adding {0}", region.RegionHandle);
agent.ChildrenCapSeeds.Add(region.RegionHandle, agent.CapsPath); if (agent.ChildrenCapSeeds.ContainsKey(region.RegionHandle))
{
m_log.WarnFormat(
"[ENTITY TRANSFER]: Overwriting caps seed {0} with {1} for region {2} (handle {3}) for {4} in {5}",
agent.ChildrenCapSeeds[region.RegionHandle], agent.CapsPath,
region.RegionName, region.RegionHandle, sp.Name, Scene.Name);
}
agent.ChildrenCapSeeds[region.RegionHandle] = agent.CapsPath;
if (sp.Scene.CapsModule != null) if (sp.Scene.CapsModule != null)
{ {

View File

@ -130,7 +130,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
base.AddRegion(scene); base.AddRegion(scene);
m_assMapper = new HGAssetMapper(scene, m_HomeURI); m_assMapper = new HGAssetMapper(scene, m_HomeURI);
scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; scene.EventManager.OnNewInventoryItemUploadComplete += PostInventoryAsset;
scene.EventManager.OnTeleportStart += TeleportStart; scene.EventManager.OnTeleportStart += TeleportStart;
scene.EventManager.OnTeleportFail += TeleportFail; scene.EventManager.OnTeleportFail += TeleportFail;
@ -209,7 +209,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
} }
} }
public void UploadInventoryItem(UUID avatarID, AssetType type, UUID assetID, string name, int userlevel) public void PostInventoryAsset(UUID avatarID, AssetType type, UUID assetID, string name, int userlevel)
{ {
if (type == AssetType.Link) if (type == AssetType.Link)
return; return;
@ -248,7 +248,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{ {
UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data); UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data);
UploadInventoryItem(remoteClient.AgentId, AssetType.Unknown, newAssetID, "", 0); PostInventoryAsset(remoteClient.AgentId, AssetType.Unknown, newAssetID, "", 0);
return newAssetID; return newAssetID;
} }
@ -260,7 +260,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{ {
if (base.UpdateInventoryItemAsset(ownerID, item, asset)) if (base.UpdateInventoryItemAsset(ownerID, item, asset))
{ {
UploadInventoryItem(ownerID, (AssetType)asset.Type, asset.FullID, asset.Name, 0); PostInventoryAsset(ownerID, (AssetType)asset.Type, asset.FullID, asset.Name, 0);
return true; return true;
} }
@ -273,7 +273,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
protected override void ExportAsset(UUID agentID, UUID assetID) protected override void ExportAsset(UUID agentID, UUID assetID)
{ {
if (!assetID.Equals(UUID.Zero)) if (!assetID.Equals(UUID.Zero))
UploadInventoryItem(agentID, AssetType.Unknown, assetID, "", 0); PostInventoryAsset(agentID, AssetType.Unknown, assetID, "", 0);
else else
m_log.Debug("[HGScene]: Scene.Inventory did not create asset"); m_log.Debug("[HGScene]: Scene.Inventory did not create asset");
} }

View File

@ -829,7 +829,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
Vector3 pos; Vector3 pos;
bool single = m_Scene.GetObjectsToRez(rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight); bool single
= m_Scene.GetObjectsToRez(
rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight);
if (single) if (single)
{ {

View File

@ -111,6 +111,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
InventoryFolderBase objsFolder InventoryFolderBase objsFolder
= InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0]; = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0];
item1.Folder = objsFolder.ID; item1.Folder = objsFolder.ID;
item1.Flags |= (uint)InventoryItemFlags.ObjectHasMultipleItems;
m_scene.AddInventoryItem(item1); m_scene.AddInventoryItem(item1);
SceneObjectGroup so SceneObjectGroup so

View File

@ -159,7 +159,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
} }
RegionInfo regInfo = new RegionInfo(); RegionInfo regInfo = new RegionInfo();
Scene m_MockScene = new Scene(regInfo); Scene m_MockScene = new Scene(regInfo, null);
LocalInventoryService invService = new LocalInventoryService(lib); LocalInventoryService invService = new LocalInventoryService(lib);
m_MockScene.RegisterModuleInterface<IInventoryService>(invService); m_MockScene.RegisterModuleInterface<IInventoryService>(invService);
m_MockScene.RegisterModuleInterface<IAssetService>(m_Scene.AssetService); m_MockScene.RegisterModuleInterface<IAssetService>(m_Scene.AssetService);

View File

@ -1,4 +1,4 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
@ -151,7 +151,7 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
string path = (m_logDirectory.Length > 0 ? m_logDirectory string path = (m_logDirectory.Length > 0 ? m_logDirectory
+ System.IO.Path.DirectorySeparatorChar.ToString() : "") + System.IO.Path.DirectorySeparatorChar.ToString() : "")
+ String.Format("{0}{1}.log", LogFileHeader, now.ToString("yyyyMMddHHmmss")); + String.Format("{0}{1}.log", LogFileHeader, now.ToString("yyyyMMddHHmmss"));
m_logFile = new StreamWriter(File.Open(path, FileMode.Append, FileAccess.Write)); m_logFile = new StreamWriter(File.Open(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite));
} }
if (m_logFile != null) if (m_logFile != null)
{ {

View File

@ -36,6 +36,7 @@ using Nini.Config;
using Nwc.XmlRpc; using Nwc.XmlRpc;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
@ -656,12 +657,8 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
public void Process() public void Process()
{ {
httpThread = new Thread(SendRequest);
httpThread.Name = "HttpRequestThread";
httpThread.Priority = ThreadPriority.BelowNormal;
httpThread.IsBackground = true;
_finished = false; _finished = false;
httpThread.Start(); Watchdog.StartThread(SendRequest, "HttpRequestThread", ThreadPriority.BelowNormal, true, false);
} }
/* /*
@ -733,6 +730,8 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
} }
_finished = true; _finished = true;
Watchdog.RemoveThread();
} }
public void Stop() public void Stop()

View File

@ -85,7 +85,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
r1.ExternalHostName = "127.0.0.1"; r1.ExternalHostName = "127.0.0.1";
r1.HttpPort = 9001; r1.HttpPort = 9001;
r1.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), 0); r1.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), 0);
Scene s = new Scene(new RegionInfo()); Scene s = new Scene(new RegionInfo(), null);
s.RegionInfo.RegionID = r1.RegionID; s.RegionInfo.RegionID = r1.RegionID;
m_LocalConnector.AddRegion(s); m_LocalConnector.AddRegion(s);
@ -97,7 +97,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
r2.ExternalHostName = "127.0.0.1"; r2.ExternalHostName = "127.0.0.1";
r2.HttpPort = 9002; r2.HttpPort = 9002;
r2.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), 0); r2.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), 0);
s = new Scene(new RegionInfo()); s = new Scene(new RegionInfo(), null);
s.RegionInfo.RegionID = r2.RegionID; s.RegionInfo.RegionID = r2.RegionID;
m_LocalConnector.AddRegion(s); m_LocalConnector.AddRegion(s);
@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
r3.ExternalHostName = "127.0.0.1"; r3.ExternalHostName = "127.0.0.1";
r3.HttpPort = 9003; r3.HttpPort = 9003;
r3.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), 0); r3.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), 0);
s = new Scene(new RegionInfo()); s = new Scene(new RegionInfo(), null);
s.RegionInfo.RegionID = r3.RegionID; s.RegionInfo.RegionID = r3.RegionID;
m_LocalConnector.AddRegion(s); m_LocalConnector.AddRegion(s);
@ -121,7 +121,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
r4.ExternalHostName = "127.0.0.1"; r4.ExternalHostName = "127.0.0.1";
r4.HttpPort = 9004; r4.HttpPort = 9004;
r4.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), 0); r4.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), 0);
s = new Scene(new RegionInfo()); s = new Scene(new RegionInfo(), null);
s.RegionInfo.RegionID = r4.RegionID; s.RegionInfo.RegionID = r4.RegionID;
m_LocalConnector.AddRegion(s); m_LocalConnector.AddRegion(s);

View File

@ -244,7 +244,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
if (inventoryURL != null && inventoryURL != string.Empty) if (inventoryURL != null && inventoryURL != string.Empty)
{ {
inventoryURL = inventoryURL.Trim(new char[] { '/' }); inventoryURL = inventoryURL.Trim(new char[] { '/' });
m_InventoryURLs.Add(userID, inventoryURL); m_InventoryURLs[userID] = inventoryURL;
m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL); m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
return; return;
} }

View File

@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
/// Currently valid versions are "SIMULATION/0.1" and "SIMULATION/0.2" /// Currently valid versions are "SIMULATION/0.1" and "SIMULATION/0.2"
/// </remarks> /// </remarks>
public string ServiceVersion { get; set; } public string ServiceVersion { get; set; }
private float m_VersionNumber = 0.3f;
/// <summary> /// <summary>
/// Map region ID to scene. /// Map region ID to scene.
@ -84,15 +85,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
public void InitialiseService(IConfigSource configSource) public void InitialiseService(IConfigSource configSource)
{ {
ServiceVersion = "SIMULATION/0.2"; ServiceVersion = "SIMULATION/0.3";
IConfig config = configSource.Configs["SimulationService"]; IConfig config = configSource.Configs["SimulationService"];
if (config != null) if (config != null)
{ {
ServiceVersion = config.GetString("ConnectorProtocolVersion", ServiceVersion); ServiceVersion = config.GetString("ConnectorProtocolVersion", ServiceVersion);
if (ServiceVersion != "SIMULATION/0.1" && ServiceVersion != "SIMULATION/0.2") if (ServiceVersion != "SIMULATION/0.1" && ServiceVersion != "SIMULATION/0.2" && ServiceVersion != "SIMULATION/0.3")
throw new Exception(string.Format("Invalid ConnectorProtocolVersion {0}", ServiceVersion)); throw new Exception(string.Format("Invalid ConnectorProtocolVersion {0}", ServiceVersion));
string[] versionComponents = ServiceVersion.Split(new char[] { '/' });
if (versionComponents.Length >= 2)
float.TryParse(versionComponents[1], out m_VersionNumber);
m_log.InfoFormat( m_log.InfoFormat(
"[LOCAL SIMULATION CONNECTOR]: Initialized with connector protocol version {0}", ServiceVersion); "[LOCAL SIMULATION CONNECTOR]: Initialized with connector protocol version {0}", ServiceVersion);
} }
@ -264,7 +269,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return true; return true;
} }
public bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, out string version, out string reason) public bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, string theirversion, out string version, out string reason)
{ {
reason = "Communications failure"; reason = "Communications failure";
version = ServiceVersion; version = ServiceVersion;
@ -276,6 +281,22 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
// m_log.DebugFormat( // m_log.DebugFormat(
// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
// s.RegionInfo.RegionName, destination.RegionHandle); // s.RegionInfo.RegionName, destination.RegionHandle);
uint size = m_scenes[destination.RegionID].RegionInfo.RegionSizeX;
float theirVersionNumber = 0f;
string[] versionComponents = theirversion.Split(new char[] { '/' });
if (versionComponents.Length >= 2)
float.TryParse(versionComponents[1], out theirVersionNumber);
// Var regions here, and the requesting simulator is in an older version.
// We will forbide this, because it crashes the viewers
if (theirVersionNumber < 0.3f && size > 256)
{
reason = "Destination is a variable-sized region, and source is an old simulator. Consider upgrading.";
m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Request to access this variable-sized region from {0} simulator was denied", theirVersionNumber);
return false;
}
return m_scenes[destination.RegionID].QueryAccess(agentID, agentHomeURI, viaTeleport, position, out reason); return m_scenes[destination.RegionID].QueryAccess(agentID, agentHomeURI, viaTeleport, position, out reason);
} }

View File

@ -207,7 +207,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return m_remoteConnector.UpdateAgent(destination, cAgentData); return m_remoteConnector.UpdateAgent(destination, cAgentData);
} }
public bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, out string version, out string reason) public bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, string sversion, out string version, out string reason)
{ {
reason = "Communications failure"; reason = "Communications failure";
version = "Unknown"; version = "Unknown";
@ -216,12 +216,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return false; return false;
// Try local first // Try local first
if (m_localBackend.QueryAccess(destination, agentID, agentHomeURI, viaTeleport, position, out version, out reason)) if (m_localBackend.QueryAccess(destination, agentID, agentHomeURI, viaTeleport, position, sversion, out version, out reason))
return true; return true;
// else do the remote thing // else do the remote thing
if (!m_localBackend.IsLocalRegion(destination.RegionID)) if (!m_localBackend.IsLocalRegion(destination.RegionID))
return m_remoteConnector.QueryAccess(destination, agentID, agentHomeURI, viaTeleport, position, out version, out reason); return m_remoteConnector.QueryAccess(destination, agentID, agentHomeURI, viaTeleport, position, sversion, out version, out reason);
return false; return false;
} }

View File

@ -90,13 +90,17 @@ namespace OpenSim.Region.CoreModules.World
} }
public void AddRegion(Scene scene) public void AddRegion(Scene scene)
{
lock (m_SceneList)
{ {
if (!m_SceneList.Contains(scene)) if (!m_SceneList.Contains(scene))
m_SceneList.Add(scene); m_SceneList.Add(scene);
} }
}
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
{ {
lock (m_SceneList)
m_SceneList.Remove(scene); m_SceneList.Remove(scene);
} }

View File

@ -918,7 +918,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
{ {
ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>(); ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>();
MemoryStream ms = new MemoryStream(data); using (MemoryStream ms = new MemoryStream(data))
{
if (m_displacement != Vector3.Zero || m_rotation != 0f) if (m_displacement != Vector3.Zero || m_rotation != 0f)
{ {
Vector2 rotationCenter = new Vector2(m_rotationCenter.X, m_rotationCenter.Y); Vector2 rotationCenter = new Vector2(m_rotationCenter.X, m_rotationCenter.Y);
@ -928,7 +929,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
{ {
terrainModule.LoadFromStream(terrainPath, ms); terrainModule.LoadFromStream(terrainPath, ms);
} }
ms.Close(); }
m_log.DebugFormat("[ARCHIVER]: Restored terrain {0}", terrainPath); m_log.DebugFormat("[ARCHIVER]: Restored terrain {0}", terrainPath);

View File

@ -569,10 +569,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
string terrainPath = String.Format("{0}{1}{2}.r32", string terrainPath = String.Format("{0}{1}{2}.r32",
regionDir, ArchiveConstants.TERRAINS_PATH, scene.RegionInfo.RegionName); regionDir, ArchiveConstants.TERRAINS_PATH, scene.RegionInfo.RegionName);
MemoryStream ms = new MemoryStream(); using (MemoryStream ms = new MemoryStream())
{
scene.RequestModuleInterface<ITerrainModule>().SaveToStream(terrainPath, ms); scene.RequestModuleInterface<ITerrainModule>().SaveToStream(terrainPath, ms);
m_archiveWriter.WriteFile(terrainPath, ms.ToArray()); m_archiveWriter.WriteFile(terrainPath, ms.ToArray());
ms.Close(); }
m_log.InfoFormat("[ARCHIVER]: Adding scene objects to archive."); m_log.InfoFormat("[ARCHIVER]: Adding scene objects to archive.");

View File

@ -1116,9 +1116,8 @@ namespace OpenSim.Region.CoreModules.World.Estate
{ {
try try
{ {
MemoryStream terrainStream = new MemoryStream(terrainData); using (MemoryStream terrainStream = new MemoryStream(terrainData))
terr.LoadFromStream(filename, terrainStream); terr.LoadFromStream(filename, terrainStream);
terrainStream.Close();
FileInfo x = new FileInfo(filename); FileInfo x = new FileInfo(filename);
remoteClient.SendAlertMessage("Your terrain was loaded as a " + x.Extension + " file. It may take a few moments to appear."); remoteClient.SendAlertMessage("Your terrain was loaded as a " + x.Extension + " file. It may take a few moments to appear.");

View File

@ -281,18 +281,8 @@ namespace OpenSim.Region.CoreModules.World.Estate
rootElement.AppendChild(result); rootElement.AppendChild(result);
return DocToBytes(doc); return Util.DocToBytes(doc);
} }
private byte[] DocToBytes(XmlDocument doc)
{
MemoryStream ms = new MemoryStream();
XmlTextWriter xw = new XmlTextWriter(ms, null);
xw.Formatting = Formatting.Indented;
doc.WriteTo(xw);
xw.Flush();
return ms.ToArray();
}
} }
} }

View File

@ -525,16 +525,13 @@ namespace OpenSim.Region.CoreModules.World.Land
/// </summary> /// </summary>
/// <param name="avatar"></param> /// <param name="avatar"></param>
public void EventManagerOnClientMovement(ScenePresence avatar) public void EventManagerOnClientMovement(ScenePresence avatar)
//
{ {
ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); Vector3 pos = avatar.AbsolutePosition;
ILandObject over = GetLandObject(pos.X, pos.Y);
if (over != null) if (over != null)
{ {
if (!over.IsRestrictedFromLand(avatar.UUID) && (!over.IsBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= LandChannel.BAN_LINE_SAFETY_HIEGHT)) if (!over.IsRestrictedFromLand(avatar.UUID) && (!over.IsBannedFromLand(avatar.UUID) || pos.Z >= LandChannel.BAN_LINE_SAFETY_HIEGHT))
{ avatar.lastKnownAllowedPosition = pos;
avatar.lastKnownAllowedPosition =
new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z);
}
} }
} }
@ -858,7 +855,7 @@ namespace OpenSim.Region.CoreModules.World.Land
return null; return null;
else else
throw new Exception( throw new Exception(
String.Format("{0} GetLandObject for non-existant position. Region={1}, pos=<{2},{3}", String.Format("{0} GetLandObject for non-existent position. Region={1}, pos=<{2},{3}",
LogHeader, m_scene.RegionInfo.RegionName, x, y) LogHeader, m_scene.RegionInfo.RegionName, x, y)
); );
} }
@ -1985,7 +1982,9 @@ namespace OpenSim.Region.CoreModules.World.Land
telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject); telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject);
// Can the user set home here? // Can the user set home here?
if (// (a) gods and land managers can set home if (// Required: local user; foreign users cannot set home
m_scene.UserManagementModule.IsLocalGridUser(remoteClient.AgentId) &&
(// (a) gods and land managers can set home
m_scene.Permissions.IsAdministrator(remoteClient.AgentId) || m_scene.Permissions.IsAdministrator(remoteClient.AgentId) ||
m_scene.Permissions.IsGod(remoteClient.AgentId) || m_scene.Permissions.IsGod(remoteClient.AgentId) ||
// (b) land owners can set home // (b) land owners can set home
@ -1993,7 +1992,7 @@ namespace OpenSim.Region.CoreModules.World.Land
// (c) members of the land-associated group in roles that can set home // (c) members of the land-associated group in roles that can set home
((gpowers & (ulong)GroupPowers.AllowSetHome) == (ulong)GroupPowers.AllowSetHome) || ((gpowers & (ulong)GroupPowers.AllowSetHome) == (ulong)GroupPowers.AllowSetHome) ||
// (d) parcels with telehubs can be the home of anyone // (d) parcels with telehubs can be the home of anyone
(telehub != null && land.ContainsPoint((int)telehub.AbsolutePosition.X, (int)telehub.AbsolutePosition.Y))) (telehub != null && land.ContainsPoint((int)telehub.AbsolutePosition.X, (int)telehub.AbsolutePosition.Y))))
{ {
if (m_scene.GridUserService.SetHome(remoteClient.AgentId.ToString(), land.RegionUUID, position, lookAt)) if (m_scene.GridUserService.SetHome(remoteClient.AgentId.ToString(), land.RegionUUID, position, lookAt))
// FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.

View File

@ -54,14 +54,15 @@ namespace OpenSim.Region.CoreModules.World.Serialiser
{ {
string xmlstream = GetObjectXml(scene); string xmlstream = GetObjectXml(scene);
MemoryStream stream = ReformatXmlString(xmlstream); using (MemoryStream stream = ReformatXmlString(xmlstream))
{
stream.Seek(0, SeekOrigin.Begin); stream.Seek(0, SeekOrigin.Begin);
CreateXmlFile(stream, fileName); CreateXmlFile(stream, fileName);
stream.Seek(0, SeekOrigin.Begin); stream.Seek(0, SeekOrigin.Begin);
CreateCompressedXmlFile(stream, fileName); CreateCompressedXmlFile(stream, fileName);
} }
}
private static MemoryStream ReformatXmlString(string xmlstream) private static MemoryStream ReformatXmlString(string xmlstream)
{ {
@ -112,13 +113,16 @@ namespace OpenSim.Region.CoreModules.World.Serialiser
{ {
#region GZip Compressed Version #region GZip Compressed Version
FileStream objectsFileCompressed = new FileStream(fileName + ".gzs", FileMode.Create); using (FileStream objectsFileCompressed = new FileStream(fileName + ".gzs", FileMode.Create))
MemoryStream gzipMSStream = new MemoryStream(); using (MemoryStream gzipMSStream = new MemoryStream())
GZipStream gzipStream = new GZipStream(gzipMSStream, CompressionMode.Compress); {
using (GZipStream gzipStream = new GZipStream(gzipMSStream, CompressionMode.Compress, true))
{
xmlStream.WriteTo(gzipStream); xmlStream.WriteTo(gzipStream);
}
gzipMSStream.WriteTo(objectsFileCompressed); gzipMSStream.WriteTo(objectsFileCompressed);
objectsFileCompressed.Flush(); }
objectsFileCompressed.Close();
#endregion #endregion
} }

View File

@ -27,6 +27,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text;
using System.Xml; using System.Xml;
using log4net.Config; using log4net.Config;
using NUnit.Framework; using NUnit.Framework;
@ -42,8 +43,8 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
[TestFixture] [TestFixture]
public class SerialiserTests : OpenSimTestCase public class SerialiserTests : OpenSimTestCase
{ {
private string xml = @" private const string ObjectRootPartStubXml =
<SceneObjectGroup> @"<SceneObjectGroup>
<RootPart> <RootPart>
<SceneObjectPart xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""> <SceneObjectPart xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<AllowedDrop>false</AllowedDrop> <AllowedDrop>false</AllowedDrop>
@ -159,11 +160,234 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
</llsd> </llsd>
</DynAttrs> </DynAttrs>
</SceneObjectPart> </SceneObjectPart>
</RootPart> </RootPart>";
<OtherParts />
</SceneObjectGroup>";
private string badFloatsXml = @" private const string ObjectWithNoOtherPartsXml = ObjectRootPartStubXml +
@"
<OtherParts />
</SceneObjectGroup>";
private const string ObjectWithOtherPartsXml = ObjectRootPartStubXml +
@"
<OtherParts>
<Part>
<SceneObjectPart xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<AllowedDrop>false</AllowedDrop>
<CreatorID><Guid>a6dacf01-4636-4bb9-8a97-30609438af9d</Guid></CreatorID>
<FolderID><Guid>9958feb1-02a6-49e4-a4ce-eba6f578ee13</Guid></FolderID>
<InventorySerial>3</InventorySerial>
<UUID><Guid>9958feb1-02a6-49e4-a4ce-eba6f578ee13</Guid></UUID>
<LocalId>1154704500</LocalId>
<Name>Alien Head 1</Name>
<Material>3</Material>
<PassTouches>false</PassTouches>
<PassCollisions>false</PassCollisions>
<RegionHandle>21990232560640000</RegionHandle>
<ScriptAccessPin>0</ScriptAccessPin>
<GroupPosition><X>125.5655</X><Y>127.346</Y><Z>22.48036</Z></GroupPosition>
<OffsetPosition><X>-0.2171936</X><Y>0.1083984</Y><Z>0.0009994507</Z></OffsetPosition>
<RotationOffset><X>-0.5122106</X><Y>0.4851225</Y><Z>-0.4957454</Z><W>0.5064908</W></RotationOffset>
<Velocity><X>0</X><Y>0</Y><Z>0</Z></Velocity>
<AngularVelocity><X>0</X><Y>0</Y><Z>0</Z></AngularVelocity>
<Acceleration><X>0</X><Y>0</Y><Z>0</Z></Acceleration>
<Description>(No Description)</Description>
<Color><R>0</R><G>0</G><B>0</B><A>255</A></Color>
<Text/>
<SitName/>
<TouchName/>
<LinkNum>253</LinkNum>
<ClickAction>0</ClickAction>
<Shape>
<ProfileCurve>5</ProfileCurve>
<TextureEntry>Vw3dpvgTRUOiIUOGsnpWlAB/f38AAAAAgL8AAACAPwAAAAAAAAAF4ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</TextureEntry>
<ExtraParams>AA==</ExtraParams>
<PathBegin>0</PathBegin>
<PathCurve>32</PathCurve>
<PathEnd>0</PathEnd>
<PathRadiusOffset>0</PathRadiusOffset>
<PathRevolutions>0</PathRevolutions>
<PathScaleX>100</PathScaleX>
<PathScaleY>100</PathScaleY>
<PathShearX>0</PathShearX>
<PathShearY>0</PathShearY>
<PathSkew>0</PathSkew>
<PathTaperX>0</PathTaperX>
<PathTaperY>0</PathTaperY>
<PathTwist>0</PathTwist>
<PathTwistBegin>0</PathTwistBegin>
<PCode>9</PCode>
<ProfileBegin>0</ProfileBegin>
<ProfileEnd>0</ProfileEnd>
<ProfileHollow>0</ProfileHollow>
<State>9</State>
<LastAttachPoint>0</LastAttachPoint>
<ProfileShape>HalfCircle</ProfileShape>
<HollowShape>Same</HollowShape>
<SculptTexture><Guid>00000000-0000-0000-0000-000000000000</Guid></SculptTexture>
<SculptType>0</SculptType>
<FlexiSoftness>0</FlexiSoftness>
<FlexiTension>0</FlexiTension>
<FlexiDrag>0</FlexiDrag>
<FlexiGravity>0</FlexiGravity>
<FlexiWind>0</FlexiWind>
<FlexiForceX>0</FlexiForceX>
<FlexiForceY>0</FlexiForceY>
<FlexiForceZ>0</FlexiForceZ>
<LightColorR>0</LightColorR>
<LightColorG>0</LightColorG>
<LightColorB>0</LightColorB>
<LightColorA>1</LightColorA>
<LightRadius>0</LightRadius>
<LightCutoff>0</LightCutoff>
<LightFalloff>0</LightFalloff>
<LightIntensity>1</LightIntensity>
<FlexiEntry>false</FlexiEntry>
<LightEntry>false</LightEntry>
<SculptEntry>false</SculptEntry>
</Shape>
<Scale><X>0.1148195</X><Y>0.0143891</Y><Z>0.02768878</Z></Scale>
<SitTargetOrientation><X>0</X><Y>0</Y><Z>0</Z><W>1</W></SitTargetOrientation>
<SitTargetPosition><X>0</X><Y>0</Y><Z>0</Z></SitTargetPosition>
<SitTargetPositionLL><X>0</X><Y>0</Y><Z>0</Z></SitTargetPositionLL>
<SitTargetOrientationLL><X>0</X><Y>0</Y><Z>0</Z><W>1</W></SitTargetOrientationLL>
<ParentID>1154704499</ParentID>
<CreationDate>1256611042</CreationDate>
<Category>0</Category>
<SalePrice>10</SalePrice>
<ObjectSaleType>0</ObjectSaleType>
<OwnershipCost>0</OwnershipCost>
<GroupID><Guid>00000000-0000-0000-0000-000000000000</Guid></GroupID>
<OwnerID><Guid>7b2022f0-5f19-488c-b7e5-829d8f96b448</Guid></OwnerID>
<LastOwnerID><Guid>7b2022f0-5f19-488c-b7e5-829d8f96b448</Guid></LastOwnerID>
<BaseMask>647168</BaseMask>
<OwnerMask>647168</OwnerMask>
<GroupMask>0</GroupMask>
<EveryoneMask>0</EveryoneMask>
<NextOwnerMask>581632</NextOwnerMask>
<Flags>None</Flags>
<CollisionSound><Guid>00000000-0000-0000-0000-000000000000</Guid></CollisionSound>
<CollisionSoundVolume>0</CollisionSoundVolume>
<AttachedPos><X>0</X><Y>0</Y><Z>0</Z></AttachedPos>
<TextureAnimation/>
<ParticleSystem/>
<PayPrice0>-2</PayPrice0>
<PayPrice1>-2</PayPrice1>
<PayPrice2>-2</PayPrice2>
<PayPrice3>-2</PayPrice3>
<PayPrice4>-2</PayPrice4>
</SceneObjectPart>
</Part>
<Part>
<SceneObjectPart xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<AllowedDrop>false</AllowedDrop>
<CreatorID><Guid>a6dacf01-4636-4bb9-8a97-30609438af9d</Guid></CreatorID>
<FolderID><Guid>674b6b86-f5aa-439a-8e00-0d75bc08c80a</Guid></FolderID>
<InventorySerial>3</InventorySerial>
<UUID><Guid>674b6b86-f5aa-439a-8e00-0d75bc08c80a</Guid></UUID>
<LocalId>1154704501</LocalId>
<Name>Alien Head 2</Name>
<Material>3</Material>
<PassTouches>false</PassTouches>
<PassCollisions>false</PassCollisions>
<RegionHandle>21990232560640000</RegionHandle>
<ScriptAccessPin>0</ScriptAccessPin>
<GroupPosition><X>125.5655</X><Y>127.346</Y><Z>22.48036</Z></GroupPosition>
<OffsetPosition><X>-0.2490997</X><Y>0.08520126</Y><Z>0.0009002686</Z></OffsetPosition>
<RotationOffset><X>-0.4765368</X><Y>0.5194498</Y><Z>-0.5301372</Z><W>0.4712104</W></RotationOffset>
<Velocity><X>0</X><Y>0</Y><Z>0</Z></Velocity>
<AngularVelocity><X>0</X><Y>0</Y><Z>0</Z></AngularVelocity>
<Acceleration><X>0</X><Y>0</Y><Z>0</Z></Acceleration>
<Description>(No Description)</Description>
<Color><R>0</R><G>0</G><B>0</B><A>255</A></Color>
<Text/>
<SitName/>
<TouchName/>
<LinkNum>252</LinkNum>
<ClickAction>0</ClickAction>
<Shape>
<ProfileCurve>0</ProfileCurve>
<TextureEntry>Vw3dpvgTRUOiIUOGsnpWlAB/f38AAAAAgL8AAACAPwAAAAAAAAAF4ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</TextureEntry>
<ExtraParams>AA==</ExtraParams>
<PathBegin>0</PathBegin>
<PathCurve>32</PathCurve>
<PathEnd>0</PathEnd>
<PathRadiusOffset>0</PathRadiusOffset>
<PathRevolutions>0</PathRevolutions>
<PathScaleX>100</PathScaleX>
<PathScaleY>150</PathScaleY>
<PathShearX>0</PathShearX>
<PathShearY>0</PathShearY>
<PathSkew>0</PathSkew>
<PathTaperX>0</PathTaperX>
<PathTaperY>0</PathTaperY>
<PathTwist>0</PathTwist>
<PathTwistBegin>0</PathTwistBegin>
<PCode>9</PCode>
<ProfileBegin>0</ProfileBegin>
<ProfileEnd>0</ProfileEnd>
<ProfileHollow>0</ProfileHollow>
<State>9</State>
<LastAttachPoint>0</LastAttachPoint>
<ProfileShape>Circle</ProfileShape>
<HollowShape>Same</HollowShape>
<SculptTexture><Guid>00000000-0000-0000-0000-000000000000</Guid></SculptTexture>
<SculptType>0</SculptType>
<FlexiSoftness>0</FlexiSoftness>
<FlexiTension>0</FlexiTension>
<FlexiDrag>0</FlexiDrag>
<FlexiGravity>0</FlexiGravity>
<FlexiWind>0</FlexiWind>
<FlexiForceX>0</FlexiForceX>
<FlexiForceY>0</FlexiForceY>
<FlexiForceZ>0</FlexiForceZ>
<LightColorR>0</LightColorR>
<LightColorG>0</LightColorG>
<LightColorB>0</LightColorB>
<LightColorA>1</LightColorA>
<LightRadius>0</LightRadius>
<LightCutoff>0</LightCutoff>
<LightFalloff>0</LightFalloff>
<LightIntensity>1</LightIntensity>
<FlexiEntry>false</FlexiEntry>
<LightEntry>false</LightEntry>
<SculptEntry>false</SculptEntry>
</Shape>
<Scale><X>0.03574385</X><Y>0.05958032</Y><Z>0.04764182</Z></Scale>
<SitTargetOrientation><X>0</X><Y>0</Y><Z>0</Z><W>1</W></SitTargetOrientation>
<SitTargetPosition><X>0</X><Y>0</Y><Z>0</Z></SitTargetPosition>
<SitTargetPositionLL><X>0</X><Y>0</Y><Z>0</Z></SitTargetPositionLL>
<SitTargetOrientationLL><X>0</X><Y>0</Y><Z>0</Z><W>1</W></SitTargetOrientationLL>
<ParentID>1154704499</ParentID>
<CreationDate>1256611042</CreationDate>
<Category>0</Category>
<SalePrice>10</SalePrice>
<ObjectSaleType>0</ObjectSaleType>
<OwnershipCost>0</OwnershipCost>
<GroupID><Guid>00000000-0000-0000-0000-000000000000</Guid></GroupID>
<OwnerID><Guid>7b2022f0-5f19-488c-b7e5-829d8f96b448</Guid></OwnerID>
<LastOwnerID><Guid>7b2022f0-5f19-488c-b7e5-829d8f96b448</Guid></LastOwnerID>
<BaseMask>647168</BaseMask>
<OwnerMask>647168</OwnerMask>
<GroupMask>0</GroupMask>
<EveryoneMask>0</EveryoneMask>
<NextOwnerMask>581632</NextOwnerMask>
<Flags>None</Flags>
<CollisionSound><Guid>00000000-0000-0000-0000-000000000000</Guid></CollisionSound>
<CollisionSoundVolume>0</CollisionSoundVolume>
<AttachedPos><X>0</X><Y>0</Y><Z>0</Z></AttachedPos>
<TextureAnimation/>
<ParticleSystem/>
<PayPrice0>-2</PayPrice0>
<PayPrice1>-2</PayPrice1>
<PayPrice2>-2</PayPrice2>
<PayPrice3>-2</PayPrice3>
<PayPrice4>-2</PayPrice4>
</SceneObjectPart>
</Part>
</OtherParts>
</SceneObjectGroup>";
private const string ObjectWithBadFloatsXml = @"
<SceneObjectGroup> <SceneObjectGroup>
<RootPart> <RootPart>
<SceneObjectPart xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""> <SceneObjectPart xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
@ -270,7 +494,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
<OtherParts /> <OtherParts />
</SceneObjectGroup>"; </SceneObjectGroup>";
private string xml2 = @" private const string ObjectWithNoPartsXml2 = @"
<SceneObjectGroup> <SceneObjectGroup>
<SceneObjectPart xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""> <SceneObjectPart xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<CreatorID><UUID>b46ef588-411e-4a8b-a284-d7dcfe8e74ef</UUID></CreatorID> <CreatorID><UUID>b46ef588-411e-4a8b-a284-d7dcfe8e74ef</UUID></CreatorID>
@ -377,12 +601,12 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
} }
[Test] [Test]
public void TestDeserializeXml() public void TestDeserializeXmlObjectWithNoOtherParts()
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
//log4net.Config.XmlConfigurator.Configure(); TestHelpers.EnableLogging();
SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(xml); SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(ObjectWithNoOtherPartsXml);
SceneObjectPart rootPart = so.RootPart; SceneObjectPart rootPart = so.RootPart;
Assert.That(rootPart.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790"))); Assert.That(rootPart.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790")));
@ -394,13 +618,52 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
// TODO: Check other properties // TODO: Check other properties
} }
[Test]
public void TestDeserializeXmlObjectWithOtherParts()
{
TestHelpers.InMethod();
TestHelpers.EnableLogging();
SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(ObjectWithOtherPartsXml);
SceneObjectPart[] parts = so.Parts;
Assert.AreEqual(3, so.Parts.Length);
{
SceneObjectPart part = parts[0];
Assert.That(part.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790")));
Assert.That(part.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d")));
Assert.That(part.Name, Is.EqualTo("PrimMyRide"));
OSDMap store = part.DynAttrs.GetStore("MyNamespace", "MyStore");
Assert.AreEqual(42, store["the answer"].AsInteger());
}
{
SceneObjectPart part = parts[1];
Assert.That(part.UUID, Is.EqualTo(new UUID("9958feb1-02a6-49e4-a4ce-eba6f578ee13")));
Assert.That(part.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d")));
Assert.That(part.Name, Is.EqualTo("Alien Head 1"));
}
{
SceneObjectPart part = parts[2];
Assert.That(part.UUID, Is.EqualTo(new UUID("674b6b86-f5aa-439a-8e00-0d75bc08c80a")));
Assert.That(part.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d")));
Assert.That(part.Name, Is.EqualTo("Alien Head 2"));
}
// TODO: Check other properties
}
[Test] [Test]
public void TestDeserializeBadFloatsXml() public void TestDeserializeBadFloatsXml()
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(badFloatsXml); SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(ObjectWithBadFloatsXml);
SceneObjectPart rootPart = so.RootPart; SceneObjectPart rootPart = so.RootPart;
Assert.That(rootPart.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790"))); Assert.That(rootPart.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790")));
@ -517,7 +780,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
TestHelpers.InMethod(); TestHelpers.InMethod();
//log4net.Config.XmlConfigurator.Configure(); //log4net.Config.XmlConfigurator.Configure();
SceneObjectGroup so = m_serialiserModule.DeserializeGroupFromXml2(xml2); SceneObjectGroup so = m_serialiserModule.DeserializeGroupFromXml2(ObjectWithNoPartsXml2);
SceneObjectPart rootPart = so.RootPart; SceneObjectPart rootPart = so.RootPart;
Assert.That(rootPart.UUID, Is.EqualTo(new UUID("9be68fdd-f740-4a0f-9675-dfbbb536b946"))); Assert.That(rootPart.UUID, Is.EqualTo(new UUID("9be68fdd-f740-4a0f-9675-dfbbb536b946")));

View File

@ -1029,7 +1029,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
block.X = (ushort)minX; block.X = (ushort)minX;
block.Y = (ushort)minY; block.Y = (ushort)minY;
block.Access = (byte)SimAccess.Down; // means 'simulator is offline' block.Access = (byte)SimAccess.Down; // means 'simulator is offline'
// block.Access = (byte)SimAccess.NonExistant; // block.Access = (byte)SimAccess.NonExistent;
response.Add(block); response.Add(block);
} }
// The lower 16 bits are an unsigned int16 // The lower 16 bits are an unsigned int16
@ -1121,32 +1121,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
block.SizeX = (ushort)r.RegionSizeX; block.SizeX = (ushort)r.RegionSizeX;
block.SizeY = (ushort)r.RegionSizeY; block.SizeY = (ushort)r.RegionSizeY;
blocks.Add(block); blocks.Add(block);
// If these are larger than legacy regions, create fake map entries for the covered
// regions. The map system only does legacy sized regions so we have to fake map
// entries for all the covered regions.
if (r.RegionSizeX > Constants.RegionSize || r.RegionSizeY > Constants.RegionSize)
{
for (int x = 0; x < r.RegionSizeX / Constants.RegionSize; x++)
{
for (int y = 0; y < r.RegionSizeY / Constants.RegionSize; y++)
{
if (x == 0 && y == 0)
continue;
block = new MapBlockData
{
Access = r.Access,
MapImageId = r.TerrainImage,
Name = r.RegionName,
X = (ushort)((r.RegionLocX / Constants.RegionSize) + x),
Y = (ushort)((r.RegionLocY / Constants.RegionSize) + y),
SizeX = (ushort)r.RegionSizeX,
SizeY = (ushort)r.RegionSizeY
};
//Child piece, so ignore it
blocks.Add(block);
}
}
}
} }
return blocks; return blocks;
} }
@ -1171,7 +1145,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
if (myMapImageJPEG.Length == 0) if (myMapImageJPEG.Length == 0)
{ {
MemoryStream imgstream = new MemoryStream(); MemoryStream imgstream = null;
Bitmap mapTexture = new Bitmap(1,1); Bitmap mapTexture = new Bitmap(1,1);
ManagedImage managedImage; ManagedImage managedImage;
Image image = (Image)mapTexture; Image image = (Image)mapTexture;
@ -1218,12 +1192,9 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
image.Dispose(); image.Dispose();
if (imgstream != null) if (imgstream != null)
{
imgstream.Close();
imgstream.Dispose(); imgstream.Dispose();
} }
} }
}
else else
{ {
// Use cached version so we don't have to loose our mind // Use cached version so we don't have to loose our mind
@ -1467,7 +1438,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
public void GenerateMaptile() public void GenerateMaptile()
{ {
// Cannot create a map for a nonexistant heightmap // Cannot create a map for a nonexistent heightmap
if (m_scene.Heightmap == null) if (m_scene.Heightmap == null)
return; return;
@ -1578,12 +1549,20 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
private Byte[] GenerateOverlay() private Byte[] GenerateOverlay()
{ {
using (Bitmap overlay = new Bitmap(256, 256)) // These need to be ints for bitmap generation
int regionSizeX = (int)m_scene.RegionInfo.RegionSizeX;
int regionSizeY = (int)m_scene.RegionInfo.RegionSizeY;
int landTileSize = LandManagementModule.LandUnit;
int regionLandTilesX = regionSizeX / landTileSize;
int regionLandTilesY = regionSizeY / landTileSize;
using (Bitmap overlay = new Bitmap(regionSizeX, regionSizeY))
{ {
bool[,] saleBitmap = new bool[64, 64]; bool[,] saleBitmap = new bool[regionLandTilesX, regionLandTilesY];
for (int x = 0 ; x < 64 ; x++) for (int x = 0; x < regionLandTilesX; x++)
{ {
for (int y = 0 ; y < 64 ; y++) for (int y = 0; y < regionLandTilesY; y++)
saleBitmap[x, y] = false; saleBitmap[x, y] = false;
} }
@ -1596,8 +1575,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
using (Graphics g = Graphics.FromImage(overlay)) using (Graphics g = Graphics.FromImage(overlay))
{ {
using (SolidBrush transparent = new SolidBrush(background)) using (SolidBrush transparent = new SolidBrush(background))
g.FillRectangle(transparent, 0, 0, 256, 256); g.FillRectangle(transparent, 0, 0, regionSizeX, regionSizeY);
foreach (ILandObject land in parcels) foreach (ILandObject land in parcels)
{ {
@ -1620,12 +1598,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
using (SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9))) using (SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)))
{ {
for (int x = 0 ; x < 64 ; x++) for (int x = 0 ; x < regionLandTilesX ; x++)
{ {
for (int y = 0 ; y < 64 ; y++) for (int y = 0 ; y < regionLandTilesY ; y++)
{ {
if (saleBitmap[x, y]) if (saleBitmap[x, y])
g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4); g.FillRectangle(
yellow, x * landTileSize,
regionSizeX - landTileSize - (y * landTileSize),
landTileSize,
landTileSize);
} }
} }
} }

View File

@ -373,7 +373,8 @@ namespace OpenSim.Region.DataSnapshot
for (int i = 0; i < services.Length; i++) for (int i = 0; i < services.Length; i++)
{ {
string url = services[i].Trim(); string url = services[i].Trim();
RestClient cli = new RestClient(url); using (RestClient cli = new RestClient(url))
{
cli.AddQueryParameter("service", serviceName); cli.AddQueryParameter("service", serviceName);
cli.AddQueryParameter("host", m_hostname); cli.AddQueryParameter("host", m_hostname);
cli.AddQueryParameter("port", m_listener_port); cli.AddQueryParameter("port", m_listener_port);
@ -391,6 +392,7 @@ namespace OpenSim.Region.DataSnapshot
{ {
m_log.Warn("[DATASNAPSHOT]: Ignoring unknown exception " + e.ToString()); m_log.Warn("[DATASNAPSHOT]: Ignoring unknown exception " + e.ToString());
} }
byte[] response = new byte[1024]; byte[] response = new byte[1024];
// int n = 0; // int n = 0;
try try
@ -406,6 +408,7 @@ namespace OpenSim.Region.DataSnapshot
// string responseStr = Util.UTF8.GetString(response); // string responseStr = Util.UTF8.GetString(response);
m_log.Info("[DATASNAPSHOT]: data service " + url + " notified. Secret: " + m_Secret); m_log.Info("[DATASNAPSHOT]: data service " + url + " notified. Secret: " + m_Secret);
} }
}
} }
#endregion #endregion

View File

@ -1,4 +1,4 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
@ -113,9 +113,11 @@ namespace OpenSim.Region.Framework.Scenes.Animation
public byte[] ToBytes() public byte[] ToBytes()
{ {
byte[] outputbytes = new byte[0]; byte[] outputbytes;
BinaryWriter iostream = new BinaryWriter(new MemoryStream()); using (MemoryStream ms = new MemoryStream())
using (BinaryWriter iostream = new BinaryWriter(ms))
{
iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(unknown0))); iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(unknown0)));
iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(unknown1))); iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(unknown1)));
iostream.Write(BinBVHUtil.ES(Utils.IntToBytes(Priority))); iostream.Write(BinBVHUtil.ES(Utils.IntToBytes(Priority)));
@ -134,10 +136,11 @@ namespace OpenSim.Region.Framework.Scenes.Animation
Joints[i].WriteBytesToStream(iostream, InPoint, OutPoint); Joints[i].WriteBytesToStream(iostream, InPoint, OutPoint);
} }
iostream.Write(BinBVHUtil.ES(Utils.IntToBytes(0))); iostream.Write(BinBVHUtil.ES(Utils.IntToBytes(0)));
MemoryStream ms = (MemoryStream)iostream.BaseStream;
outputbytes = ms.ToArray(); using (MemoryStream ms2 = (MemoryStream)iostream.BaseStream)
ms.Close(); outputbytes = ms2.ToArray();
iostream.Close(); }
return outputbytes; return outputbytes;
} }

View File

@ -308,10 +308,11 @@ namespace OpenSim.Region.Framework.Scenes
try try
{ {
MemoryStream ms = new MemoryStream(data); using (MemoryStream ms = new MemoryStream(data))
{
BinaryFormatter fmt = new BinaryFormatter(); BinaryFormatter fmt = new BinaryFormatter();
newMotion = (KeyframeMotion)fmt.Deserialize(ms); newMotion = (KeyframeMotion)fmt.Deserialize(ms);
}
newMotion.m_group = grp; newMotion.m_group = grp;
@ -764,13 +765,15 @@ namespace OpenSim.Region.Framework.Scenes
public Byte[] Serialize() public Byte[] Serialize()
{ {
StopTimer(); StopTimer();
MemoryStream ms = new MemoryStream();
BinaryFormatter fmt = new BinaryFormatter();
SceneObjectGroup tmp = m_group; SceneObjectGroup tmp = m_group;
m_group = null; m_group = null;
if (!m_selected && tmp != null) if (!m_selected && tmp != null)
m_serializedPosition = tmp.AbsolutePosition; m_serializedPosition = tmp.AbsolutePosition;
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter fmt = new BinaryFormatter();
fmt.Serialize(ms, this); fmt.Serialize(ms, this);
m_group = tmp; m_group = tmp;
if (m_running && !m_waitingCrossing) if (m_running && !m_waitingCrossing)
@ -778,6 +781,7 @@ namespace OpenSim.Region.Framework.Scenes
return ms.ToArray(); return ms.ToArray();
} }
}
public void StartCrossingCheck() public void StartCrossingCheck()
{ {

View File

@ -30,6 +30,7 @@ using System.Collections.Generic;
using System.Collections; using System.Collections;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading;
using System.Timers; using System.Timers;
using System.Xml; using System.Xml;
using OpenMetaverse; using OpenMetaverse;
@ -1226,15 +1227,20 @@ namespace OpenSim.Region.Framework.Scenes
agentItem.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move); agentItem.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move);
if (taskItem.InvType == (int)InventoryType.Object) if (taskItem.InvType == (int)InventoryType.Object)
{ {
uint perms = taskItem.CurrentPermissions; // Bake the new base permissions from folded permissions
// The folded perms are in the lowest 3 bits of the current perms
// We use base permissions here to avoid baking the "Locked" status
// into the item as it is passed.
uint perms = taskItem.BasePermissions & taskItem.NextPermissions;
PermissionsUtil.ApplyFoldedPermissions(taskItem.CurrentPermissions, ref perms); PermissionsUtil.ApplyFoldedPermissions(taskItem.CurrentPermissions, ref perms);
// Avoid the "lock trap" - move must always be enabled but the above may remove it
// Add it back here.
agentItem.BasePermissions = perms | (uint)PermissionMask.Move; agentItem.BasePermissions = perms | (uint)PermissionMask.Move;
// Newly given items cannot be "locked" on rez. Make sure by
// setting current equal to base.
}
agentItem.CurrentPermissions = agentItem.BasePermissions; agentItem.CurrentPermissions = agentItem.BasePermissions;
}
else
{
agentItem.CurrentPermissions = agentItem.BasePermissions & taskItem.CurrentPermissions;
}
agentItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; agentItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
agentItem.NextPermissions = taskItem.NextPermissions; agentItem.NextPermissions = taskItem.NextPermissions;
@ -1934,8 +1940,11 @@ namespace OpenSim.Region.Framework.Scenes
/// Rez a script into a prim's inventory from another prim /// Rez a script into a prim's inventory from another prim
/// </summary> /// </summary>
/// <param name="remoteClient"></param> /// <param name="remoteClient"></param>
/// <param name="itemID"> </param> /// <param name="srcPart"> </param>
/// <param name="localID"></param> /// <param name="destId"> </param>
/// <param name="pin"></param>
/// <param name="running"></param>
/// <param name="start_param"></param>
public void RezScriptFromPrim(UUID srcId, SceneObjectPart srcPart, UUID destId, int pin, int running, int start_param) public void RezScriptFromPrim(UUID srcId, SceneObjectPart srcPart, UUID destId, int pin, int running, int start_param)
{ {
TaskInventoryItem srcTaskItem = srcPart.Inventory.GetInventoryItem(srcId); TaskInventoryItem srcTaskItem = srcPart.Inventory.GetInventoryItem(srcId);
@ -1955,9 +1964,8 @@ namespace OpenSim.Region.Framework.Scenes
if (destPart == null) if (destPart == null)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[PRIM INVENTORY]: " + "[PRIM INVENTORY]: Could not find part {0} to insert script item {1} from {2} {3} in {4}",
"Could not find script for ID {0}", destId, srcId, srcPart.Name, srcPart.UUID, Name);
destId);
return; return;
} }
@ -1968,12 +1976,14 @@ namespace OpenSim.Region.Framework.Scenes
if ((destPart.GroupID == UUID.Zero) || (destPart.GroupID != srcPart.GroupID) || if ((destPart.GroupID == UUID.Zero) || (destPart.GroupID != srcPart.GroupID) ||
((destPart.GroupMask & (uint)PermissionMask.Modify) == 0)) ((destPart.GroupMask & (uint)PermissionMask.Modify) == 0))
return; return;
} else { }
else
{
if ((destPart.OwnerMask & (uint)PermissionMask.Modify) == 0) if ((destPart.OwnerMask & (uint)PermissionMask.Modify) == 0)
return; return;
} }
if (destPart.ScriptAccessPin != pin) if (destPart.ScriptAccessPin == 0 || destPart.ScriptAccessPin != pin)
{ {
m_log.WarnFormat( m_log.WarnFormat(
"[PRIM INVENTORY]: " + "[PRIM INVENTORY]: " +
@ -2192,34 +2202,47 @@ namespace OpenSim.Region.Framework.Scenes
/// Returns one object if the asset is a regular object, and multiple objects for a coalesced object. /// Returns one object if the asset is a regular object, and multiple objects for a coalesced object.
/// </remarks> /// </remarks>
/// <param name="assetData">Asset data</param> /// <param name="assetData">Asset data</param>
/// <param name="attachment">Whether the item is an attachment</param> /// <param name="isAttachment">True if the object is an attachment.</param>
/// <param name="objlist">The objects included in the asset</param> /// <param name="objlist">The objects included in the asset</param>
/// <param name="veclist">Relative positions of the objects</param> /// <param name="veclist">Relative positions of the objects</param>
/// <param name="bbox">Bounding box of all the objects</param> /// <param name="bbox">Bounding box of all the objects</param>
/// <param name="offsetHeight">Offset in the Z axis from the centre of the bounding box /// <param name="offsetHeight">Offset in the Z axis from the centre of the bounding box
/// to the centre of the root prim (relevant only when returning a single object)</param> /// to the centre of the root prim (relevant only when returning a single object)</param>
/// <returns>true = returning a single object; false = multiple objects</returns> /// <returns>
public bool GetObjectsToRez(byte[] assetData, bool attachment, out List<SceneObjectGroup> objlist, out List<Vector3> veclist, /// true if returning a single object or deserialization fails, false if returning the coalesced
/// list of objects
/// </returns>
public bool GetObjectsToRez(
byte[] assetData, bool isAttachment, out List<SceneObjectGroup> objlist, out List<Vector3> veclist,
out Vector3 bbox, out float offsetHeight) out Vector3 bbox, out float offsetHeight)
{ {
objlist = new List<SceneObjectGroup>(); objlist = new List<SceneObjectGroup>();
veclist = new List<Vector3>(); veclist = new List<Vector3>();
XmlDocument doc = new XmlDocument();
string xmlData = Utils.BytesToString(assetData); string xmlData = Utils.BytesToString(assetData);
doc.LoadXml(xmlData);
XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
if (e == null || attachment) // Single try
{ {
SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null))
{
using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment }))
{
reader.Read();
bool isSingleObject = reader.Name != "CoalescedObject";
if (isSingleObject || isAttachment)
{
SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(reader);
objlist.Add(g); objlist.Add(g);
veclist.Add(new Vector3(0, 0, 0)); veclist.Add(Vector3.Zero);
bbox = g.GetAxisAlignedBoundingBox(out offsetHeight); bbox = g.GetAxisAlignedBoundingBox(out offsetHeight);
return true; return true;
} }
else else
{ {
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlData);
XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
XmlElement coll = (XmlElement)e; XmlElement coll = (XmlElement)e;
float bx = Convert.ToSingle(coll.GetAttribute("x")); float bx = Convert.ToSingle(coll.GetAttribute("x"));
float by = Convert.ToSingle(coll.GetAttribute("y")); float by = Convert.ToSingle(coll.GetAttribute("y"));
@ -2243,10 +2266,24 @@ namespace OpenSim.Region.Framework.Scenes
float z = Convert.ToSingle(rawZ); float z = Convert.ToSingle(rawZ);
veclist.Add(new Vector3(x, y, z)); veclist.Add(new Vector3(x, y, z));
} }
}
return false; return false;
} }
}
}
}
catch (Exception e)
{
m_log.Error(
"[AGENT INVENTORY]: Deserialization of xml failed when looking for CoalescedObject tag. Exception ",
e);
bbox = Vector3.Zero;
offsetHeight = 0;
}
return true;
}
/// <summary> /// <summary>
/// Event Handler Rez an object into a scene /// Event Handler Rez an object into a scene

View File

@ -103,7 +103,29 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary> /// <summary>
/// If false then physical objects are disabled, though collisions will continue as normal. /// If false then physical objects are disabled, though collisions will continue as normal.
/// </summary> /// </summary>
public bool PhysicsEnabled { get; set; } public bool PhysicsEnabled
{
get
{
return m_physicsEnabled;
}
set
{
m_physicsEnabled = value;
if (PhysicsScene != null)
{
IPhysicsParameters physScene = PhysicsScene as IPhysicsParameters;
if (physScene != null)
physScene.SetPhysicsParameter(
"Active", m_physicsEnabled.ToString(), PhysParameterEntry.APPLY_TO_NONE);
}
}
}
private bool m_physicsEnabled;
/// <summary> /// <summary>
/// If false then scripts are not enabled on the smiulator /// If false then scripts are not enabled on the smiulator
@ -192,7 +214,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary> /// <summary>
/// Maximum value of the size of a physical prim in each axis /// Maximum value of the size of a physical prim in each axis
/// </summary> /// </summary>
public float m_maxPhys = 10; public float m_maxPhys = 64;
/// <summary> /// <summary>
/// Max prims an object will hold /// Max prims an object will hold
@ -201,7 +223,13 @@ namespace OpenSim.Region.Framework.Scenes
public bool m_clampPrimSize; public bool m_clampPrimSize;
public bool m_trustBinaries; public bool m_trustBinaries;
public bool m_allowScriptCrossings; public bool m_allowScriptCrossings = true;
/// <summary>
/// Can avatars cross from and to this region?
/// </summary>
public bool AllowAvatarCrossing { get; set; }
public bool m_useFlySlow; public bool m_useFlySlow;
public bool m_useTrashOnDelete = true; public bool m_useTrashOnDelete = true;
@ -210,6 +238,31 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
public bool SendPeriodicAppearanceUpdates { get; set; } public bool SendPeriodicAppearanceUpdates { get; set; }
/// <summary>
/// How much a root agent has to change position before updates are sent to viewers.
/// </summary>
public float RootPositionUpdateTolerance { get; set; }
/// <summary>
/// How much a root agent has to rotate before updates are sent to viewers.
/// </summary>
public float RootRotationUpdateTolerance { get; set; }
/// <summary>
/// How much a root agent has to change velocity before updates are sent to viewers.
/// </summary>
public float RootVelocityUpdateTolerance { get; set; }
/// <summary>
/// If greater than 1, we only send terse updates to other root agents on every n updates.
/// </summary>
public int RootTerseUpdatePeriod { get; set; }
/// <summary>
/// If greater than 1, we only send terse updates to child agents on every n updates.
/// </summary>
public int ChildTerseUpdatePeriod { get; set; }
protected float m_defaultDrawDistance = 255.0f; protected float m_defaultDrawDistance = 255.0f;
public float DefaultDrawDistance public float DefaultDrawDistance
{ {
@ -409,12 +462,6 @@ namespace OpenSim.Region.Framework.Scenes
// private int m_lastUpdate; // private int m_lastUpdate;
// private bool m_firstHeartbeat = true; // private bool m_firstHeartbeat = true;
private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time;
private bool m_reprioritizationEnabled = true;
private double m_reprioritizationInterval = 5000.0;
private double m_rootReprioritizationDistance = 10.0;
private double m_childReprioritizationDistance = 20.0;
private Timer m_mapGenerationTimer = new Timer(); private Timer m_mapGenerationTimer = new Timer();
private bool m_generateMaptiles; private bool m_generateMaptiles;
@ -646,11 +693,11 @@ namespace OpenSim.Region.Framework.Scenes
public int MonitorLandTime { get { return landMS; } } public int MonitorLandTime { get { return landMS; } }
public int MonitorLastFrameTick { get { return m_lastFrameTick; } } public int MonitorLastFrameTick { get { return m_lastFrameTick; } }
public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } } public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get; set; }
public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } } public bool IsReprioritizationEnabled { get; set; }
public double ReprioritizationInterval { get { return m_reprioritizationInterval; } } public double ReprioritizationInterval { get; set; }
public double RootReprioritizationDistance { get { return m_rootReprioritizationDistance; } } public double RootReprioritizationDistance { get; set; }
public double ChildReprioritizationDistance { get { return m_childReprioritizationDistance; } } public double ChildReprioritizationDistance { get; set; }
public AgentCircuitManager AuthenticateHandler public AgentCircuitManager AuthenticateHandler
{ {
@ -713,11 +760,11 @@ namespace OpenSim.Region.Framework.Scenes
#region Constructors #region Constructors
public Scene(RegionInfo regInfo, AgentCircuitManager authen, public Scene(RegionInfo regInfo, AgentCircuitManager authen, PhysicsScene physicsScene,
SceneCommunicationService sceneGridService, SceneCommunicationService sceneGridService,
ISimulationDataService simDataService, IEstateDataService estateDataService, ISimulationDataService simDataService, IEstateDataService estateDataService,
IConfigSource config, string simulatorVersion) IConfigSource config, string simulatorVersion)
: this(regInfo) : this(regInfo, physicsScene)
{ {
m_config = config; m_config = config;
MinFrameTime = 0.089f; MinFrameTime = 0.089f;
@ -790,21 +837,6 @@ namespace OpenSim.Region.Framework.Scenes
EventManager.OnLandObjectRemoved += EventManager.OnLandObjectRemoved +=
new EventManager.LandObjectRemoved(simDataService.RemoveLandObject); new EventManager.LandObjectRemoved(simDataService.RemoveLandObject);
m_sceneGraph = new SceneGraph(this);
// If the scene graph has an Unrecoverable error, restart this sim.
// Currently the only thing that causes it to happen is two kinds of specific
// Physics based crashes.
//
// Out of memory
// Operating system has killed the plugin
m_sceneGraph.UnRecoverableError
+= () =>
{
m_log.ErrorFormat("[SCENE]: Restarting region {0} due to unrecoverable physics crash", Name);
RestartNow();
};
RegisterDefaultSceneEvents(); RegisterDefaultSceneEvents();
// XXX: Don't set the public property since we don't want to activate here. This needs to be handled // XXX: Don't set the public property since we don't want to activate here. This needs to be handled
@ -982,6 +1014,12 @@ namespace OpenSim.Region.Framework.Scenes
#endregion Region Config #endregion Region Config
IConfig entityTransferConfig = m_config.Configs["EntityTransfer"];
if (entityTransferConfig != null)
{
AllowAvatarCrossing = entityTransferConfig.GetBoolean("AllowAvatarCrossing", AllowAvatarCrossing);
}
#region Interest Management #region Interest Management
IConfig interestConfig = m_config.Configs["InterestManagement"]; IConfig interestConfig = m_config.Configs["InterestManagement"];
@ -991,21 +1029,35 @@ namespace OpenSim.Region.Framework.Scenes
try try
{ {
m_priorityScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true); UpdatePrioritizationScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true);
} }
catch (Exception) catch (Exception)
{ {
m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time"); m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time");
m_priorityScheme = UpdatePrioritizationSchemes.Time; UpdatePrioritizationScheme = UpdatePrioritizationSchemes.Time;
} }
m_reprioritizationEnabled = interestConfig.GetBoolean("ReprioritizationEnabled", true); IsReprioritizationEnabled
m_reprioritizationInterval = interestConfig.GetDouble("ReprioritizationInterval", 5000.0); = interestConfig.GetBoolean("ReprioritizationEnabled", IsReprioritizationEnabled);
m_rootReprioritizationDistance = interestConfig.GetDouble("RootReprioritizationDistance", 10.0); ReprioritizationInterval
m_childReprioritizationDistance = interestConfig.GetDouble("ChildReprioritizationDistance", 20.0); = interestConfig.GetDouble("ReprioritizationInterval", ReprioritizationInterval);
RootReprioritizationDistance
= interestConfig.GetDouble("RootReprioritizationDistance", RootReprioritizationDistance);
ChildReprioritizationDistance
= interestConfig.GetDouble("ChildReprioritizationDistance", ChildReprioritizationDistance);
RootTerseUpdatePeriod = interestConfig.GetInt("RootTerseUpdatePeriod", RootTerseUpdatePeriod);
ChildTerseUpdatePeriod = interestConfig.GetInt("ChildTerseUpdatePeriod", ChildTerseUpdatePeriod);
RootPositionUpdateTolerance
= interestConfig.GetFloat("RootPositionUpdateTolerance", RootPositionUpdateTolerance);
RootRotationUpdateTolerance
= interestConfig.GetFloat("RootRotationUpdateTolerance", RootRotationUpdateTolerance);
RootVelocityUpdateTolerance
= interestConfig.GetFloat("RootVelocityUpdateTolerance", RootVelocityUpdateTolerance);
} }
m_log.DebugFormat("[SCENE]: Using the {0} prioritization scheme", m_priorityScheme); m_log.DebugFormat("[SCENE]: Using the {0} prioritization scheme", UpdatePrioritizationScheme);
#endregion Interest Management #endregion Interest Management
@ -1014,15 +1066,43 @@ namespace OpenSim.Region.Framework.Scenes
StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
} }
public Scene(RegionInfo regInfo) : base(regInfo) public Scene(RegionInfo regInfo, PhysicsScene physicsScene) : base(regInfo)
{ {
m_sceneGraph = new SceneGraph(this);
m_sceneGraph.PhysicsScene = physicsScene;
// If the scene graph has an Unrecoverable error, restart this sim.
// Currently the only thing that causes it to happen is two kinds of specific
// Physics based crashes.
//
// Out of memory
// Operating system has killed the plugin
m_sceneGraph.UnRecoverableError
+= () =>
{
m_log.ErrorFormat("[SCENE]: Restarting region {0} due to unrecoverable physics crash", Name);
RestartNow();
};
PhysicalPrims = true; PhysicalPrims = true;
CollidablePrims = true; CollidablePrims = true;
PhysicsEnabled = true; PhysicsEnabled = true;
AllowAvatarCrossing = true;
PeriodicBackup = true; PeriodicBackup = true;
UseBackup = true; UseBackup = true;
IsReprioritizationEnabled = true;
UpdatePrioritizationScheme = UpdatePrioritizationSchemes.Time;
ReprioritizationInterval = 5000;
RootRotationUpdateTolerance = 0.1f;
RootVelocityUpdateTolerance = 0.001f;
RootPositionUpdateTolerance = 0.05f;
RootReprioritizationDistance = 10.0;
ChildReprioritizationDistance = 20.0;
m_eventManager = new EventManager(); m_eventManager = new EventManager();
m_permissions = new ScenePermissions(this); m_permissions = new ScenePermissions(this);
@ -1069,18 +1149,22 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns>True after all operations complete, throws exceptions otherwise.</returns> /// <returns>True after all operations complete, throws exceptions otherwise.</returns>
public override void OtherRegionUp(GridRegion otherRegion) public override void OtherRegionUp(GridRegion otherRegion)
{ {
uint xcell = Util.WorldToRegionLoc((uint)otherRegion.RegionLocX);
uint ycell = Util.WorldToRegionLoc((uint)otherRegion.RegionLocY);
//m_log.InfoFormat("[SCENE]: (on region {0}): Region {1} up in coords {2}-{3}",
// RegionInfo.RegionName, otherRegion.RegionName, xcell, ycell);
if (RegionInfo.RegionHandle != otherRegion.RegionHandle) if (RegionInfo.RegionHandle != otherRegion.RegionHandle)
{ {
// If these are cast to INT because long + negative values + abs returns invalid data //// If these are cast to INT because long + negative values + abs returns invalid data
int resultX = Math.Abs((int)xcell - (int)RegionInfo.RegionLocX); //int resultX = Math.Abs((int)xcell - (int)RegionInfo.RegionLocX);
int resultY = Math.Abs((int)ycell - (int)RegionInfo.RegionLocY); //int resultY = Math.Abs((int)ycell - (int)RegionInfo.RegionLocY);
if (resultX <= 1 && resultY <= 1) //if (resultX <= 1 && resultY <= 1)
float dist = (float)Math.Max(DefaultDrawDistance,
(float)Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY));
uint newRegionX, newRegionY, thisRegionX, thisRegionY;
Util.RegionHandleToRegionLoc(otherRegion.RegionHandle, out newRegionX, out newRegionY);
Util.RegionHandleToRegionLoc(RegionInfo.RegionHandle, out thisRegionX, out thisRegionY);
//m_log.InfoFormat("[SCENE]: (on region {0}): Region {1} up in coords {2}-{3}",
// RegionInfo.RegionName, otherRegion.RegionName, newRegionX, newRegionY);
if (!Util.IsOutsideView(dist, thisRegionX, newRegionX, thisRegionY, newRegionY))
{ {
// Let the grid service module know, so this can be cached // Let the grid service module know, so this can be cached
m_eventManager.TriggerOnRegionUp(otherRegion); m_eventManager.TriggerOnRegionUp(otherRegion);
@ -1894,6 +1978,7 @@ namespace OpenSim.Region.Framework.Scenes
RegionInfo.RegionID, RegionInfo.RegionID,
RegionInfo.RegionLocX, RegionInfo.RegionLocY, RegionInfo.RegionLocX, RegionInfo.RegionLocY,
RegionInfo.RegionSizeX, RegionInfo.RegionSizeY); RegionInfo.RegionSizeX, RegionInfo.RegionSizeY);
if (error != String.Empty) if (error != String.Empty)
throw new Exception(error); throw new Exception(error);
} }
@ -2002,8 +2087,8 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart target = GetSceneObjectPart(RayTargetID); SceneObjectPart target = GetSceneObjectPart(RayTargetID);
Vector3 direction = Vector3.Normalize(RayEnd - RayStart); Vector3 direction = Vector3.Normalize(RayEnd - RayStart);
Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z); Vector3 AXOrigin = RayStart;
Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z); Vector3 AXdirection = direction;
if (target != null) if (target != null)
{ {
@ -2025,13 +2110,13 @@ namespace OpenSim.Region.Framework.Scenes
// If we hit something // If we hit something
if (ei.HitTF) if (ei.HitTF)
{ {
Vector3 scaleComponent = new Vector3(ei.AAfaceNormal.X, ei.AAfaceNormal.Y, ei.AAfaceNormal.Z); Vector3 scaleComponent = ei.AAfaceNormal;
if (scaleComponent.X != 0) ScaleOffset = scale.X; if (scaleComponent.X != 0) ScaleOffset = scale.X;
if (scaleComponent.Y != 0) ScaleOffset = scale.Y; if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
if (scaleComponent.Z != 0) ScaleOffset = scale.Z; if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
ScaleOffset = Math.Abs(ScaleOffset); ScaleOffset = Math.Abs(ScaleOffset);
Vector3 intersectionpoint = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); Vector3 intersectionpoint = ei.ipoint;
Vector3 normal = new Vector3(ei.normal.X, ei.normal.Y, ei.normal.Z); Vector3 normal = ei.normal;
// Set the position to the intersection point // Set the position to the intersection point
Vector3 offset = (normal * (ScaleOffset / 2f)); Vector3 offset = (normal * (ScaleOffset / 2f));
pos = (intersectionpoint + offset); pos = (intersectionpoint + offset);
@ -2056,8 +2141,9 @@ namespace OpenSim.Region.Framework.Scenes
if (ei.HitTF) if (ei.HitTF)
{ {
pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); pos = ei.ipoint;
} else }
else
{ {
// fall back to our stupid functionality // fall back to our stupid functionality
pos = RayEnd; pos = RayEnd;
@ -3110,8 +3196,8 @@ namespace OpenSim.Region.Framework.Scenes
if (target != null && target2 != null) if (target != null && target2 != null)
{ {
Vector3 direction = Vector3.Normalize(RayEnd - RayStart); Vector3 direction = Vector3.Normalize(RayEnd - RayStart);
Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z); Vector3 AXOrigin = RayStart;
Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z); Vector3 AXdirection = direction;
pos = target2.AbsolutePosition; pos = target2.AbsolutePosition;
//m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString()); //m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString());
@ -3132,13 +3218,13 @@ namespace OpenSim.Region.Framework.Scenes
if (ei.HitTF) if (ei.HitTF)
{ {
Vector3 scale = target.Scale; Vector3 scale = target.Scale;
Vector3 scaleComponent = new Vector3(ei.AAfaceNormal.X, ei.AAfaceNormal.Y, ei.AAfaceNormal.Z); Vector3 scaleComponent = ei.AAfaceNormal;
if (scaleComponent.X != 0) ScaleOffset = scale.X; if (scaleComponent.X != 0) ScaleOffset = scale.X;
if (scaleComponent.Y != 0) ScaleOffset = scale.Y; if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
if (scaleComponent.Z != 0) ScaleOffset = scale.Z; if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
ScaleOffset = Math.Abs(ScaleOffset); ScaleOffset = Math.Abs(ScaleOffset);
Vector3 intersectionpoint = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); Vector3 intersectionpoint = ei.ipoint;
Vector3 normal = new Vector3(ei.normal.X, ei.normal.Y, ei.normal.Z); Vector3 normal = ei.normal;
Vector3 offset = normal * (ScaleOffset / 2f); Vector3 offset = normal * (ScaleOffset / 2f);
pos = intersectionpoint + offset; pos = intersectionpoint + offset;
@ -3158,6 +3244,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
copy = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, Quaternion.Identity); copy = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, Quaternion.Identity);
} }
if (copy != null) if (copy != null)
EventManager.TriggerObjectAddedToScene(copy); EventManager.TriggerObjectAddedToScene(copy);
} }
@ -3214,10 +3301,6 @@ namespace OpenSim.Region.Framework.Scenes
return; return;
} }
else
{
m_authenticateHandler.RemoveCircuit(agentID);
}
// TODO: Can we now remove this lock? // TODO: Can we now remove this lock?
lock (acd) lock (acd)
@ -3233,6 +3316,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
m_authenticateHandler.RemoveCircuit(agentID);
return; return;
} }
@ -3310,6 +3394,7 @@ namespace OpenSim.Region.Framework.Scenes
// Always clean these structures up so that any failure above doesn't cause them to remain in the // Always clean these structures up so that any failure above doesn't cause them to remain in the
// scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
// the same cleanup exception continually. // the same cleanup exception continually.
m_authenticateHandler.RemoveCircuit(agentID);
m_sceneGraph.RemoveScenePresence(agentID); m_sceneGraph.RemoveScenePresence(agentID);
m_clientManager.Remove(agentID); m_clientManager.Remove(agentID);
@ -3462,7 +3547,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
foreach (string viewer in m_AllowedViewers) foreach (string viewer in m_AllowedViewers)
{ {
if (viewer == curViewer.Substring(0, viewer.Length).Trim().ToLower()) if (viewer == curViewer.Substring(0, Math.Min(viewer.Length, curViewer.Length)).Trim().ToLower())
{ {
ViewerDenied = false; ViewerDenied = false;
break; break;
@ -3479,7 +3564,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
foreach (string viewer in m_BannedViewers) foreach (string viewer in m_BannedViewers)
{ {
if (viewer == curViewer.Substring(0, viewer.Length).Trim().ToLower()) if (viewer == curViewer.Substring(0, Math.Min(viewer.Length, curViewer.Length)).Trim().ToLower())
{ {
ViewerDenied = true; ViewerDenied = true;
break; break;
@ -4992,7 +5077,7 @@ namespace OpenSim.Region.Framework.Scenes
case PhysicsJointType.Ball: case PhysicsJointType.Ball:
{ {
Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint); Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint);
Vector3 proxyPos = new Vector3(jointAnchor.X, jointAnchor.Y, jointAnchor.Z); Vector3 proxyPos = jointAnchor;
jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update
} }
break; break;
@ -5017,7 +5102,7 @@ namespace OpenSim.Region.Framework.Scenes
jointErrorMessage(joint, "joint.TrackedBodyName is null, joint " + joint.ObjectNameInScene); jointErrorMessage(joint, "joint.TrackedBodyName is null, joint " + joint.ObjectNameInScene);
} }
Vector3 proxyPos = new Vector3(jointAnchor.X, jointAnchor.Y, jointAnchor.Z); Vector3 proxyPos = jointAnchor;
Quaternion q = trackedBody.RotationOffset * joint.LocalRotation; Quaternion q = trackedBody.RotationOffset * joint.LocalRotation;
jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update
@ -5118,8 +5203,8 @@ namespace OpenSim.Region.Framework.Scenes
y = Heightmap.Height - 1; y = Heightmap.Height - 1;
Vector3 p0 = new Vector3(x, y, (float)Heightmap[(int)x, (int)y]); Vector3 p0 = new Vector3(x, y, (float)Heightmap[(int)x, (int)y]);
Vector3 p1 = new Vector3(p0); Vector3 p1 = p0;
Vector3 p2 = new Vector3(p0); Vector3 p2 = p0;
p1.X += 1.0f; p1.X += 1.0f;
if (p1.X < Heightmap.Width) if (p1.X < Heightmap.Width)
@ -5505,6 +5590,9 @@ namespace OpenSim.Region.Framework.Scenes
return true; return true;
} }
if (!AllowAvatarCrossing && !viaTeleport)
return false;
// FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check. // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check.
// However, the long term fix is to make sure root agent count is always accurate. // However, the long term fix is to make sure root agent count is always accurate.
m_sceneGraph.RecalculateStats(); m_sceneGraph.RecalculateStats();

View File

@ -154,6 +154,10 @@ namespace OpenSim.Region.Framework.Scenes
public void SendChildAgentDataUpdate(AgentPosition cAgentData, ScenePresence presence) public void SendChildAgentDataUpdate(AgentPosition cAgentData, ScenePresence presence)
{ {
// m_log.DebugFormat(
// "[SCENE COMMUNICATION SERVICE]: Sending child agent position updates for {0} in {1}",
// presence.Name, m_scene.Name);
// This assumes that we know what our neighbors are. // This assumes that we know what our neighbors are.
try try
{ {

View File

@ -1906,7 +1906,7 @@ namespace OpenSim.Region.Framework.Scenes
if (original == null) if (original == null)
{ {
m_log.WarnFormat( m_log.WarnFormat(
"[SCENEGRAPH]: Attempt to duplicate nonexistant prim id {0} by {1}", originalPrimID, AgentID); "[SCENEGRAPH]: Attempt to duplicate nonexistent prim id {0} by {1}", originalPrimID, AgentID);
return null; return null;
} }

View File

@ -568,7 +568,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val); m_log.DebugFormat("[SCENE OBJECT]: Not crossing avatar {0} to {1} because it's already in transit", av.Name, val);
} }
} }
@ -902,6 +902,34 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void LoadScriptState(XmlReader reader)
{
// m_log.DebugFormat("[SCENE OBJECT GROUP]: Looking for script state for {0} in {1}", Name);
while (reader.ReadToFollowing("SavedScriptState"))
{
// m_log.DebugFormat("[SCENE OBJECT GROUP]: Loading script state for {0}", Name);
if (m_savedScriptState == null)
m_savedScriptState = new Dictionary<UUID, string>();
string uuid = reader.GetAttribute("UUID");
if (uuid != null)
{
// m_log.DebugFormat("[SCENE OBJECT GROUP]: Found state for item ID {0} in object {1}", uuid, Name);
UUID itemid = new UUID(uuid);
if (itemid != UUID.Zero)
m_savedScriptState[itemid] = reader.ReadInnerXml();
}
else
{
m_log.WarnFormat("[SCENE OBJECT GROUP]: SavedScriptState element had no UUID in object {0}", Name);
}
}
}
/// <summary> /// <summary>
/// Hooks this object up to the backup event so that it is persisted to the database when the update thread executes. /// Hooks this object up to the backup event so that it is persisted to the database when the update thread executes.
/// </summary> /// </summary>

View File

@ -2044,7 +2044,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
/// <param name="xmlReader"></param> /// <param name="xmlReader"></param>
/// <returns></returns> /// <returns></returns>
public static SceneObjectPart FromXml(XmlTextReader xmlReader) public static SceneObjectPart FromXml(XmlReader xmlReader)
{ {
SceneObjectPart part = SceneObjectSerializer.Xml2ToSOP(xmlReader); SceneObjectPart part = SceneObjectSerializer.Xml2ToSOP(xmlReader);

View File

@ -870,8 +870,8 @@ namespace OpenSim.Region.Framework.Scenes
int type = m_items[itemID].InvType; int type = m_items[itemID].InvType;
if (type == 10) // Script if (type == 10) // Script
{ {
m_part.RemoveScriptEvents(itemID); // route it through here, to handle script cleanup tasks
m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); RemoveScriptInstance(itemID, false);
} }
m_items.Remove(itemID); m_items.Remove(itemID);
m_inventorySerial++; m_inventorySerial++;

View File

@ -286,6 +286,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public bool SentInitialDataToClient { get; private set; }
/// <summary> /// <summary>
/// Copy of the script states while the agent is in transit. This state may /// Copy of the script states while the agent is in transit. This state may
/// need to be placed back in case of transfer fail. /// need to be placed back in case of transfer fail.
@ -343,6 +345,12 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
private object m_originRegionIDAccessLock = new object(); private object m_originRegionIDAccessLock = new object();
/// <summary>
/// Triggered on entity transfer after to allow CompleteMovement() to proceed after we have received an
/// UpdateAgent from the originating region.ddkjjkj
/// </summary>
private AutoResetEvent m_updateAgentReceivedAfterTransferEvent = new AutoResetEvent(false);
/// <summary> /// <summary>
/// Used by the entity transfer module to signal when the presence should not be closed because a subsequent /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent
/// teleport is reusing the connection. /// teleport is reusing the connection.
@ -859,6 +867,11 @@ namespace OpenSim.Region.Framework.Scenes
get { return Util.GetViewerName(m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode)); } get { return Util.GetViewerName(m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode)); }
} }
/// <summary>
/// Count of how many terse updates we have sent out. It doesn't matter if this overflows.
/// </summary>
private int m_terseUpdateCount;
#endregion #endregion
#region Constructor(s) #region Constructor(s)
@ -1192,20 +1205,18 @@ namespace OpenSim.Region.Framework.Scenes
// and it has already rezzed the attachments and started their scripts. // and it has already rezzed the attachments and started their scripts.
// We do the following only for non-login agents, because their scripts // We do the following only for non-login agents, because their scripts
// haven't started yet. // haven't started yet.
if (PresenceType == PresenceType.Npc || (TeleportFlags & TeleportFlags.ViaLogin) != 0) if (PresenceType == PresenceType.Npc || IsRealLogin(m_teleportFlags))
{ {
// Viewers which have a current outfit folder will actually rez their own attachments. However, // Viewers which have a current outfit folder will actually rez their own attachments. However,
// viewers without (e.g. v1 viewers) will not, so we still need to make this call. // viewers without (e.g. v1 viewers) will not, so we still need to make this call.
if (Scene.AttachmentsModule != null) if (Scene.AttachmentsModule != null)
Util.FireAndForget(
o =>
{ {
// if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None) Util.FireAndForget(o =>
// System.Threading.Thread.Sleep(7000); {
Scene.AttachmentsModule.RezAttachments(this); Scene.AttachmentsModule.RezAttachments(this);
}); });
} }
}
else else
{ {
// We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
@ -1246,7 +1257,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
SendAvatarDataToAllAgents(); SendAvatarDataToAllClients();
// send the animations of the other presences to me // send the animations of the other presences to me
m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
@ -1266,6 +1277,11 @@ namespace OpenSim.Region.Framework.Scenes
return true; return true;
} }
private static bool IsRealLogin(TeleportFlags teleportFlags)
{
return ((teleportFlags & TeleportFlags.ViaLogin) != 0) && ((teleportFlags & TeleportFlags.ViaHGLogin) == 0);
}
/// <summary> /// <summary>
/// Force viewers to show the avatar's current name. /// Force viewers to show the avatar's current name.
/// </summary> /// </summary>
@ -1281,7 +1297,7 @@ namespace OpenSim.Region.Framework.Scenes
m_log.DebugFormat("[SCENE PRESENCE]: Forcing viewers to update the avatar name for " + Name); m_log.DebugFormat("[SCENE PRESENCE]: Forcing viewers to update the avatar name for " + Name);
UseFakeGroupTitle = true; UseFakeGroupTitle = true;
SendAvatarDataToAllAgents(false); SendAvatarDataToAllClients(false);
Util.FireAndForget(o => Util.FireAndForget(o =>
{ {
@ -1292,7 +1308,7 @@ namespace OpenSim.Region.Framework.Scenes
Thread.Sleep(5000); Thread.Sleep(5000);
UseFakeGroupTitle = false; UseFakeGroupTitle = false;
SendAvatarDataToAllAgents(false); SendAvatarDataToAllClients(false);
}); });
} }
@ -1640,7 +1656,6 @@ namespace OpenSim.Region.Framework.Scenes
PhysicsActor.Size = size; PhysicsActor.Size = size;
// PhysicsActor.setAvatarSize(size, feetoffset); // PhysicsActor.setAvatarSize(size, feetoffset);
} }
} }
private bool WaitForUpdateAgent(IClientAPI client) private bool WaitForUpdateAgent(IClientAPI client)
@ -1649,21 +1664,13 @@ namespace OpenSim.Region.Framework.Scenes
// (which triggers Scene.IncomingUpdateChildAgent(AgentData cAgentData) here in the destination, // (which triggers Scene.IncomingUpdateChildAgent(AgentData cAgentData) here in the destination,
// m_originRegionID is UUID.Zero; after, it's non-Zero. The CompleteMovement sequence initiated from the // m_originRegionID is UUID.Zero; after, it's non-Zero. The CompleteMovement sequence initiated from the
// viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero // viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero
int count = 50; m_updateAgentReceivedAfterTransferEvent.WaitOne(10000);
UUID originID;
UUID originID = UUID.Zero;
lock (m_originRegionIDAccessLock) lock (m_originRegionIDAccessLock)
originID = m_originRegionID; originID = m_originRegionID;
while (originID.Equals(UUID.Zero) && count-- > 0)
{
lock (m_originRegionIDAccessLock)
originID = m_originRegionID;
m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name);
Thread.Sleep(200);
}
if (originID.Equals(UUID.Zero)) if (originID.Equals(UUID.Zero))
{ {
// Movement into region will fail // Movement into region will fail
@ -1691,8 +1698,13 @@ namespace OpenSim.Region.Framework.Scenes
"[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
client.Name, Scene.Name, AbsolutePosition); client.Name, Scene.Name, AbsolutePosition);
bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); // Get this ahead of time because IsInTransit modifies 'm_AgentControlFlags'
IsInTransit = true;
try
{
// Make sure it's not a login agent. We don't want to wait for updates during login // Make sure it's not a login agent. We don't want to wait for updates during login
if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0) if (!(PresenceType == PresenceType.Npc || IsRealLogin(m_teleportFlags)))
{ {
// Let's wait until UpdateAgent (called by departing region) is done // Let's wait until UpdateAgent (called by departing region) is done
if (!WaitForUpdateAgent(client)) if (!WaitForUpdateAgent(client))
@ -1719,7 +1731,6 @@ namespace OpenSim.Region.Framework.Scenes
AbsolutePosition = pos; AbsolutePosition = pos;
} }
bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
if (!MakeRootAgent(AbsolutePosition, flying)) if (!MakeRootAgent(AbsolutePosition, flying))
{ {
m_log.DebugFormat( m_log.DebugFormat(
@ -1732,11 +1743,11 @@ namespace OpenSim.Region.Framework.Scenes
// Tell the client that we're totally ready // Tell the client that we're totally ready
ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
// Remember in HandleUseCircuitCode, we delayed this to here // Child agents send initial data up in LLUDPServer.HandleUseCircuitCode()
if (m_teleportFlags > 0) if (!SentInitialDataToClient)
SendInitialDataToMe(); SendInitialDataToClient();
// m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); // m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
if (!string.IsNullOrEmpty(m_callbackURI)) if (!string.IsNullOrEmpty(m_callbackURI))
{ {
@ -1745,26 +1756,21 @@ namespace OpenSim.Region.Framework.Scenes
// here until we know for sure that the agent is active in this region. Sending AgentMovementComplete // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete
// is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this
// region as the current region, meaning that a close sent before then will fail the teleport. // region as the current region, meaning that a close sent before then will fail the teleport.
// System.Threading.Thread.Sleep(2000); // System.Threading.Thread.Sleep(2000);
m_log.DebugFormat( m_log.DebugFormat(
"[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
client.Name, client.AgentId, m_callbackURI); client.Name, client.AgentId, m_callbackURI);
UUID originID; Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI);
lock (m_originRegionIDAccessLock)
originID = m_originRegionID;
Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI);
m_callbackURI = null; m_callbackURI = null;
} }
// else // else
// { // {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}", // "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}",
// client.Name, client.AgentId, m_scene.RegionInfo.RegionName); // client.Name, client.AgentId, m_scene.RegionInfo.RegionName);
// } // }
ValidateAndSendAppearanceAndAgentData(); ValidateAndSendAppearanceAndAgentData();
@ -1773,7 +1779,12 @@ namespace OpenSim.Region.Framework.Scenes
{ {
IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
if (m_agentTransfer != null) if (m_agentTransfer != null)
{
// Note: this call can take a while, because it notifies each of the simulator's neighbours.
// It's important that we don't allow the avatar to cross regions meanwhile, as that will
// cause serious errors. We've prevented that from happening by setting IsInTransit=true.
m_agentTransfer.EnableChildAgents(this); m_agentTransfer.EnableChildAgents(this);
}
IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
if (friendsModule != null) if (friendsModule != null)
@ -1790,10 +1801,14 @@ namespace OpenSim.Region.Framework.Scenes
sog.ScheduleGroupForFullUpdate(); sog.ScheduleGroupForFullUpdate();
} }
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
}
finally
{
IsInTransit = false;
}
} }
/// <summary> /// <summary>
@ -2638,7 +2653,7 @@ namespace OpenSim.Region.Framework.Scenes
if (satOnObject) if (satOnObject)
{ {
SendAvatarDataToAllAgents(); SendAvatarDataToAllClients();
m_requestedSitTargetID = 0; m_requestedSitTargetID = 0;
part.RemoveSittingAvatar(this); part.RemoveSittingAvatar(this);
@ -2933,7 +2948,7 @@ namespace OpenSim.Region.Framework.Scenes
Animator.TrySetMovementAnimation("SIT_GROUND"); Animator.TrySetMovementAnimation("SIT_GROUND");
else else
Animator.TrySetMovementAnimation("SIT"); Animator.TrySetMovementAnimation("SIT");
SendAvatarDataToAllAgents(); SendAvatarDataToAllClients();
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
} }
@ -3048,7 +3063,7 @@ namespace OpenSim.Region.Framework.Scenes
sitAnimation = part.SitAnimation; sitAnimation = part.SitAnimation;
} }
Animator.TrySetMovementAnimation(sitAnimation); Animator.TrySetMovementAnimation(sitAnimation);
SendAvatarDataToAllAgents(); SendAvatarDataToAllClients();
TriggerScenePresenceUpdated(); TriggerScenePresenceUpdated();
} }
} }
@ -3165,17 +3180,13 @@ namespace OpenSim.Region.Framework.Scenes
public override void Update() public override void Update()
{ {
const float ROTATION_TOLERANCE = 0.01f;
const float VELOCITY_TOLERANCE = 0.001f;
const float POSITION_TOLERANCE = 0.05f;
if (IsChildAgent == false) if (IsChildAgent == false)
{ {
// NOTE: Velocity is not the same as m_velocity. Velocity will attempt to // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
// grab the latest PhysicsActor velocity, whereas m_velocity is often // grab the latest PhysicsActor velocity, whereas m_velocity is often
// storing a requested force instead of an actual traveling velocity // storing a requested force instead of an actual traveling velocity
if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn) if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
SendAvatarDataToAllAgents(); SendAvatarDataToAllClients();
// Allow any updates for sitting avatars to that llSetPrimitiveLinkParams() can work for very // Allow any updates for sitting avatars to that llSetPrimitiveLinkParams() can work for very
// small increments (e.g. sit position adjusters). An alternative may be to eliminate the tolerance // small increments (e.g. sit position adjusters). An alternative may be to eliminate the tolerance
@ -3185,9 +3196,9 @@ namespace OpenSim.Region.Framework.Scenes
if (!updateClients) if (!updateClients)
updateClients updateClients
= !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) = !Rotation.ApproxEquals(m_lastRotation, Scene.RootRotationUpdateTolerance)
|| !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || !Velocity.ApproxEquals(m_lastVelocity, Scene.RootVelocityUpdateTolerance)
|| !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE); || !m_pos.ApproxEquals(m_lastPosition, Scene.RootPositionUpdateTolerance);
if (updateClients) if (updateClients)
{ {
@ -3199,6 +3210,7 @@ namespace OpenSim.Region.Framework.Scenes
m_lastVelocity = Velocity; m_lastVelocity = Velocity;
} }
if (Scene.AllowAvatarCrossing)
CheckForBorderCrossing(); CheckForBorderCrossing();
CheckForSignificantMovement(); // sends update to the modules. CheckForSignificantMovement(); // sends update to the modules.
@ -3209,7 +3221,6 @@ namespace OpenSim.Region.Framework.Scenes
#region Update Client(s) #region Update Client(s)
/// <summary> /// <summary>
/// Sends a location update to the client connected to this scenePresence /// Sends a location update to the client connected to this scenePresence
/// </summary> /// </summary>
@ -3220,6 +3231,29 @@ namespace OpenSim.Region.Framework.Scenes
// server. // server.
if (remoteClient.IsActive) if (remoteClient.IsActive)
{ {
if (Scene.RootTerseUpdatePeriod > 1)
{
// Console.WriteLine(
// "{0} {1} {2} {3} {4} {5} for {6} to {7}",
// remoteClient.AgentId, UUID, remoteClient.SceneAgent.IsChildAgent, m_terseUpdateCount, Scene.RootTerseUpdatePeriod, Velocity.ApproxEquals(Vector3.Zero, 0.001f), Name, remoteClient.Name);
if (remoteClient.AgentId != UUID
&& !remoteClient.SceneAgent.IsChildAgent
&& m_terseUpdateCount % Scene.RootTerseUpdatePeriod != 0
&& !Velocity.ApproxEquals(Vector3.Zero, 0.001f))
{
// m_log.DebugFormat("[SCENE PRESENCE]: Discarded update from {0} to {1}, args {2} {3} {4} {5} {6} {7}",
// Name, remoteClient.Name, remoteClient.AgentId, UUID, remoteClient.SceneAgent.IsChildAgent, m_terseUpdateCount, Scene.RootTerseUpdatePeriod, Velocity.ApproxEquals(Vector3.Zero, 0.001f));
return;
}
}
if (Scene.ChildTerseUpdatePeriod > 1
&& remoteClient.SceneAgent.IsChildAgent
&& m_terseUpdateCount % Scene.ChildTerseUpdatePeriod != 0
&& !Velocity.ApproxEquals(Vector3.Zero, 0.001f))
return;
//m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity); //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
remoteClient.SendEntityUpdate( remoteClient.SendEntityUpdate(
@ -3257,7 +3291,11 @@ namespace OpenSim.Region.Framework.Scenes
float distanceError = Vector3.Distance(OffsetPosition, expectedPosition); float distanceError = Vector3.Distance(OffsetPosition, expectedPosition);
float speed = Velocity.Length(); float speed = Velocity.Length();
float velocidyDiff = Vector3.Distance(lastVelocitySentToAllClients, Velocity); float velocityDiff = Vector3.Distance(lastVelocitySentToAllClients, Velocity);
// m_log.DebugFormat(
// "[SCENE PRESENCE]: Delta-v {0}, lastVelocity {1}, Velocity {2} for {3} in {4}",
// velocidyDiff, lastVelocitySentToAllClients, Velocity, Name, Scene.Name);
// assuming 5 ms. worst case precision for timer, use 2x that // assuming 5 ms. worst case precision for timer, use 2x that
// for distance error threshold // for distance error threshold
@ -3265,12 +3303,18 @@ namespace OpenSim.Region.Framework.Scenes
if (speed < 0.01f // allow rotation updates if avatar position is unchanged if (speed < 0.01f // allow rotation updates if avatar position is unchanged
|| Math.Abs(distanceError) > distanceErrorThreshold || Math.Abs(distanceError) > distanceErrorThreshold
|| velocidyDiff > 0.01f) // did velocity change from last update? || velocityDiff > 0.01f) // did velocity change from last update?
{ {
// m_log.DebugFormat(
// "[SCENE PRESENCE]: Update triggered with speed {0}, distanceError {1}, distanceThreshold {2}, delta-v {3} for {4} in {5}",
// speed, distanceError, distanceErrorThreshold, velocidyDiff, Name, Scene.Name);
lastVelocitySentToAllClients = Velocity; lastVelocitySentToAllClients = Velocity;
lastTerseUpdateToAllClientsTick = currentTick; lastTerseUpdateToAllClientsTick = currentTick;
lastPositionSentToAllClients = OffsetPosition; lastPositionSentToAllClients = OffsetPosition;
m_terseUpdateCount++;
// Console.WriteLine("Scheduled update for {0} in {1}", Name, Scene.Name); // Console.WriteLine("Scheduled update for {0} in {1}", Name, Scene.Name);
m_scene.ForEachClient(SendTerseUpdateToClient); m_scene.ForEachClient(SendTerseUpdateToClient);
} }
@ -3297,16 +3341,22 @@ namespace OpenSim.Region.Framework.Scenes
ControllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations); ControllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations);
} }
public void SendInitialDataToMe() public void SendInitialDataToClient()
{ {
SentInitialDataToClient = true;
// Send all scene object to the new client // Send all scene object to the new client
Util.RunThreadNoTimeout(delegate Util.RunThreadNoTimeout(delegate
{ {
// m_log.DebugFormat(
// "[SCENE PRESENCE]: Sending initial data to {0} agent {1} in {2}, tp flags {3}",
// IsChildAgent ? "child" : "root", Name, Scene.Name, m_teleportFlags);
// we created a new ScenePresence (a new child agent) in a fresh region. // we created a new ScenePresence (a new child agent) in a fresh region.
// Request info about all the (root) agents in this region // Request info about all the (root) agents in this region
// Note: This won't send data *to* other clients in that region (children don't send) // Note: This won't send data *to* other clients in that region (children don't send)
SendOtherAgentsAvatarDataToMe(); SendOtherAgentsAvatarDataToClient();
SendOtherAgentsAppearanceToMe(); SendOtherAgentsAppearanceToClient();
EntityBase[] entities = Scene.Entities.GetEntities(); EntityBase[] entities = Scene.Entities.GetEntities();
foreach (EntityBase e in entities) foreach (EntityBase e in entities)
@ -3315,7 +3365,7 @@ namespace OpenSim.Region.Framework.Scenes
((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient);
} }
}, "SendInitialDataToMe", null); }, "SendInitialDataToClient", null);
} }
/// <summary> /// <summary>
@ -3348,10 +3398,10 @@ namespace OpenSim.Region.Framework.Scenes
// getting other avatars information was initiated elsewhere immediately after the child circuit connected... don't do it // getting other avatars information was initiated elsewhere immediately after the child circuit connected... don't do it
// again here... this comes after the cached appearance check because the avatars // again here... this comes after the cached appearance check because the avatars
// appearance goes into the avatar update packet // appearance goes into the avatar update packet
SendAvatarDataToAllAgents(); SendAvatarDataToAllClients();
// This invocation always shows up in the viewer logs as an error. Is it needed? // This invocation always shows up in the viewer logs as an error. Is it needed?
SendAppearanceToAgent(this); SendAppearanceToClient(this);
// If we are using the the cached appearance then send it out to everyone // If we are using the the cached appearance then send it out to everyone
if (cachedappearance) if (cachedappearance)
@ -3361,20 +3411,20 @@ namespace OpenSim.Region.Framework.Scenes
// If the avatars baked textures are all in the cache, then we have a // If the avatars baked textures are all in the cache, then we have a
// complete appearance... send it out, if not, then we'll send it when // complete appearance... send it out, if not, then we'll send it when
// the avatar finishes updating its appearance // the avatar finishes updating its appearance
SendAppearanceToAllOtherAgents(); SendAppearanceToAllOtherClients();
} }
} }
public void SendAvatarDataToAllAgents() public void SendAvatarDataToAllClients()
{ {
SendAvatarDataToAllAgents(true); SendAvatarDataToAllClients(true);
} }
/// <summary> /// <summary>
/// Send this agent's avatar data to all other root and child agents in the scene /// Send this agent's avatar data to all other root and child agents in the scene
/// This agent must be root. This avatar will receive its own update. /// This agent must be root. This avatar will receive its own update.
/// </summary> /// </summary>
public void SendAvatarDataToAllAgents(bool full) public void SendAvatarDataToAllClients(bool full)
{ {
//m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAllAgents: {0} ({1})", Name, UUID); //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAllAgents: {0} ({1})", Name, UUID);
// only send update from root agents to other clients; children are only "listening posts" // only send update from root agents to other clients; children are only "listening posts"
@ -3393,7 +3443,7 @@ namespace OpenSim.Region.Framework.Scenes
m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
{ {
if (full) if (full)
SendAvatarDataToAgent(scenePresence); SendAvatarDataToClient(scenePresence);
else else
scenePresence.ControllingClient.SendAvatarDataImmediate(this); scenePresence.ControllingClient.SendAvatarDataImmediate(this);
count++; count++;
@ -3406,7 +3456,7 @@ namespace OpenSim.Region.Framework.Scenes
/// Send avatar data for all other root agents to this agent, this agent /// Send avatar data for all other root agents to this agent, this agent
/// can be either a child or root /// can be either a child or root
/// </summary> /// </summary>
public void SendOtherAgentsAvatarDataToMe() public void SendOtherAgentsAvatarDataToClient()
{ {
int count = 0; int count = 0;
m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence) m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence)
@ -3415,7 +3465,7 @@ namespace OpenSim.Region.Framework.Scenes
if (scenePresence.UUID == UUID) if (scenePresence.UUID == UUID)
return; return;
scenePresence.SendAvatarDataToAgent(this); scenePresence.SendAvatarDataToClient(this);
count++; count++;
}); });
@ -3426,9 +3476,9 @@ namespace OpenSim.Region.Framework.Scenes
/// Send avatar data to an agent. /// Send avatar data to an agent.
/// </summary> /// </summary>
/// <param name="avatar"></param> /// <param name="avatar"></param>
public void SendAvatarDataToAgent(ScenePresence avatar) public void SendAvatarDataToClient(ScenePresence avatar)
{ {
//m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID); //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToClient from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID);
avatar.ControllingClient.SendAvatarDataImmediate(this); avatar.ControllingClient.SendAvatarDataImmediate(this);
Animator.SendAnimPackToClient(avatar.ControllingClient); Animator.SendAnimPackToClient(avatar.ControllingClient);
@ -3438,9 +3488,9 @@ namespace OpenSim.Region.Framework.Scenes
/// Send this agent's appearance to all other root and child agents in the scene /// Send this agent's appearance to all other root and child agents in the scene
/// This agent must be root. /// This agent must be root.
/// </summary> /// </summary>
public void SendAppearanceToAllOtherAgents() public void SendAppearanceToAllOtherClients()
{ {
// m_log.DebugFormat("[SCENE PRESENCE] SendAppearanceToAllOtherAgents: {0} {1}", Name, UUID); // m_log.DebugFormat("[SCENE PRESENCE] SendAppearanceToAllOtherClients: {0} {1}", Name, UUID);
// only send update from root agents to other clients; children are only "listening posts" // only send update from root agents to other clients; children are only "listening posts"
if (IsChildAgent) if (IsChildAgent)
@ -3459,7 +3509,7 @@ namespace OpenSim.Region.Framework.Scenes
if (scenePresence.UUID == UUID) if (scenePresence.UUID == UUID)
return; return;
SendAppearanceToAgent(scenePresence); SendAppearanceToClient(scenePresence);
count++; count++;
}); });
@ -3470,9 +3520,9 @@ namespace OpenSim.Region.Framework.Scenes
/// Send appearance from all other root agents to this agent. this agent /// Send appearance from all other root agents to this agent. this agent
/// can be either root or child /// can be either root or child
/// </summary> /// </summary>
public void SendOtherAgentsAppearanceToMe() public void SendOtherAgentsAppearanceToClient()
{ {
// m_log.DebugFormat("[SCENE PRESENCE] SendOtherAgentsAppearanceToMe: {0} {1}", Name, UUID); // m_log.DebugFormat("[SCENE PRESENCE] SendOtherAgentsAppearanceToClient {0} {1}", Name, UUID);
int count = 0; int count = 0;
m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence) m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence)
@ -3481,7 +3531,7 @@ namespace OpenSim.Region.Framework.Scenes
if (scenePresence.UUID == UUID) if (scenePresence.UUID == UUID)
return; return;
scenePresence.SendAppearanceToAgent(this); scenePresence.SendAppearanceToClient(this);
count++; count++;
}); });
@ -3492,7 +3542,7 @@ namespace OpenSim.Region.Framework.Scenes
/// Send appearance data to an agent. /// Send appearance data to an agent.
/// </summary> /// </summary>
/// <param name="avatar"></param> /// <param name="avatar"></param>
public void SendAppearanceToAgent(ScenePresence avatar) public void SendAppearanceToClient(ScenePresence avatar)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE PRESENCE]: Sending appearance data from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID); // "[SCENE PRESENCE]: Sending appearance data from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID);
@ -3579,8 +3629,9 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero) if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
return; return;
if (!IsInTransit) if (IsInTransit)
{ return;
Vector3 pos2 = AbsolutePosition; Vector3 pos2 = AbsolutePosition;
Vector3 origPosition = pos2; Vector3 origPosition = pos2;
Vector3 vel = Velocity; Vector3 vel = Velocity;
@ -3593,10 +3644,9 @@ namespace OpenSim.Region.Framework.Scenes
pos2.Y = pos2.Y + (vel.Y * timeStep); pos2.Y = pos2.Y + (vel.Y * timeStep);
pos2.Z = pos2.Z + (vel.Z * timeStep); pos2.Z = pos2.Z + (vel.Z * timeStep);
if (!IsInTransit) if (m_scene.PositionIsInCurrentRegion(pos2))
{ return;
if (!m_scene.PositionIsInCurrentRegion(pos2))
{
m_log.DebugFormat("{0} CheckForBorderCrossing: position outside region. {1} in {2} at pos {3}", m_log.DebugFormat("{0} CheckForBorderCrossing: position outside region. {1} in {2} at pos {3}",
LogHeader, Name, Scene.Name, pos2); LogHeader, Name, Scene.Name, pos2);
@ -3624,21 +3674,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
} }
}
else
{
// This constant has been inferred from experimentation
// I'm not sure what this value should be, so I tried a few values.
timeStep = 0.04f;
pos2 = AbsolutePosition;
pos2.X = pos2.X + (vel.X * timeStep);
pos2.Y = pos2.Y + (vel.Y * timeStep);
// Don't touch the Z
m_pos = pos2;
m_log.DebugFormat("[SCENE PRESENCE]: In transit m_pos={0}", m_pos);
}
}
}
// Given a position, make sure it is within the current region. // Given a position, make sure it is within the current region.
// If just outside some border, the returned position will be just inside the border on that side. // If just outside some border, the returned position will be just inside the border on that side.
@ -3725,7 +3760,9 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); // m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX)));
// m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); // m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) float dist = (float)Math.Max(Scene.DefaultDrawDistance,
(float)Math.Max(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY));
if (Util.IsOutsideView(dist, x, newRegionX, y, newRegionY))
{ {
byebyeRegions.Add(handle); byebyeRegions.Add(handle);
} }
@ -3788,6 +3825,8 @@ namespace OpenSim.Region.Framework.Scenes
return; return;
CopyFrom(cAgentData); CopyFrom(cAgentData);
m_updateAgentReceivedAfterTransferEvent.Set();
} }
private static Vector3 marker = new Vector3(-1f, -1f, -1f); private static Vector3 marker = new Vector3(-1f, -1f, -1f);

View File

@ -58,58 +58,60 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
/// <param name="xmlData"></param> /// <param name="xmlData"></param>
/// <returns>The scene object deserialized. Null on failure.</returns> /// <returns>The scene object deserialized. Null on failure.</returns>
public static SceneObjectGroup FromOriginalXmlFormat(string xmlData) public static SceneObjectGroup FromOriginalXmlFormat(string xmlData)
{
using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null))
using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment }))
return FromOriginalXmlFormat(reader);
}
/// <summary>
/// Deserialize a scene object from the original xml format
/// </summary>
/// <param name="xmlData"></param>
/// <returns>The scene object deserialized. Null on failure.</returns>
public static SceneObjectGroup FromOriginalXmlFormat(XmlReader reader)
{ {
//m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); //m_log.DebugFormat("[SOG]: Starting deserialization of SOG");
//int time = System.Environment.TickCount; //int time = System.Environment.TickCount;
SceneObjectGroup sceneObject = null;
try try
{ {
StringReader sr;
XmlTextReader reader;
XmlNodeList parts;
XmlDocument doc;
int linkNum; int linkNum;
doc = new XmlDocument(); reader.ReadToFollowing("RootPart");
doc.LoadXml(xmlData); reader.ReadToFollowing("SceneObjectPart");
parts = doc.GetElementsByTagName("RootPart"); sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader));
reader.ReadToFollowing("OtherParts");
if (parts.Count == 0) if (reader.ReadToDescendant("Part"))
throw new Exception("Invalid Xml format - no root part"); {
do
sr = new StringReader(parts[0].InnerXml); {
reader = new XmlTextReader(sr); if (reader.ReadToDescendant("SceneObjectPart"))
SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader));
reader.Close();
sr.Close();
parts = doc.GetElementsByTagName("Part");
for (int i = 0; i < parts.Count; i++)
{ {
sr = new StringReader(parts[i].InnerXml);
reader = new XmlTextReader(sr);
SceneObjectPart part = SceneObjectPart.FromXml(reader); SceneObjectPart part = SceneObjectPart.FromXml(reader);
linkNum = part.LinkNum; linkNum = part.LinkNum;
sceneObject.AddPart(part); sceneObject.AddPart(part);
part.LinkNum = linkNum; part.LinkNum = linkNum;
part.TrimPermissions(); part.TrimPermissions();
reader.Close(); }
sr.Close(); }
while (reader.ReadToNextSibling("Part"));
} }
// Script state may, or may not, exist. Not having any, is NOT // Script state may, or may not, exist. Not having any, is NOT
// ever a problem. // ever a problem.
sceneObject.LoadScriptState(doc); sceneObject.LoadScriptState(reader);
return sceneObject;
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat( m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed. Exception {0}", e);
"[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData);
return null; return null;
} }
return sceneObject;
} }
/// <summary> /// <summary>
@ -369,14 +371,14 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
#region manual serialization #region manual serialization
private static Dictionary<string, Action<SceneObjectPart, XmlTextReader>> m_SOPXmlProcessors private static Dictionary<string, Action<SceneObjectPart, XmlReader>> m_SOPXmlProcessors
= new Dictionary<string, Action<SceneObjectPart, XmlTextReader>>(); = new Dictionary<string, Action<SceneObjectPart, XmlReader>>();
private static Dictionary<string, Action<TaskInventoryItem, XmlTextReader>> m_TaskInventoryXmlProcessors private static Dictionary<string, Action<TaskInventoryItem, XmlReader>> m_TaskInventoryXmlProcessors
= new Dictionary<string, Action<TaskInventoryItem, XmlTextReader>>(); = new Dictionary<string, Action<TaskInventoryItem, XmlReader>>();
private static Dictionary<string, Action<PrimitiveBaseShape, XmlTextReader>> m_ShapeXmlProcessors private static Dictionary<string, Action<PrimitiveBaseShape, XmlReader>> m_ShapeXmlProcessors
= new Dictionary<string, Action<PrimitiveBaseShape, XmlTextReader>>(); = new Dictionary<string, Action<PrimitiveBaseShape, XmlReader>>();
static SceneObjectSerializer() static SceneObjectSerializer()
{ {
@ -532,112 +534,112 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
} }
#region SOPXmlProcessors #region SOPXmlProcessors
private static void ProcessAllowedDrop(SceneObjectPart obj, XmlTextReader reader) private static void ProcessAllowedDrop(SceneObjectPart obj, XmlReader reader)
{ {
obj.AllowedDrop = Util.ReadBoolean(reader); obj.AllowedDrop = Util.ReadBoolean(reader);
} }
private static void ProcessCreatorID(SceneObjectPart obj, XmlTextReader reader) private static void ProcessCreatorID(SceneObjectPart obj, XmlReader reader)
{ {
obj.CreatorID = Util.ReadUUID(reader, "CreatorID"); obj.CreatorID = Util.ReadUUID(reader, "CreatorID");
} }
private static void ProcessCreatorData(SceneObjectPart obj, XmlTextReader reader) private static void ProcessCreatorData(SceneObjectPart obj, XmlReader reader)
{ {
obj.CreatorData = reader.ReadElementContentAsString("CreatorData", String.Empty); obj.CreatorData = reader.ReadElementContentAsString("CreatorData", String.Empty);
} }
private static void ProcessFolderID(SceneObjectPart obj, XmlTextReader reader) private static void ProcessFolderID(SceneObjectPart obj, XmlReader reader)
{ {
obj.FolderID = Util.ReadUUID(reader, "FolderID"); obj.FolderID = Util.ReadUUID(reader, "FolderID");
} }
private static void ProcessInventorySerial(SceneObjectPart obj, XmlTextReader reader) private static void ProcessInventorySerial(SceneObjectPart obj, XmlReader reader)
{ {
obj.InventorySerial = (uint)reader.ReadElementContentAsInt("InventorySerial", String.Empty); obj.InventorySerial = (uint)reader.ReadElementContentAsInt("InventorySerial", String.Empty);
} }
private static void ProcessTaskInventory(SceneObjectPart obj, XmlTextReader reader) private static void ProcessTaskInventory(SceneObjectPart obj, XmlReader reader)
{ {
obj.TaskInventory = ReadTaskInventory(reader, "TaskInventory"); obj.TaskInventory = ReadTaskInventory(reader, "TaskInventory");
} }
private static void ProcessUUID(SceneObjectPart obj, XmlTextReader reader) private static void ProcessUUID(SceneObjectPart obj, XmlReader reader)
{ {
obj.UUID = Util.ReadUUID(reader, "UUID"); obj.UUID = Util.ReadUUID(reader, "UUID");
} }
private static void ProcessLocalId(SceneObjectPart obj, XmlTextReader reader) private static void ProcessLocalId(SceneObjectPart obj, XmlReader reader)
{ {
obj.LocalId = (uint)reader.ReadElementContentAsLong("LocalId", String.Empty); obj.LocalId = (uint)reader.ReadElementContentAsLong("LocalId", String.Empty);
} }
private static void ProcessName(SceneObjectPart obj, XmlTextReader reader) private static void ProcessName(SceneObjectPart obj, XmlReader reader)
{ {
obj.Name = reader.ReadElementString("Name"); obj.Name = reader.ReadElementString("Name");
} }
private static void ProcessMaterial(SceneObjectPart obj, XmlTextReader reader) private static void ProcessMaterial(SceneObjectPart obj, XmlReader reader)
{ {
obj.Material = (byte)reader.ReadElementContentAsInt("Material", String.Empty); obj.Material = (byte)reader.ReadElementContentAsInt("Material", String.Empty);
} }
private static void ProcessPassTouches(SceneObjectPart obj, XmlTextReader reader) private static void ProcessPassTouches(SceneObjectPart obj, XmlReader reader)
{ {
obj.PassTouches = Util.ReadBoolean(reader); obj.PassTouches = Util.ReadBoolean(reader);
} }
private static void ProcessPassCollisions(SceneObjectPart obj, XmlTextReader reader) private static void ProcessPassCollisions(SceneObjectPart obj, XmlReader reader)
{ {
obj.PassCollisions = Util.ReadBoolean(reader); obj.PassCollisions = Util.ReadBoolean(reader);
} }
private static void ProcessRegionHandle(SceneObjectPart obj, XmlTextReader reader) private static void ProcessRegionHandle(SceneObjectPart obj, XmlReader reader)
{ {
obj.RegionHandle = (ulong)reader.ReadElementContentAsLong("RegionHandle", String.Empty); obj.RegionHandle = (ulong)reader.ReadElementContentAsLong("RegionHandle", String.Empty);
} }
private static void ProcessScriptAccessPin(SceneObjectPart obj, XmlTextReader reader) private static void ProcessScriptAccessPin(SceneObjectPart obj, XmlReader reader)
{ {
obj.ScriptAccessPin = reader.ReadElementContentAsInt("ScriptAccessPin", String.Empty); obj.ScriptAccessPin = reader.ReadElementContentAsInt("ScriptAccessPin", String.Empty);
} }
private static void ProcessGroupPosition(SceneObjectPart obj, XmlTextReader reader) private static void ProcessGroupPosition(SceneObjectPart obj, XmlReader reader)
{ {
obj.GroupPosition = Util.ReadVector(reader, "GroupPosition"); obj.GroupPosition = Util.ReadVector(reader, "GroupPosition");
} }
private static void ProcessOffsetPosition(SceneObjectPart obj, XmlTextReader reader) private static void ProcessOffsetPosition(SceneObjectPart obj, XmlReader reader)
{ {
obj.OffsetPosition = Util.ReadVector(reader, "OffsetPosition"); ; obj.OffsetPosition = Util.ReadVector(reader, "OffsetPosition"); ;
} }
private static void ProcessRotationOffset(SceneObjectPart obj, XmlTextReader reader) private static void ProcessRotationOffset(SceneObjectPart obj, XmlReader reader)
{ {
obj.RotationOffset = Util.ReadQuaternion(reader, "RotationOffset"); obj.RotationOffset = Util.ReadQuaternion(reader, "RotationOffset");
} }
private static void ProcessVelocity(SceneObjectPart obj, XmlTextReader reader) private static void ProcessVelocity(SceneObjectPart obj, XmlReader reader)
{ {
obj.Velocity = Util.ReadVector(reader, "Velocity"); obj.Velocity = Util.ReadVector(reader, "Velocity");
} }
private static void ProcessAngularVelocity(SceneObjectPart obj, XmlTextReader reader) private static void ProcessAngularVelocity(SceneObjectPart obj, XmlReader reader)
{ {
obj.AngularVelocity = Util.ReadVector(reader, "AngularVelocity"); obj.AngularVelocity = Util.ReadVector(reader, "AngularVelocity");
} }
private static void ProcessAcceleration(SceneObjectPart obj, XmlTextReader reader) private static void ProcessAcceleration(SceneObjectPart obj, XmlReader reader)
{ {
obj.Acceleration = Util.ReadVector(reader, "Acceleration"); obj.Acceleration = Util.ReadVector(reader, "Acceleration");
} }
private static void ProcessDescription(SceneObjectPart obj, XmlTextReader reader) private static void ProcessDescription(SceneObjectPart obj, XmlReader reader)
{ {
obj.Description = reader.ReadElementString("Description"); obj.Description = reader.ReadElementString("Description");
} }
private static void ProcessColor(SceneObjectPart obj, XmlTextReader reader) private static void ProcessColor(SceneObjectPart obj, XmlReader reader)
{ {
reader.ReadStartElement("Color"); reader.ReadStartElement("Color");
if (reader.Name == "R") if (reader.Name == "R")
@ -651,57 +653,57 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
} }
} }
private static void ProcessText(SceneObjectPart obj, XmlTextReader reader) private static void ProcessText(SceneObjectPart obj, XmlReader reader)
{ {
obj.Text = reader.ReadElementString("Text", String.Empty); obj.Text = reader.ReadElementString("Text", String.Empty);
} }
private static void ProcessSitName(SceneObjectPart obj, XmlTextReader reader) private static void ProcessSitName(SceneObjectPart obj, XmlReader reader)
{ {
obj.SitName = reader.ReadElementString("SitName", String.Empty); obj.SitName = reader.ReadElementString("SitName", String.Empty);
} }
private static void ProcessTouchName(SceneObjectPart obj, XmlTextReader reader) private static void ProcessTouchName(SceneObjectPart obj, XmlReader reader)
{ {
obj.TouchName = reader.ReadElementString("TouchName", String.Empty); obj.TouchName = reader.ReadElementString("TouchName", String.Empty);
} }
private static void ProcessLinkNum(SceneObjectPart obj, XmlTextReader reader) private static void ProcessLinkNum(SceneObjectPart obj, XmlReader reader)
{ {
obj.LinkNum = reader.ReadElementContentAsInt("LinkNum", String.Empty); obj.LinkNum = reader.ReadElementContentAsInt("LinkNum", String.Empty);
} }
private static void ProcessClickAction(SceneObjectPart obj, XmlTextReader reader) private static void ProcessClickAction(SceneObjectPart obj, XmlReader reader)
{ {
obj.ClickAction = (byte)reader.ReadElementContentAsInt("ClickAction", String.Empty); obj.ClickAction = (byte)reader.ReadElementContentAsInt("ClickAction", String.Empty);
} }
private static void ProcessPhysicsShapeType(SceneObjectPart obj, XmlTextReader reader) private static void ProcessPhysicsShapeType(SceneObjectPart obj, XmlReader reader)
{ {
obj.PhysicsShapeType = (byte)reader.ReadElementContentAsInt("PhysicsShapeType", String.Empty); obj.PhysicsShapeType = (byte)reader.ReadElementContentAsInt("PhysicsShapeType", String.Empty);
} }
private static void ProcessDensity(SceneObjectPart obj, XmlTextReader reader) private static void ProcessDensity(SceneObjectPart obj, XmlReader reader)
{ {
obj.Density = reader.ReadElementContentAsFloat("Density", String.Empty); obj.Density = reader.ReadElementContentAsFloat("Density", String.Empty);
} }
private static void ProcessFriction(SceneObjectPart obj, XmlTextReader reader) private static void ProcessFriction(SceneObjectPart obj, XmlReader reader)
{ {
obj.Friction = reader.ReadElementContentAsFloat("Friction", String.Empty); obj.Friction = reader.ReadElementContentAsFloat("Friction", String.Empty);
} }
private static void ProcessBounce(SceneObjectPart obj, XmlTextReader reader) private static void ProcessBounce(SceneObjectPart obj, XmlReader reader)
{ {
obj.Restitution = reader.ReadElementContentAsFloat("Bounce", String.Empty); obj.Restitution = reader.ReadElementContentAsFloat("Bounce", String.Empty);
} }
private static void ProcessGravityModifier(SceneObjectPart obj, XmlTextReader reader) private static void ProcessGravityModifier(SceneObjectPart obj, XmlReader reader)
{ {
obj.GravityModifier = reader.ReadElementContentAsFloat("GravityModifier", String.Empty); obj.GravityModifier = reader.ReadElementContentAsFloat("GravityModifier", String.Empty);
} }
private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) private static void ProcessShape(SceneObjectPart obj, XmlReader reader)
{ {
List<string> errorNodeNames; List<string> errorNodeNames;
obj.Shape = ReadShape(reader, "Shape", out errorNodeNames); obj.Shape = ReadShape(reader, "Shape", out errorNodeNames);
@ -714,163 +716,163 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
} }
} }
private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader) private static void ProcessScale(SceneObjectPart obj, XmlReader reader)
{ {
obj.Scale = Util.ReadVector(reader, "Scale"); obj.Scale = Util.ReadVector(reader, "Scale");
} }
private static void ProcessSitTargetOrientation(SceneObjectPart obj, XmlTextReader reader) private static void ProcessSitTargetOrientation(SceneObjectPart obj, XmlReader reader)
{ {
obj.SitTargetOrientation = Util.ReadQuaternion(reader, "SitTargetOrientation"); obj.SitTargetOrientation = Util.ReadQuaternion(reader, "SitTargetOrientation");
} }
private static void ProcessSitTargetPosition(SceneObjectPart obj, XmlTextReader reader) private static void ProcessSitTargetPosition(SceneObjectPart obj, XmlReader reader)
{ {
obj.SitTargetPosition = Util.ReadVector(reader, "SitTargetPosition"); obj.SitTargetPosition = Util.ReadVector(reader, "SitTargetPosition");
} }
private static void ProcessSitTargetPositionLL(SceneObjectPart obj, XmlTextReader reader) private static void ProcessSitTargetPositionLL(SceneObjectPart obj, XmlReader reader)
{ {
obj.SitTargetPositionLL = Util.ReadVector(reader, "SitTargetPositionLL"); obj.SitTargetPositionLL = Util.ReadVector(reader, "SitTargetPositionLL");
} }
private static void ProcessSitTargetOrientationLL(SceneObjectPart obj, XmlTextReader reader) private static void ProcessSitTargetOrientationLL(SceneObjectPart obj, XmlReader reader)
{ {
obj.SitTargetOrientationLL = Util.ReadQuaternion(reader, "SitTargetOrientationLL"); obj.SitTargetOrientationLL = Util.ReadQuaternion(reader, "SitTargetOrientationLL");
} }
private static void ProcessParentID(SceneObjectPart obj, XmlTextReader reader) private static void ProcessParentID(SceneObjectPart obj, XmlReader reader)
{ {
string str = reader.ReadElementContentAsString("ParentID", String.Empty); string str = reader.ReadElementContentAsString("ParentID", String.Empty);
obj.ParentID = Convert.ToUInt32(str); obj.ParentID = Convert.ToUInt32(str);
} }
private static void ProcessCreationDate(SceneObjectPart obj, XmlTextReader reader) private static void ProcessCreationDate(SceneObjectPart obj, XmlReader reader)
{ {
obj.CreationDate = reader.ReadElementContentAsInt("CreationDate", String.Empty); obj.CreationDate = reader.ReadElementContentAsInt("CreationDate", String.Empty);
} }
private static void ProcessCategory(SceneObjectPart obj, XmlTextReader reader) private static void ProcessCategory(SceneObjectPart obj, XmlReader reader)
{ {
obj.Category = (uint)reader.ReadElementContentAsInt("Category", String.Empty); obj.Category = (uint)reader.ReadElementContentAsInt("Category", String.Empty);
} }
private static void ProcessSalePrice(SceneObjectPart obj, XmlTextReader reader) private static void ProcessSalePrice(SceneObjectPart obj, XmlReader reader)
{ {
obj.SalePrice = reader.ReadElementContentAsInt("SalePrice", String.Empty); obj.SalePrice = reader.ReadElementContentAsInt("SalePrice", String.Empty);
} }
private static void ProcessObjectSaleType(SceneObjectPart obj, XmlTextReader reader) private static void ProcessObjectSaleType(SceneObjectPart obj, XmlReader reader)
{ {
obj.ObjectSaleType = (byte)reader.ReadElementContentAsInt("ObjectSaleType", String.Empty); obj.ObjectSaleType = (byte)reader.ReadElementContentAsInt("ObjectSaleType", String.Empty);
} }
private static void ProcessOwnershipCost(SceneObjectPart obj, XmlTextReader reader) private static void ProcessOwnershipCost(SceneObjectPart obj, XmlReader reader)
{ {
obj.OwnershipCost = reader.ReadElementContentAsInt("OwnershipCost", String.Empty); obj.OwnershipCost = reader.ReadElementContentAsInt("OwnershipCost", String.Empty);
} }
private static void ProcessGroupID(SceneObjectPart obj, XmlTextReader reader) private static void ProcessGroupID(SceneObjectPart obj, XmlReader reader)
{ {
obj.GroupID = Util.ReadUUID(reader, "GroupID"); obj.GroupID = Util.ReadUUID(reader, "GroupID");
} }
private static void ProcessOwnerID(SceneObjectPart obj, XmlTextReader reader) private static void ProcessOwnerID(SceneObjectPart obj, XmlReader reader)
{ {
obj.OwnerID = Util.ReadUUID(reader, "OwnerID"); obj.OwnerID = Util.ReadUUID(reader, "OwnerID");
} }
private static void ProcessLastOwnerID(SceneObjectPart obj, XmlTextReader reader) private static void ProcessLastOwnerID(SceneObjectPart obj, XmlReader reader)
{ {
obj.LastOwnerID = Util.ReadUUID(reader, "LastOwnerID"); obj.LastOwnerID = Util.ReadUUID(reader, "LastOwnerID");
} }
private static void ProcessBaseMask(SceneObjectPart obj, XmlTextReader reader) private static void ProcessBaseMask(SceneObjectPart obj, XmlReader reader)
{ {
obj.BaseMask = (uint)reader.ReadElementContentAsInt("BaseMask", String.Empty); obj.BaseMask = (uint)reader.ReadElementContentAsInt("BaseMask", String.Empty);
} }
private static void ProcessOwnerMask(SceneObjectPart obj, XmlTextReader reader) private static void ProcessOwnerMask(SceneObjectPart obj, XmlReader reader)
{ {
obj.OwnerMask = (uint)reader.ReadElementContentAsInt("OwnerMask", String.Empty); obj.OwnerMask = (uint)reader.ReadElementContentAsInt("OwnerMask", String.Empty);
} }
private static void ProcessGroupMask(SceneObjectPart obj, XmlTextReader reader) private static void ProcessGroupMask(SceneObjectPart obj, XmlReader reader)
{ {
obj.GroupMask = (uint)reader.ReadElementContentAsInt("GroupMask", String.Empty); obj.GroupMask = (uint)reader.ReadElementContentAsInt("GroupMask", String.Empty);
} }
private static void ProcessEveryoneMask(SceneObjectPart obj, XmlTextReader reader) private static void ProcessEveryoneMask(SceneObjectPart obj, XmlReader reader)
{ {
obj.EveryoneMask = (uint)reader.ReadElementContentAsInt("EveryoneMask", String.Empty); obj.EveryoneMask = (uint)reader.ReadElementContentAsInt("EveryoneMask", String.Empty);
} }
private static void ProcessNextOwnerMask(SceneObjectPart obj, XmlTextReader reader) private static void ProcessNextOwnerMask(SceneObjectPart obj, XmlReader reader)
{ {
obj.NextOwnerMask = (uint)reader.ReadElementContentAsInt("NextOwnerMask", String.Empty); obj.NextOwnerMask = (uint)reader.ReadElementContentAsInt("NextOwnerMask", String.Empty);
} }
private static void ProcessFlags(SceneObjectPart obj, XmlTextReader reader) private static void ProcessFlags(SceneObjectPart obj, XmlReader reader)
{ {
obj.Flags = Util.ReadEnum<PrimFlags>(reader, "Flags"); obj.Flags = Util.ReadEnum<PrimFlags>(reader, "Flags");
} }
private static void ProcessCollisionSound(SceneObjectPart obj, XmlTextReader reader) private static void ProcessCollisionSound(SceneObjectPart obj, XmlReader reader)
{ {
obj.CollisionSound = Util.ReadUUID(reader, "CollisionSound"); obj.CollisionSound = Util.ReadUUID(reader, "CollisionSound");
} }
private static void ProcessCollisionSoundVolume(SceneObjectPart obj, XmlTextReader reader) private static void ProcessCollisionSoundVolume(SceneObjectPart obj, XmlReader reader)
{ {
obj.CollisionSoundVolume = reader.ReadElementContentAsFloat("CollisionSoundVolume", String.Empty); obj.CollisionSoundVolume = reader.ReadElementContentAsFloat("CollisionSoundVolume", String.Empty);
} }
private static void ProcessMediaUrl(SceneObjectPart obj, XmlTextReader reader) private static void ProcessMediaUrl(SceneObjectPart obj, XmlReader reader)
{ {
obj.MediaUrl = reader.ReadElementContentAsString("MediaUrl", String.Empty); obj.MediaUrl = reader.ReadElementContentAsString("MediaUrl", String.Empty);
} }
private static void ProcessAttachedPos(SceneObjectPart obj, XmlTextReader reader) private static void ProcessAttachedPos(SceneObjectPart obj, XmlReader reader)
{ {
obj.AttachedPos = Util.ReadVector(reader, "AttachedPos"); obj.AttachedPos = Util.ReadVector(reader, "AttachedPos");
} }
private static void ProcessDynAttrs(SceneObjectPart obj, XmlTextReader reader) private static void ProcessDynAttrs(SceneObjectPart obj, XmlReader reader)
{ {
obj.DynAttrs.ReadXml(reader); obj.DynAttrs.ReadXml(reader);
} }
private static void ProcessTextureAnimation(SceneObjectPart obj, XmlTextReader reader) private static void ProcessTextureAnimation(SceneObjectPart obj, XmlReader reader)
{ {
obj.TextureAnimation = Convert.FromBase64String(reader.ReadElementContentAsString("TextureAnimation", String.Empty)); obj.TextureAnimation = Convert.FromBase64String(reader.ReadElementContentAsString("TextureAnimation", String.Empty));
} }
private static void ProcessParticleSystem(SceneObjectPart obj, XmlTextReader reader) private static void ProcessParticleSystem(SceneObjectPart obj, XmlReader reader)
{ {
obj.ParticleSystem = Convert.FromBase64String(reader.ReadElementContentAsString("ParticleSystem", String.Empty)); obj.ParticleSystem = Convert.FromBase64String(reader.ReadElementContentAsString("ParticleSystem", String.Empty));
} }
private static void ProcessPayPrice0(SceneObjectPart obj, XmlTextReader reader) private static void ProcessPayPrice0(SceneObjectPart obj, XmlReader reader)
{ {
obj.PayPrice[0] = (int)reader.ReadElementContentAsInt("PayPrice0", String.Empty); obj.PayPrice[0] = (int)reader.ReadElementContentAsInt("PayPrice0", String.Empty);
} }
private static void ProcessPayPrice1(SceneObjectPart obj, XmlTextReader reader) private static void ProcessPayPrice1(SceneObjectPart obj, XmlReader reader)
{ {
obj.PayPrice[1] = (int)reader.ReadElementContentAsInt("PayPrice1", String.Empty); obj.PayPrice[1] = (int)reader.ReadElementContentAsInt("PayPrice1", String.Empty);
} }
private static void ProcessPayPrice2(SceneObjectPart obj, XmlTextReader reader) private static void ProcessPayPrice2(SceneObjectPart obj, XmlReader reader)
{ {
obj.PayPrice[2] = (int)reader.ReadElementContentAsInt("PayPrice2", String.Empty); obj.PayPrice[2] = (int)reader.ReadElementContentAsInt("PayPrice2", String.Empty);
} }
private static void ProcessPayPrice3(SceneObjectPart obj, XmlTextReader reader) private static void ProcessPayPrice3(SceneObjectPart obj, XmlReader reader)
{ {
obj.PayPrice[3] = (int)reader.ReadElementContentAsInt("PayPrice3", String.Empty); obj.PayPrice[3] = (int)reader.ReadElementContentAsInt("PayPrice3", String.Empty);
} }
private static void ProcessPayPrice4(SceneObjectPart obj, XmlTextReader reader) private static void ProcessPayPrice4(SceneObjectPart obj, XmlReader reader)
{ {
obj.PayPrice[4] = (int)reader.ReadElementContentAsInt("PayPrice4", String.Empty); obj.PayPrice[4] = (int)reader.ReadElementContentAsInt("PayPrice4", String.Empty);
} }
@ -878,122 +880,122 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
#endregion #endregion
#region TaskInventoryXmlProcessors #region TaskInventoryXmlProcessors
private static void ProcessTIAssetID(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIAssetID(TaskInventoryItem item, XmlReader reader)
{ {
item.AssetID = Util.ReadUUID(reader, "AssetID"); item.AssetID = Util.ReadUUID(reader, "AssetID");
} }
private static void ProcessTIBasePermissions(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIBasePermissions(TaskInventoryItem item, XmlReader reader)
{ {
item.BasePermissions = (uint)reader.ReadElementContentAsInt("BasePermissions", String.Empty); item.BasePermissions = (uint)reader.ReadElementContentAsInt("BasePermissions", String.Empty);
} }
private static void ProcessTICreationDate(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTICreationDate(TaskInventoryItem item, XmlReader reader)
{ {
item.CreationDate = (uint)reader.ReadElementContentAsInt("CreationDate", String.Empty); item.CreationDate = (uint)reader.ReadElementContentAsInt("CreationDate", String.Empty);
} }
private static void ProcessTICreatorID(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTICreatorID(TaskInventoryItem item, XmlReader reader)
{ {
item.CreatorID = Util.ReadUUID(reader, "CreatorID"); item.CreatorID = Util.ReadUUID(reader, "CreatorID");
} }
private static void ProcessTICreatorData(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTICreatorData(TaskInventoryItem item, XmlReader reader)
{ {
item.CreatorData = reader.ReadElementContentAsString("CreatorData", String.Empty); item.CreatorData = reader.ReadElementContentAsString("CreatorData", String.Empty);
} }
private static void ProcessTIDescription(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIDescription(TaskInventoryItem item, XmlReader reader)
{ {
item.Description = reader.ReadElementContentAsString("Description", String.Empty); item.Description = reader.ReadElementContentAsString("Description", String.Empty);
} }
private static void ProcessTIEveryonePermissions(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIEveryonePermissions(TaskInventoryItem item, XmlReader reader)
{ {
item.EveryonePermissions = (uint)reader.ReadElementContentAsInt("EveryonePermissions", String.Empty); item.EveryonePermissions = (uint)reader.ReadElementContentAsInt("EveryonePermissions", String.Empty);
} }
private static void ProcessTIFlags(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIFlags(TaskInventoryItem item, XmlReader reader)
{ {
item.Flags = (uint)reader.ReadElementContentAsInt("Flags", String.Empty); item.Flags = (uint)reader.ReadElementContentAsInt("Flags", String.Empty);
} }
private static void ProcessTIGroupID(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIGroupID(TaskInventoryItem item, XmlReader reader)
{ {
item.GroupID = Util.ReadUUID(reader, "GroupID"); item.GroupID = Util.ReadUUID(reader, "GroupID");
} }
private static void ProcessTIGroupPermissions(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIGroupPermissions(TaskInventoryItem item, XmlReader reader)
{ {
item.GroupPermissions = (uint)reader.ReadElementContentAsInt("GroupPermissions", String.Empty); item.GroupPermissions = (uint)reader.ReadElementContentAsInt("GroupPermissions", String.Empty);
} }
private static void ProcessTIInvType(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIInvType(TaskInventoryItem item, XmlReader reader)
{ {
item.InvType = reader.ReadElementContentAsInt("InvType", String.Empty); item.InvType = reader.ReadElementContentAsInt("InvType", String.Empty);
} }
private static void ProcessTIItemID(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIItemID(TaskInventoryItem item, XmlReader reader)
{ {
item.ItemID = Util.ReadUUID(reader, "ItemID"); item.ItemID = Util.ReadUUID(reader, "ItemID");
} }
private static void ProcessTIOldItemID(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIOldItemID(TaskInventoryItem item, XmlReader reader)
{ {
item.OldItemID = Util.ReadUUID(reader, "OldItemID"); item.OldItemID = Util.ReadUUID(reader, "OldItemID");
} }
private static void ProcessTILastOwnerID(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTILastOwnerID(TaskInventoryItem item, XmlReader reader)
{ {
item.LastOwnerID = Util.ReadUUID(reader, "LastOwnerID"); item.LastOwnerID = Util.ReadUUID(reader, "LastOwnerID");
} }
private static void ProcessTIName(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIName(TaskInventoryItem item, XmlReader reader)
{ {
item.Name = reader.ReadElementContentAsString("Name", String.Empty); item.Name = reader.ReadElementContentAsString("Name", String.Empty);
} }
private static void ProcessTINextPermissions(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTINextPermissions(TaskInventoryItem item, XmlReader reader)
{ {
item.NextPermissions = (uint)reader.ReadElementContentAsInt("NextPermissions", String.Empty); item.NextPermissions = (uint)reader.ReadElementContentAsInt("NextPermissions", String.Empty);
} }
private static void ProcessTIOwnerID(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIOwnerID(TaskInventoryItem item, XmlReader reader)
{ {
item.OwnerID = Util.ReadUUID(reader, "OwnerID"); item.OwnerID = Util.ReadUUID(reader, "OwnerID");
} }
private static void ProcessTICurrentPermissions(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTICurrentPermissions(TaskInventoryItem item, XmlReader reader)
{ {
item.CurrentPermissions = (uint)reader.ReadElementContentAsInt("CurrentPermissions", String.Empty); item.CurrentPermissions = (uint)reader.ReadElementContentAsInt("CurrentPermissions", String.Empty);
} }
private static void ProcessTIParentID(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIParentID(TaskInventoryItem item, XmlReader reader)
{ {
item.ParentID = Util.ReadUUID(reader, "ParentID"); item.ParentID = Util.ReadUUID(reader, "ParentID");
} }
private static void ProcessTIParentPartID(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIParentPartID(TaskInventoryItem item, XmlReader reader)
{ {
item.ParentPartID = Util.ReadUUID(reader, "ParentPartID"); item.ParentPartID = Util.ReadUUID(reader, "ParentPartID");
} }
private static void ProcessTIPermsGranter(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIPermsGranter(TaskInventoryItem item, XmlReader reader)
{ {
item.PermsGranter = Util.ReadUUID(reader, "PermsGranter"); item.PermsGranter = Util.ReadUUID(reader, "PermsGranter");
} }
private static void ProcessTIPermsMask(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIPermsMask(TaskInventoryItem item, XmlReader reader)
{ {
item.PermsMask = reader.ReadElementContentAsInt("PermsMask", String.Empty); item.PermsMask = reader.ReadElementContentAsInt("PermsMask", String.Empty);
} }
private static void ProcessTIType(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIType(TaskInventoryItem item, XmlReader reader)
{ {
item.Type = reader.ReadElementContentAsInt("Type", String.Empty); item.Type = reader.ReadElementContentAsInt("Type", String.Empty);
} }
private static void ProcessTIOwnerChanged(TaskInventoryItem item, XmlTextReader reader) private static void ProcessTIOwnerChanged(TaskInventoryItem item, XmlReader reader)
{ {
item.OwnerChanged = Util.ReadBoolean(reader); item.OwnerChanged = Util.ReadBoolean(reader);
} }
@ -1001,243 +1003,243 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
#endregion #endregion
#region ShapeXmlProcessors #region ShapeXmlProcessors
private static void ProcessShpProfileCurve(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpProfileCurve(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.ProfileCurve = (byte)reader.ReadElementContentAsInt("ProfileCurve", String.Empty); shp.ProfileCurve = (byte)reader.ReadElementContentAsInt("ProfileCurve", String.Empty);
} }
private static void ProcessShpTextureEntry(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpTextureEntry(PrimitiveBaseShape shp, XmlReader reader)
{ {
byte[] teData = Convert.FromBase64String(reader.ReadElementString("TextureEntry")); byte[] teData = Convert.FromBase64String(reader.ReadElementString("TextureEntry"));
shp.Textures = new Primitive.TextureEntry(teData, 0, teData.Length); shp.Textures = new Primitive.TextureEntry(teData, 0, teData.Length);
} }
private static void ProcessShpExtraParams(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpExtraParams(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.ExtraParams = Convert.FromBase64String(reader.ReadElementString("ExtraParams")); shp.ExtraParams = Convert.FromBase64String(reader.ReadElementString("ExtraParams"));
} }
private static void ProcessShpPathBegin(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPathBegin(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PathBegin = (ushort)reader.ReadElementContentAsInt("PathBegin", String.Empty); shp.PathBegin = (ushort)reader.ReadElementContentAsInt("PathBegin", String.Empty);
} }
private static void ProcessShpPathCurve(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPathCurve(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PathCurve = (byte)reader.ReadElementContentAsInt("PathCurve", String.Empty); shp.PathCurve = (byte)reader.ReadElementContentAsInt("PathCurve", String.Empty);
} }
private static void ProcessShpPathEnd(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPathEnd(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PathEnd = (ushort)reader.ReadElementContentAsInt("PathEnd", String.Empty); shp.PathEnd = (ushort)reader.ReadElementContentAsInt("PathEnd", String.Empty);
} }
private static void ProcessShpPathRadiusOffset(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPathRadiusOffset(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PathRadiusOffset = (sbyte)reader.ReadElementContentAsInt("PathRadiusOffset", String.Empty); shp.PathRadiusOffset = (sbyte)reader.ReadElementContentAsInt("PathRadiusOffset", String.Empty);
} }
private static void ProcessShpPathRevolutions(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPathRevolutions(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PathRevolutions = (byte)reader.ReadElementContentAsInt("PathRevolutions", String.Empty); shp.PathRevolutions = (byte)reader.ReadElementContentAsInt("PathRevolutions", String.Empty);
} }
private static void ProcessShpPathScaleX(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPathScaleX(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PathScaleX = (byte)reader.ReadElementContentAsInt("PathScaleX", String.Empty); shp.PathScaleX = (byte)reader.ReadElementContentAsInt("PathScaleX", String.Empty);
} }
private static void ProcessShpPathScaleY(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPathScaleY(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PathScaleY = (byte)reader.ReadElementContentAsInt("PathScaleY", String.Empty); shp.PathScaleY = (byte)reader.ReadElementContentAsInt("PathScaleY", String.Empty);
} }
private static void ProcessShpPathShearX(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPathShearX(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PathShearX = (byte)reader.ReadElementContentAsInt("PathShearX", String.Empty); shp.PathShearX = (byte)reader.ReadElementContentAsInt("PathShearX", String.Empty);
} }
private static void ProcessShpPathShearY(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPathShearY(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PathShearY = (byte)reader.ReadElementContentAsInt("PathShearY", String.Empty); shp.PathShearY = (byte)reader.ReadElementContentAsInt("PathShearY", String.Empty);
} }
private static void ProcessShpPathSkew(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPathSkew(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PathSkew = (sbyte)reader.ReadElementContentAsInt("PathSkew", String.Empty); shp.PathSkew = (sbyte)reader.ReadElementContentAsInt("PathSkew", String.Empty);
} }
private static void ProcessShpPathTaperX(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPathTaperX(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PathTaperX = (sbyte)reader.ReadElementContentAsInt("PathTaperX", String.Empty); shp.PathTaperX = (sbyte)reader.ReadElementContentAsInt("PathTaperX", String.Empty);
} }
private static void ProcessShpPathTaperY(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPathTaperY(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PathTaperY = (sbyte)reader.ReadElementContentAsInt("PathTaperY", String.Empty); shp.PathTaperY = (sbyte)reader.ReadElementContentAsInt("PathTaperY", String.Empty);
} }
private static void ProcessShpPathTwist(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPathTwist(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PathTwist = (sbyte)reader.ReadElementContentAsInt("PathTwist", String.Empty); shp.PathTwist = (sbyte)reader.ReadElementContentAsInt("PathTwist", String.Empty);
} }
private static void ProcessShpPathTwistBegin(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPathTwistBegin(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PathTwistBegin = (sbyte)reader.ReadElementContentAsInt("PathTwistBegin", String.Empty); shp.PathTwistBegin = (sbyte)reader.ReadElementContentAsInt("PathTwistBegin", String.Empty);
} }
private static void ProcessShpPCode(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpPCode(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.PCode = (byte)reader.ReadElementContentAsInt("PCode", String.Empty); shp.PCode = (byte)reader.ReadElementContentAsInt("PCode", String.Empty);
} }
private static void ProcessShpProfileBegin(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpProfileBegin(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.ProfileBegin = (ushort)reader.ReadElementContentAsInt("ProfileBegin", String.Empty); shp.ProfileBegin = (ushort)reader.ReadElementContentAsInt("ProfileBegin", String.Empty);
} }
private static void ProcessShpProfileEnd(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpProfileEnd(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.ProfileEnd = (ushort)reader.ReadElementContentAsInt("ProfileEnd", String.Empty); shp.ProfileEnd = (ushort)reader.ReadElementContentAsInt("ProfileEnd", String.Empty);
} }
private static void ProcessShpProfileHollow(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpProfileHollow(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.ProfileHollow = (ushort)reader.ReadElementContentAsInt("ProfileHollow", String.Empty); shp.ProfileHollow = (ushort)reader.ReadElementContentAsInt("ProfileHollow", String.Empty);
} }
private static void ProcessShpScale(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpScale(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.Scale = Util.ReadVector(reader, "Scale"); shp.Scale = Util.ReadVector(reader, "Scale");
} }
private static void ProcessShpState(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpState(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.State = (byte)reader.ReadElementContentAsInt("State", String.Empty); shp.State = (byte)reader.ReadElementContentAsInt("State", String.Empty);
} }
private static void ProcessShpLastAttach(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpLastAttach(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.LastAttachPoint = (byte)reader.ReadElementContentAsInt("LastAttachPoint", String.Empty); shp.LastAttachPoint = (byte)reader.ReadElementContentAsInt("LastAttachPoint", String.Empty);
} }
private static void ProcessShpProfileShape(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpProfileShape(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.ProfileShape = Util.ReadEnum<ProfileShape>(reader, "ProfileShape"); shp.ProfileShape = Util.ReadEnum<ProfileShape>(reader, "ProfileShape");
} }
private static void ProcessShpHollowShape(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpHollowShape(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.HollowShape = Util.ReadEnum<HollowShape>(reader, "HollowShape"); shp.HollowShape = Util.ReadEnum<HollowShape>(reader, "HollowShape");
} }
private static void ProcessShpSculptTexture(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpSculptTexture(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.SculptTexture = Util.ReadUUID(reader, "SculptTexture"); shp.SculptTexture = Util.ReadUUID(reader, "SculptTexture");
} }
private static void ProcessShpSculptType(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpSculptType(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.SculptType = (byte)reader.ReadElementContentAsInt("SculptType", String.Empty); shp.SculptType = (byte)reader.ReadElementContentAsInt("SculptType", String.Empty);
} }
private static void ProcessShpFlexiSoftness(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpFlexiSoftness(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.FlexiSoftness = reader.ReadElementContentAsInt("FlexiSoftness", String.Empty); shp.FlexiSoftness = reader.ReadElementContentAsInt("FlexiSoftness", String.Empty);
} }
private static void ProcessShpFlexiTension(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpFlexiTension(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.FlexiTension = reader.ReadElementContentAsFloat("FlexiTension", String.Empty); shp.FlexiTension = reader.ReadElementContentAsFloat("FlexiTension", String.Empty);
} }
private static void ProcessShpFlexiDrag(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpFlexiDrag(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.FlexiDrag = reader.ReadElementContentAsFloat("FlexiDrag", String.Empty); shp.FlexiDrag = reader.ReadElementContentAsFloat("FlexiDrag", String.Empty);
} }
private static void ProcessShpFlexiGravity(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpFlexiGravity(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.FlexiGravity = reader.ReadElementContentAsFloat("FlexiGravity", String.Empty); shp.FlexiGravity = reader.ReadElementContentAsFloat("FlexiGravity", String.Empty);
} }
private static void ProcessShpFlexiWind(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpFlexiWind(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.FlexiWind = reader.ReadElementContentAsFloat("FlexiWind", String.Empty); shp.FlexiWind = reader.ReadElementContentAsFloat("FlexiWind", String.Empty);
} }
private static void ProcessShpFlexiForceX(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpFlexiForceX(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.FlexiForceX = reader.ReadElementContentAsFloat("FlexiForceX", String.Empty); shp.FlexiForceX = reader.ReadElementContentAsFloat("FlexiForceX", String.Empty);
} }
private static void ProcessShpFlexiForceY(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpFlexiForceY(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.FlexiForceY = reader.ReadElementContentAsFloat("FlexiForceY", String.Empty); shp.FlexiForceY = reader.ReadElementContentAsFloat("FlexiForceY", String.Empty);
} }
private static void ProcessShpFlexiForceZ(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpFlexiForceZ(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.FlexiForceZ = reader.ReadElementContentAsFloat("FlexiForceZ", String.Empty); shp.FlexiForceZ = reader.ReadElementContentAsFloat("FlexiForceZ", String.Empty);
} }
private static void ProcessShpLightColorR(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpLightColorR(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.LightColorR = reader.ReadElementContentAsFloat("LightColorR", String.Empty); shp.LightColorR = reader.ReadElementContentAsFloat("LightColorR", String.Empty);
} }
private static void ProcessShpLightColorG(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpLightColorG(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.LightColorG = reader.ReadElementContentAsFloat("LightColorG", String.Empty); shp.LightColorG = reader.ReadElementContentAsFloat("LightColorG", String.Empty);
} }
private static void ProcessShpLightColorB(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpLightColorB(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.LightColorB = reader.ReadElementContentAsFloat("LightColorB", String.Empty); shp.LightColorB = reader.ReadElementContentAsFloat("LightColorB", String.Empty);
} }
private static void ProcessShpLightColorA(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpLightColorA(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.LightColorA = reader.ReadElementContentAsFloat("LightColorA", String.Empty); shp.LightColorA = reader.ReadElementContentAsFloat("LightColorA", String.Empty);
} }
private static void ProcessShpLightRadius(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpLightRadius(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.LightRadius = reader.ReadElementContentAsFloat("LightRadius", String.Empty); shp.LightRadius = reader.ReadElementContentAsFloat("LightRadius", String.Empty);
} }
private static void ProcessShpLightCutoff(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpLightCutoff(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.LightCutoff = reader.ReadElementContentAsFloat("LightCutoff", String.Empty); shp.LightCutoff = reader.ReadElementContentAsFloat("LightCutoff", String.Empty);
} }
private static void ProcessShpLightFalloff(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpLightFalloff(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.LightFalloff = reader.ReadElementContentAsFloat("LightFalloff", String.Empty); shp.LightFalloff = reader.ReadElementContentAsFloat("LightFalloff", String.Empty);
} }
private static void ProcessShpLightIntensity(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpLightIntensity(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.LightIntensity = reader.ReadElementContentAsFloat("LightIntensity", String.Empty); shp.LightIntensity = reader.ReadElementContentAsFloat("LightIntensity", String.Empty);
} }
private static void ProcessShpFlexiEntry(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpFlexiEntry(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.FlexiEntry = Util.ReadBoolean(reader); shp.FlexiEntry = Util.ReadBoolean(reader);
} }
private static void ProcessShpLightEntry(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpLightEntry(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.LightEntry = Util.ReadBoolean(reader); shp.LightEntry = Util.ReadBoolean(reader);
} }
private static void ProcessShpSculptEntry(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpSculptEntry(PrimitiveBaseShape shp, XmlReader reader)
{ {
shp.SculptEntry = Util.ReadBoolean(reader); shp.SculptEntry = Util.ReadBoolean(reader);
} }
private static void ProcessShpMedia(PrimitiveBaseShape shp, XmlTextReader reader) private static void ProcessShpMedia(PrimitiveBaseShape shp, XmlReader reader)
{ {
string value = reader.ReadElementContentAsString("Media", String.Empty); string value = reader.ReadElementContentAsString("Media", String.Empty);
shp.Media = PrimitiveBaseShape.MediaList.FromXml(value); shp.Media = PrimitiveBaseShape.MediaList.FromXml(value);
@ -1589,7 +1591,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
} }
} }
public static SceneObjectPart Xml2ToSOP(XmlTextReader reader) public static SceneObjectPart Xml2ToSOP(XmlReader reader)
{ {
SceneObjectPart obj = new SceneObjectPart(); SceneObjectPart obj = new SceneObjectPart();
@ -1610,7 +1612,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
return obj; return obj;
} }
public static TaskInventoryDictionary ReadTaskInventory(XmlTextReader reader, string name) public static TaskInventoryDictionary ReadTaskInventory(XmlReader reader, string name)
{ {
TaskInventoryDictionary tinv = new TaskInventoryDictionary(); TaskInventoryDictionary tinv = new TaskInventoryDictionary();
@ -1651,7 +1653,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
/// <param name="name">The name of the xml element containing the shape</param> /// <param name="name">The name of the xml element containing the shape</param>
/// <param name="errors">a list containing the failing node names. If no failures then null.</param> /// <param name="errors">a list containing the failing node names. If no failures then null.</param>
/// <returns>The shape parsed</returns> /// <returns>The shape parsed</returns>
public static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out List<string> errorNodeNames) public static PrimitiveBaseShape ReadShape(XmlReader reader, string name, out List<string> errorNodeNames)
{ {
List<string> internalErrorNodeNames = null; List<string> internalErrorNodeNames = null;

View File

@ -0,0 +1,249 @@
/*
* 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.Net;
using Mono.Addins;
using Nini.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenSim;
using OpenSim.ApplicationPlugins.RegionModulesController;
using OpenSim.Framework;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Tests.Common;
namespace OpenSim.Region.Framework.Scenes.Tests
{
public class SharedRegionModuleTests : OpenSimTestCase
{
// [Test]
public void TestLifecycle()
{
TestHelpers.InMethod();
TestHelpers.EnableLogging();
UUID estateOwnerId = TestHelpers.ParseTail(0x1);
UUID regionId = TestHelpers.ParseTail(0x10);
IConfigSource configSource = new IniConfigSource();
configSource.AddConfig("Startup");
configSource.AddConfig("Modules");
// // We use this to skip estate questions
// Turns out not to be needed is estate owner id is pre-set in region information.
// IConfig estateConfig = configSource.AddConfig(OpenSimBase.ESTATE_SECTION_NAME);
// estateConfig.Set("DefaultEstateOwnerName", "Zaphod Beeblebrox");
// estateConfig.Set("DefaultEstateOwnerUUID", estateOwnerId);
// estateConfig.Set("DefaultEstateOwnerEMail", "zaphod@galaxy.com");
// estateConfig.Set("DefaultEstateOwnerPassword", "two heads");
// For grid servic
configSource.AddConfig("GridService");
configSource.Configs["Modules"].Set("GridServices", "LocalGridServicesConnector");
configSource.Configs["GridService"].Set("StorageProvider", "OpenSim.Data.Null.dll:NullRegionData");
configSource.Configs["GridService"].Set("LocalServiceModule", "OpenSim.Services.GridService.dll:GridService");
configSource.Configs["GridService"].Set("ConnectionString", "!static");
LocalGridServicesConnector gridService = new LocalGridServicesConnector();
//
OpenSim sim = new OpenSim(configSource);
sim.SuppressExit = true;
sim.EnableInitialPluginLoad = false;
sim.LoadEstateDataService = false;
sim.NetServersInfo.HttpListenerPort = 0;
IRegistryCore reg = sim.ApplicationRegistry;
RegionInfo ri = new RegionInfo();
ri.RegionID = regionId;
ri.EstateSettings.EstateOwner = estateOwnerId;
ri.InternalEndPoint = new IPEndPoint(0, 0);
MockRegionModulesControllerPlugin rmcp = new MockRegionModulesControllerPlugin();
sim.m_plugins = new List<IApplicationPlugin>() { rmcp };
reg.RegisterInterface<IRegionModulesController>(rmcp);
// XXX: Have to initialize directly for now
rmcp.Initialise(sim);
rmcp.AddNode(gridService);
TestSharedRegion tsr = new TestSharedRegion();
rmcp.AddNode(tsr);
// FIXME: Want to use the real one eventually but this is currently directly tied into Mono.Addins
// which has been written in such a way that makes it impossible to use for regression tests.
// RegionModulesControllerPlugin rmcp = new RegionModulesControllerPlugin();
// rmcp.LoadModulesFromAddins = false;
//// reg.RegisterInterface<IRegionModulesController>(rmcp);
// rmcp.Initialise(sim);
// rmcp.PostInitialise();
// TypeExtensionNode node = new TypeExtensionNode();
// node.
// rmcp.AddNode(node, configSource.Configs["Modules"], new Dictionary<RuntimeAddin, IList<int>>());
sim.Startup();
IScene scene;
sim.CreateRegion(ri, out scene);
sim.Shutdown();
List<string> co = tsr.CallOrder;
int expectedEventCount = 6;
Assert.AreEqual(
expectedEventCount,
co.Count,
"Expected {0} events but only got {1} ({2})",
expectedEventCount, co.Count, string.Join(",", co));
Assert.AreEqual("Initialise", co[0]);
Assert.AreEqual("PostInitialise", co[1]);
Assert.AreEqual("AddRegion", co[2]);
Assert.AreEqual("RegionLoaded", co[3]);
Assert.AreEqual("RemoveRegion", co[4]);
Assert.AreEqual("Close", co[5]);
}
}
class TestSharedRegion : ISharedRegionModule
{
// FIXME: Should really use MethodInfo
public List<string> CallOrder = new List<string>();
public string Name { get { return "TestSharedRegion"; } }
public Type ReplaceableInterface { get { return null; } }
public void PostInitialise()
{
CallOrder.Add("PostInitialise");
}
public void Initialise(IConfigSource source)
{
CallOrder.Add("Initialise");
}
public void Close()
{
CallOrder.Add("Close");
}
public void AddRegion(Scene scene)
{
CallOrder.Add("AddRegion");
}
public void RemoveRegion(Scene scene)
{
CallOrder.Add("RemoveRegion");
}
public void RegionLoaded(Scene scene)
{
CallOrder.Add("RegionLoaded");
}
}
class MockRegionModulesControllerPlugin : IRegionModulesController, IApplicationPlugin
{
// List of shared module instances, for adding to Scenes
private List<ISharedRegionModule> m_sharedInstances = new List<ISharedRegionModule>();
// Config access
private OpenSimBase m_openSim;
public string Version { get { return "0"; } }
public string Name { get { return "MockRegionModulesControllerPlugin"; } }
public void Initialise() {}
public void Initialise(OpenSimBase sim)
{
m_openSim = sim;
}
/// <summary>
/// Called when the application loading is completed
/// </summary>
public void PostInitialise()
{
foreach (ISharedRegionModule module in m_sharedInstances)
module.PostInitialise();
}
public void AddRegionToModules(Scene scene)
{
List<ISharedRegionModule> sharedlist = new List<ISharedRegionModule>();
foreach (ISharedRegionModule module in m_sharedInstances)
{
module.AddRegion(scene);
scene.AddRegionModule(module.Name, module);
sharedlist.Add(module);
}
foreach (ISharedRegionModule module in sharedlist)
{
module.RegionLoaded(scene);
}
}
public void RemoveRegionFromModules(Scene scene)
{
foreach (IRegionModuleBase module in scene.RegionModules.Values)
{
// m_log.DebugFormat("[REGIONMODULE]: Removing scene {0} from module {1}",
// scene.RegionInfo.RegionName, module.Name);
module.RemoveRegion(scene);
}
scene.RegionModules.Clear();
}
public void AddNode(ISharedRegionModule module)
{
m_sharedInstances.Add(module);
module.Initialise(m_openSim.ConfigSource.Source);
}
public void Dispose()
{
// We expect that all regions have been removed already
while (m_sharedInstances.Count > 0)
{
m_sharedInstances[0].Close();
m_sharedInstances.RemoveAt(0);
}
}
}
}

View File

@ -458,9 +458,9 @@ namespace OpenSim.Region.Framework.Scenes
if (null == assetBase) if (null == assetBase)
return; return;
MemoryStream ms = new MemoryStream(assetBase.Data); using (MemoryStream ms = new MemoryStream(assetBase.Data))
StreamReader sr = new StreamReader(ms); using (StreamReader sr = new StreamReader(ms))
{
sr.ReadLine(); // Unknown (Version?) sr.ReadLine(); // Unknown (Version?)
sr.ReadLine(); // Unknown sr.ReadLine(); // Unknown
sr.ReadLine(); // Unknown sr.ReadLine(); // Unknown
@ -486,7 +486,8 @@ namespace OpenSim.Region.Framework.Scenes
// If it can be parsed as a UUID, it is an asset ID // If it can be parsed as a UUID, it is an asset ID
UUID uuid; UUID uuid;
if (UUID.TryParse(id, out uuid)) if (UUID.TryParse(id, out uuid))
assetUuids[uuid] = (sbyte)AssetType.Animation; assetUuids[uuid] = (sbyte)AssetType.Animation; // the asset is either an Animation or a Sound, but this distinction isn't important
}
} }
} }

View File

@ -487,7 +487,8 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding)); report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding));
report.AppendFormat( report.AppendFormat(
"{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}\n", "{0,8} {1,7} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7}\n",
"Max",
"Total", "Total",
"Resend", "Resend",
"Land", "Land",
@ -499,7 +500,8 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", ""); report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", "");
report.AppendFormat( report.AppendFormat(
"{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}", "{0,8} {1,7} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7}\n",
"kb/s",
"kb/s", "kb/s",
"kb/s", "kb/s",
"kb/s", "kb/s",
@ -548,7 +550,8 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding)); report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
report.AppendFormat( report.AppendFormat(
"{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}", "{0,8} {1,7} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7}",
(ci.maxThrottle * 8) / 1000,
(ci.totalThrottle * 8) / 1000, (ci.totalThrottle * 8) / 1000,
(ci.resendThrottle * 8) / 1000, (ci.resendThrottle * 8) / 1000,
(ci.landThrottle * 8) / 1000, (ci.landThrottle * 8) / 1000,
@ -584,7 +587,8 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
ThrottleRates throttleRates = udpServer.ThrottleRates; ThrottleRates throttleRates = udpServer.ThrottleRates;
report.AppendFormat( report.AppendFormat(
"{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}", "{0,8} {1,7} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7}",
"-",
(throttleRates.Total * 8) / 1000, (throttleRates.Total * 8) / 1000,
(throttleRates.Resend * 8) / 1000, (throttleRates.Resend * 8) / 1000,
(throttleRates.Land * 8) / 1000, (throttleRates.Land * 8) / 1000,

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