Compare commits

...

300 Commits

Author SHA1 Message Date
Justin Clark-Casey (justincc)
df031fe8be extend TestClientThrottleRegionLimited for 2 clients after testing 1. Renames to TestSingleClientThrottleRegionLimited() 2014-11-25 23:21:37 +00:00
Justin Clark-Casey (justincc)
dce98acb69 Add regression test TestClientThrottleRegionLimited() for testing simple behaviour of throttles where a region-wide total outbound limit is in place. 2014-11-25 23:21:37 +00:00
Justin Clark-Casey (justincc)
075f718f3f factor out common throttle setting byte[] array construction in ThrottleTests. 2014-11-25 23:21:37 +00:00
Justin Clark-Casey (justincc)
9cdd38d0cf Add regression test TestClientThrottleLimited() for throttle behaviour when a max client total limit is enforced server-side 2014-11-25 23:21:37 +00:00
Justin Clark-Casey (justincc)
fc878a33ed refactor: consistently put all test classes in the OpenSim.Tests.Common package rather than some in OpenSim.Tests.Common.Mock
the separate mock package was not useful and was just another using line to always add
2014-11-25 23:21:37 +00:00
Justin Clark-Casey (justincc)
af0a851eba minor: disable logging in regression test TestClientThrottleSetNoLimit 2014-11-25 23:18:40 +00:00
Justin Clark-Casey (justincc)
9934e2c545 minor: comment out unused method in regression BasicCircuitTests 2014-11-25 23:18:40 +00:00
Justin Clark-Casey (justincc)
746defa094 Add basic regression test ThrottleTests.TestClientThrottleSetNoLimit 2014-11-25 23:18:40 +00:00
Justin Clark-Casey (justincc)
52370ac94d refactor: Move test clientstack setup code out of BasicCircuitTests into OpenSim.Tests.Common.ClientStackHelpers 2014-11-25 23:18:40 +00:00
Justin Clark-Casey (justincc)
87d5da86a1 Fix recent regression in "debug lludp throttles get" command that stopped it printing any information. Also fix max throttle displayed to be properly kbps 2014-11-25 23:18:40 +00:00
Justin Clark-Casey (justincc)
a13022c296 minor: in "show server throttles", display unset if new client throttle value is not set rather than 0 2014-11-25 23:18:40 +00:00
Justin Clark-Casey (justincc)
44e0a2f906 Add throttle-max option to "debug lludp throttles set" to allow runtime setting of default and existing client throttles.
Doesn't yet adjust until clients submit new throttle settings.
2014-11-25 23:18:40 +00:00
Justin Clark-Casey (justincc)
5c13980eb7 Change "debug lludp throttle *" commands to "debug lludp throttles" for consistency (and because I keep typing throttles).
This will still work with "debug lludp throttle" anyway.
2014-11-25 23:18:40 +00:00
Justin Clark-Casey (justincc)
a4209d2df4 small adjustment to commented out scene_throttle_max_bps and client_throttle_max_bps examples in OpenSimDefaults.ini
Make them actually reflect 20 mbit and 1.5 mbit respectively
2014-11-25 23:18:40 +00:00
Justin Clark-Casey (justincc)
c5cd93db81 Change help text for client_throttle_max_bps in OpenSimDefaults.ini to state it is in bytes, not bits
This is the same as already done for scene_throttle_max_bps
Internally, the token buckets are in bytes and the other help text makes it clear that the number is bytes per second
(though with the wrong assumption that 1 mbit = 1024 * 1024 bits whereas 1 mbit = 1000 kbits = 1000000 bits)
2014-11-25 23:18:40 +00:00
Justin Clark-Casey (justincc)
d20aeefef2 Fix console set and get of max scene rate. Was performing wrong calculation - throttle buckets are set in bytes, not bits 2014-11-25 23:18:40 +00:00
Justin Clark-Casey (justincc)
10d09e287c Eliminate 'max' throttle setting from server throttles report since this never applies. 2014-11-25 23:18:40 +00:00
Justin Clark-Casey (justincc)
679eaec22f Allow "debug lludp throttle *" commands to work without a user name, in which case they apply to all users in the lludp server 2014-11-25 23:18:39 +00:00
Justin Clark-Casey (justincc)
a142edec03 minor: add apparant total to logging when client sets throttles 2014-11-25 23:18:39 +00:00
Justin Clark-Casey (justincc)
c73e62ea3a minor: fix bug in throttle logging where arguments were mismatched 2014-11-25 23:18:39 +00:00
Justin Clark-Casey (justincc)
1d33a40f59 Add "debug lludp set scene-throttle-max <value>" console command to allow us to potentially set the scene max throttle on the fly. 2014-11-25 23:18:39 +00:00
Justin Clark-Casey (justincc)
a5eabdade3 Move information about "server agent rate" throttles into "show server throttles" command rather than "show throttles"
THis allows us to see the rates when no client is connected to the region.
2014-11-25 23:18:39 +00:00
Justin Clark-Casey (justincc)
c8f5add2fc Add "show server throttles" command for showing server specific information about throttles
This is separate from the user-oriented "show throttles" command since one will often only want to know about varying client throttle settings.
Currently displays max scene throttle and adaptive throttles config if set.
2014-11-25 23:18:39 +00:00
Justin Clark-Casey (justincc)
bb5e2e1f02 refactor: Use simpler auto-implemented property for HttpPort in GridRegion 2014-11-25 23:18:39 +00:00
Justin Clark-Casey (justincc)
13e2af7525 minor: Remove compiler warning from GridRegion in IGridService 2014-11-25 23:18:39 +00:00
Justin Clark-Casey (justincc)
968b588bb9 minor: remove compiler warning from OpenProfileClient 2014-11-25 23:18:39 +00:00
Justin Clark-Casey (justincc)
51eb8facd6 Add OutgoingPacketsQueuedCount clientstack stat.
This is the total of queued outgoing packets across all connections, as also seen in the "show queues" command.
Gives some early indication of whether the simulator can't send all outgoing packets fast enough.
Though then one would want to check that this isn't due to a few bad client connections.
2014-11-25 23:18:39 +00:00
Justin Clark-Casey (justincc)
4c5fbf8b0a minor: Remove compiler warnings from unused fields in TokenBucket 2014-11-25 23:18:39 +00:00
Justin Clark-Casey (justincc)
12daa3c3d9 refactor: Move LLUDPServer console commands into their own class. 2014-11-25 23:18:39 +00:00
Justin Clark-Casey (justincc)
f0fd2fa325 refactor: rename "debug lludp throttle status" to "debug lludp throttle get" to match set command 2014-11-25 23:18:38 +00:00
Justin Clark-Casey (justincc)
e144958e03 Add "debug lludp throttle set" command to allow setting of parameters at runtime
Can currently only set adaptive true|false, where adaptive = false
2014-11-25 23:18:38 +00:00
Justin Clark-Casey (justincc)
b9b483151f Eliminate a few unnecessary calculations in the maintenance loop.
Also uses wait event instead of sleep for periodicity control.
2014-11-25 23:18:38 +00:00
Justin Clark-Casey (justincc)
7d30bb13be Fix recent minor regression where the default frame time wasn't being set if there was no startup config section.
Caused some regression tests to fail.
2014-11-25 23:18:38 +00:00
Justin Clark-Casey (justincc)
8d72145112 If Bullet is running on its own thread, use a reset event to control timing rather than a sleep.
In theory, there should be no difference between these mechanisms.
However, on at least Mono 3.2.8 waiting via an event appears to be much more accurate.
2014-11-25 23:18:38 +00:00
Justin Clark-Casey (justincc)
7bababaab6 Improve frame time stability by taking a few unnecessary repeated calculations out of the main scene loop.
Also uses a wait event to sleep rather than a Thread.Sleep to allow the loop to be interrupted in a more controlled manner when necessary.
2014-11-25 23:18:38 +00:00
Justin Clark-Casey (justincc)
23561239ee Make BulletSim thread be ThreadPriority.Highest if running
Will only effect Windows or mono with a patch such as https://gist.github.com/justincc/31e52218d098529b4696 applied
For test purposes
2014-11-25 23:18:38 +00:00
Justin Clark-Casey (justincc)
cfc4055991 Make outboudn and packet inbox handling threads highest priority.
Will only have any affect under Windows or mono with a patch such as https://gist.github.com/justincc/31e52218d098529b4696 (not recommended) applied.
For assessment purposes.
2014-11-25 23:18:38 +00:00
Justin Clark-Casey (justincc)
5b6fb7245a Set ThreadPriority on main scene thread to highest.
This will only have an effect on Windows systems or mono with the (not recommended) mono-3.2.8 debug patch https://gist.github.com/justincc/31e52218d098529b4696 applied
2014-11-25 23:18:38 +00:00
Justin Clark-Casey (justincc)
d3ed5de77d Add loglevel to jobengine that can be controlled via "debug jobengine loglevel <level>".
Defaults to 0
Level 1 currently does verbose logging about every queued and processed job.
2014-11-25 23:18:38 +00:00
Justin Clark-Casey (justincc)
9fb3065d33 Temporarily add root agent rez attachments work to job engine if it is running rather than as a fire and forget.
Experiment to see if serializing attachment rez and send initial data jobs improves other parts of sim performance.
2014-11-25 23:18:38 +00:00
Justin Clark-Casey (justincc)
859b1c5ba4 Add experimental job engine to see if queueing some existing async work during root agent entry to a region improves perf rather than always attempting to execute everything concurrently
Job engine is controlled via "debug jobengine start|stop|status".
Can only currently be enabled and disabled dynamically at runtime.
Currently only applies to code sending initial region data (objects, other avatar data) to a client.
2014-11-25 23:18:37 +00:00
Justin Clark-Casey (justincc)
c5a0f0ba36 Temporary hack to disable av to av collisions in bulletsim.
Need to do this for a test.  Final implementation will be properly controlled through a property.
2014-11-25 23:18:37 +00:00
BlueWall
41cc73233c Re-work handling of email notifications settings. 2014-11-24 11:00:47 -05:00
BlueWall
12108bf6e9 Fix handling of user preference updates where no email address is supplied 2014-11-23 14:25:48 -05:00
Diva Canto
7813780eba Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-11-22 20:14:31 -08:00
Diva Canto
0997ce8629 Small improvements to SimulatorFeaturesModule: (1) don't overwrite extras if the grid response is invalid; (2) make the name of the config variable for destination guide consistent with the grid-wide name in LoginService; (3) account for the existence of a [USERID] in the destination guide URL 2014-11-22 20:14:09 -08:00
Justin Clark-Casey (justincc)
5bc389ff71 When logging reigon information returned by GateKeeperService.GetHyperlinkRegion, log the return server URL returned.
This helps diagnoses misconfiguration where, for instance, a LAN ExternalHostName has been configured that isn't reachable externally.
2014-11-21 20:40:59 +00:00
Diva Canto
8d3cb424a8 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-11-21 08:54:30 -08:00
Diva Canto
27512f3b42 Cleanup extraneous comments from viewer support modules 2014-11-21 08:54:10 -08:00
Cinder
cfaf904a3b LSL key should be implicitly cast to a boolean value
Signed-off-by: James Hughes <jamesh@ascent.bluewallgroup.com>
2014-11-20 11:32:46 -06:00
AliciaRaven
c155656349 Minor: Include missing EventHost power for group owner role. 2014-11-19 20:25:27 +00:00
Justin Clark-Casey
3247a7cb3e refactor: capitalize SOP.moveToTarget() and stopMoveToTarget() in accordance with code guidelines and the rest of the methods. 2014-11-19 20:12:28 +00:00
Justin Clark-Casey
7a2c77e7ea If calling llStopMoveToTarget() on an in-world prim, don't send an unnecessary object update if the prim was not moving to target.
This involves making PhysicsActor.PIDActive get as well as set.
On physics components that don't implement this (all characters and some phys engines) we return false.
2014-11-19 20:06:56 +00:00
Justin Clark-Casey
bdebd525db Remove SOP.StopMoveToTarget scheduled update which is now being done in SOG.stopMoveToTarget() as of last commit 67e568 2014-11-19 19:16:03 +00:00
Justin Clark-Casey
67e56872f3 If llStopMoveToTarget() is called on an attachment, then stop the avatar if it was moving to target.
Same behaviour as on Linden Lab grid.
Will probably also address http://opensimulator.org/mantis/view.php?id=7369 by not generating spurious object updates when llStopMoveToTarget() is called in attachments where the avatar is not moving.
2014-11-19 19:08:33 +00:00
AliciaRaven
b9f870fa73 Minor: Update LLLoginService to handle explicitly set login locations that include decimal precision. Fractions might be introduced if setting the initial login location from a viewer splash screen with data from the DataSnapshot service. At present the fractions cause regex to fail when matching the login string causing an exception. 2014-11-19 18:44:45 +00:00
Dev Random
d3b43a96fb Add 'terrain feature' command 2014-11-19 18:18:18 +00:00
Diva Canto
6a8353af36 Improved SpecialUIModule so that it sends the floater data properly. 2014-11-16 10:27:10 -08:00
Diva Canto
1a02e5d2db Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-11-11 20:42:42 -08:00
Diva Canto
32293cfd6b Fix the fetching of module references in the viewer support modules.
Remove the detachment of attachments in camera-only, because it doesn't work for HG people, and it's too drastic of a move.
2014-11-11 20:42:13 -08:00
Justin Clark-Casey
5aa8ba1b45 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:59:56 +00:00
Diva Canto
89cb07eb49 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-11-10 21:18:33 -08:00
Diva Canto
5e34727b7e Add additional viewer support modules that allow certain viewers to modify their UI on the fly. 2014-11-10 19:03:06 -08:00
Justin Clark-Casey
4123b0fdbd minor: correct console response when setting attachments logging level 2014-11-10 23:48:59 +00:00
Diva Canto
f1fc557715 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-11-06 17:49:36 -08:00
Diva Canto
ac051ef4ab Added grid information to SimFeatures response, so that the viewer can show it. 2014-11-06 17:49:04 -08:00
Justin Clark-Casey (justincc)
f084320976 Actually persist a changed console set agent-limit via "region set".
Unfortunately, it's not currently easy to do this with "max-agent-limit"
- this must be separately set as MaxAgents in region config if it's to persist over restarts.
2014-10-31 22:36:08 +00:00
Justin Clark-Casey (justincc)
a05be7bd65 Add "region set" console command.
This current allows one to set two region parameters
agent-limit <int> will set the current root agent limit for the region, as also settable through the viewer, though some impose a max setting (e.g. 100).
max-agent-limit <int> will set the maximum allowed root agent limit.  This can also be set via the MaxAgent parameter in region config.
2014-10-31 21:47:12 +00:00
Justin Clark-Casey (justincc)
23fb4f2221 Add "region get" command as a synononym for "show region" console command.
This matches existing similar commands and a soon to be added "region set" command.
2014-10-31 21:47:07 +00:00
justincc
26606190e5 Update libomv to cedac55
This resolves an issue with pCampbot where some bots would occasionally connect with the same UDP source port.
This sometimes led to console messages where bots would report receiving packets multiple times that weren't marked as resends.
DLLs built under windows
2014-10-30 22:56:57 +00:00
Kevin Cozens
466657375a Revert my commit that fixed unexpected behaviour re: parcel prim limits.
Others think different about how limits work so another solution is needed.

This reverts commit ff62b90636.
2014-10-30 18:05:16 -04:00
Kevin Cozens
ff62b90636 Use parcel prim limit (not region limit) when checking if area is full. 2014-10-30 11:21:27 -04:00
BlueWall
b463870914 Add hypergrid teleporting support to user profiles picks 2014-10-27 17:27:42 -04:00
justincc
c995b07818 Refresh OpenMetaverse libraries again at 0f4b361 but with Windows builds to see if this resolves some user problems. 2014-10-24 22:54:53 +01:00
BlueWall
94250b6836 Fix some typecasting in PgSQL Groups adapter 2014-10-16 21:16:44 -04:00
Justin Clark-Casey (justincc)
c8664e8907 Add some more llGiveInventory() regression tests 2014-10-16 19:54:40 +01:00
BlueWall
b7550c947b Experimental XAssets Module PgSQL Adapter: Remove unused migration. Syntax error preventing migration from running. 2014-10-16 12:34:04 -04:00
Melanie Thielker
04612f41a7 Fix transferring inventory from prims to agent inventory 2014-10-16 03:46:45 +02:00
BlueWall
8a93d97320 Touchup PgSQL XAssets adapter 2014-10-15 17:28:51 -04:00
BlueWall
b45c929d66 Fix over zealous chopping of text when editing (pilot error) 2014-10-15 09:55:41 -04:00
BlueWall
5c9ef4d083 Fix logging level to Error in exception handlers 2014-10-15 09:42:29 -04:00
BlueWall
231cdc2dc1 Cleanup unused code 2014-10-15 09:31:39 -04:00
BlueWall
1812cecdb7 Fix PgSQL adapter for UserProfiles 2014-10-15 09:08:25 -04:00
BlueWall
a6f8f9d003 Get V2 Groups working under PgSQL. Needed to re-create tables to satisy the generic handler type matching. There should be no existing data because it couldn't complete the first migration as-is. 2014-10-12 13:48:39 -04:00
BlueWall
300e78bfd5 Make column names lower-case, change hash column type to bytea and remove old commented lines of code 2014-10-12 10:50:32 -04:00
BlueWall
7af878a4f4 Fix some errors in PgSQL XAssets by changing some data types. Also make sql query syntax more in line with the PgSQL AssetData implementation. 2014-10-10 19:58:07 -04:00
Justin Clark-Casey (justincc)
00b23e51ae Change name of just added OSSL osForceSit() to osForceOtherSit()
This is somewhat more in keeping with something like osForceAttachToOtherAvatarFromInventory()
and potentially allows a separate osForceSit() command with High threat rather than VeryHigh that only sits the owner and can be enabled without enabling sit of other avatars.
2014-10-11 00:14:35 +01:00
Justin Clark-Casey (justincc)
5acbbcb33f minor: spacing cleanup from previous commit 79a4d1ea 2014-10-11 00:10:49 +01:00
Vegaslon
79a4d1ea8d Implements osForceSit(string avatar) & overload osForceSit(string avatar, string target)
Allows a script IN the target prim to force an avatar to sit on it using normal methods as if called by the client.

Overload method of osForceSit() to allow a script NOT in the target prim to force an avatar to sit on the target prim using normal methods as if called by the client.

This patch is based on previous work from
http://opensimulator.org/mantis/view.php?id=4492
and also includes the suggestions from justincc including change of threat level
Thank you Christos Lightling.
2014-10-11 00:04:25 +01:00
Justin Clark-Casey (justincc)
5db3f08871 minor: add --default-user option to "load oar" help long description. Do other small tidies of "load oar" console command help. 2014-10-11 00:03:05 +01:00
BlueWall
c7a11899f6 Give ability to define constants that may be used throught the configuration 2014-10-09 14:59:54 -04:00
Justin Clark-Casey (justincc)
29a05cdeb5 Change thread of osForceAttachToOvtherAvatarFromInventory to VeryHigh from Severe
It fits much better in this category.
2014-10-08 23:35:25 +01:00
Justin Clark-Casey (justincc)
458ccd26ff Use Scene or IEntityTransferModule directly in HGEntityTransferModule instead of casting or re-obtaining module.
This code originates from when IEntityTransferModule was shared rather than one per region.
Now it's one per region we know that callers are always in the same scene as the module.
2014-10-08 23:16:01 +01:00
AliciaRaven
8d4c1945c2 HG Restricted appearance checking code is only called when HG teleporting via the map but bypassed completely when teleporting via landmarks. This fixes this by including a call when acting on landmarks. Does not affect local grid teleports as flags are checked. 2014-10-08 23:04:19 +01:00
Justin Clark-Casey (justincc)
cbd428cff3 Add LSL transaction_result event.
This is cinderblocks' transaction_result.diff from http://opensimulator.org/mantis/view.php?id=7329 but I have used lsl.parser.cs and lsl.lexer.cs files generated directly from opensim-libs rather than those supplied in the patch.
I also added scriptEvents.transaction_reuslt.
The required parser/lexer generation file changes were made in commit d564f28 in the opensim-libs repo.
Thanks!
2014-10-04 00:16:47 +01:00
Justin Clark-Casey (justincc)
c496bd57b4 minor: Comment out received seed caps request logging for now 2014-10-02 22:33:58 +01:00
Justin Clark-Casey (justincc)
43520b3e8b Add "debug lludp throttle status" command to return status information about a client's throttle (currently just whether adaptive is enabled). 2014-10-02 22:30:44 +01:00
Justin Clark-Casey (justincc)
05508b5c56 Add "debug lludp throttle log <level> <avatar-first-name> <avatar-last-name>" to control extra throttle related debug logging. 2014-10-02 22:30:44 +01:00
Justin Clark-Casey (justincc)
2a9528fa22 Don't unnecessarily remove from backup objects that were not directly attached from the scene.
These are never in region backup in the first place since recent 11830c43
Extend regression test to check backup status.
2014-10-02 22:30:44 +01:00
Justin Clark-Casey (justincc)
57e75d7c03 Do not add attachments to the region scene object backup list.
Attachment persistence is not handled in this way and this just results in a load of busy work until a check in each SOG terminates a backup check for attachments anyway.
2014-10-02 22:30:44 +01:00
Justin Clark-Casey (justincc)
afa85e6b3c Set appearance refresh to false by default.
This setting was originally added some time ago to deal with issues where appearance was not received properly by all users.
However, it does not scale well with large numbers of agents.
Disabling to see if the original problem has abated or whether this will have to be tackled in another way.
2014-10-02 22:30:44 +01:00
BlueWall
1a24b7fa93 Fix key name in example Regions.ini file 2014-09-28 23:04:49 -04:00
Diva Canto
4e28a06f3c Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-09-28 16:10:57 -07:00
Diva Canto
763c22b28e Improve on the last commit to InventoryArchiver: put back the original constructor (3rd party modules use it), change order of new parameters to make it more consistent. 2014-09-28 16:10:32 -07:00
AliciaRaven
f0218258d1 When a prim is bought through BuySellModule, the click action is not changed back from buy object. This means that after the object is bought, it still appears as if for sale which can be confusing. This sets it back to touch, the default after sale.
Signed-off-by: BlueWall <jamesh@bluewallgroup.com>
2014-09-27 12:54:00 -04:00
Justin Clark-Casey (justincc)
530b0cbbf1 Move expired objects cleaning trigger to the maintenance thread of a region rather than it's main scene loop.
[Startup] default setting UpdateTempCleaningEveryNFrames becomes UpdateTempCleaningEveryNSeconds.
Default becomes 180s instead of effective 182s (which would also vary with any changes in frame time or extra long frames)
2014-09-27 00:23:52 +01:00
Justin Clark-Casey (justincc)
31c8b7fd1a Fix recent regression with llRegionSayTo() started sending messages twice.
Addresses http://opensimulator.org/mantis/view.php?id=7330
Fixed by removing chat delivery to avatar from WorldCommModule.DeliverMessageTo(), in common with existing similar methods that only handle deliver to script listeners.
Preserves fixes from http://opensimulator.org/mantis/view.php?id=5005
2014-09-26 23:35:29 +01:00
Roger Kirkman
36a1f1c70c Add missing HGInventoryService responsible for creating My Suitcase to StandaloneHypergrid.ini 2014-09-26 23:08:04 +01:00
Justin Clark-Casey (justincc)
23a0946e36 Fix long-lived thread name logging. 2014-09-26 01:10:49 +01:00
Justin Clark-Casey (justincc)
9fcee73326 Make "generate map" console command also trigger upload to maptiles as well as asset generation without performing tile generation twice. 2014-09-26 01:02:19 +01:00
Justin Clark-Casey (justincc)
d3578e2662 Add "debug lludp data out" console command for logging outgoing data just before it's put on the wire.
Unlike "debug lludp packet" which logs at the point where OpenSim first asks the clientstack to send a certain outgoing packet, this logs immediately before the actual send.
For low-level debugging purposes.
2014-09-24 23:44:55 +01:00
Justin Clark-Casey (justincc)
7852bae78f Update libopenmetaverse to 0f4b361.
Primarily to get a small message logging improvement for pCampbot.
2014-09-24 23:44:51 +01:00
Justin Clark-Casey (justincc)
6ac12a42ec Add "debug lludp packet" command to pCampbot.
This allows one to log the packets received by a particular bot that are not duplicates of already received packets.
Similar to the OpenSimulator command at the same name but currently any positive level logs all received packets.
No facility yet for logging outgoing packets.
For debug purposes.
2014-09-24 23:44:48 +01:00
Justin Clark-Casey (justincc)
c015cb3134 Remove an unnecessary check at the bottom of Scene.CloseAgent()
At this point sp != null so no check required.
2014-09-24 00:50:24 +01:00
Jak Daniels
bde60cc92e Add persistent command history in console
Signed-off-by: BlueWall <jamesh@bluewallgroup.com>
2014-09-23 10:36:00 -04:00
AliciaRaven
1e22091193 Modifications to previous IAR commits to bring them more inline with existing OpenSim code conventions. Also include new IAR save switch in console help print out. 2014-09-23 00:04:59 +01:00
AliciaRaven
5bc3bbbcf3 Add an event callback for loading IAR files. The callback for creating them already existed but not for loading. This is of interest for use by region modules. Also includes reporting numbers of items saved and items filtered to the completed log printout. 2014-09-23 00:04:53 +01:00
AliciaRaven
08675d44a7 Change existing IAR save to use UUID for its callback reference instead of Guid. This is for uniformity as discussed on IRC. 2014-09-23 00:04:50 +01:00
AliciaRaven
3bde737f76 Include same content filters for IAR file exports that already exist for OAR files. Adds new console switch --perm=CTM to save iar command. 2014-09-23 00:04:45 +01:00
Justin Clark-Casey (justincc)
c73b02d583 Replace two connecting bots state booleans in pCampbot with a single state machine.
Also adds "show status" command to pCampbot that currently just shows bot connecting state
2014-09-22 23:13:19 +01:00
Justin Clark-Casey (justincc)
8d177296ad Reinsert OpenMetaverse.dll from commit fbdf507 from an accidental replace in f1f935e
This only affected pCampbot.
2014-09-22 22:22:09 +01:00
Diva Canto
c4cd98bc34 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2014-09-21 09:23:15 -07:00
Diva Canto
94619cba58 Fixed a hard-to-run-into bug in groups: at the time of creation of a group, the OwnerRoleID in the groups table was inconsistent with the roleID in the roles table. OpenSim core was not running into this bug, but 3rd party modules (like Wifi) were. 2014-09-21 09:22:32 -07:00
Robert Adams
2ed3a918bd Merge branch 'master' into bullet-2.82 2014-09-21 07:11:00 -07:00
BlueWall
519c753e46 This fixes the Scene thread renaming issue 2014-09-17 20:25:27 -04:00
BlueWall
96a2449122 Undo "Revert "Small changes to threading to send thread names to unmanaged threads. Needs Mono 3.6+ to see thread names in utilities like top -H . Some formatting of the thread name to fin in the 16 byte limit on Linux. Please test on Windows to see if the work has any adverse effects.""
Fix for break in next commit

This reverts commit 376fab1402.
2014-09-17 20:03:54 -04:00
Justin Clark-Casey (justincc)
1f40630a9a Add eeyore to contributors 2014-09-17 23:45:53 +01:00
Edward
427240f935 Changes to be committed: modified: OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs modified: OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs This solves mantis bug# 5005: llRegionSay script does not trigger ChatFromWorld event. This was solved by adding World.SimChat() command to the llRegionSay() function (per suggestion of DrCuriosity). Additionally this fixes llRegionSayTo() which was also not functioning by adding a World.SimChat() command and adding a new SimChatToAgent() overrided function to Scene.PacketHandlers.cs This is the second patch revision. Corrections made to the position of World.SimChat() and removal of tabs per suggestion by justincc. 2014-09-17 23:37:18 +01:00
BlueWall
376fab1402 Revert "Small changes to threading to send thread names to unmanaged threads. Needs Mono 3.6+ to see thread names in utilities like top -H . Some formatting of the thread name to fin in the 16 byte limit on Linux. Please test on Windows to see if the work has any adverse effects."
This reverts commit af286d5fcb.
Issue with Jenkins builds
2014-09-17 18:11:41 -04:00
BlueWall
af286d5fcb Small changes to threading to send thread names to unmanaged threads. Needs Mono 3.6+ to see thread names in utilities like top -H . Some formatting of the thread name to fin in the 16 byte limit on Linux. Please test on Windows to see if the work has any adverse effects. 2014-09-17 17:56:10 -04:00
Justin Clark-Casey (justincc)
2d3072f053 When osNpcMoveToTarget() is called for a sitting avatar then silently do nothing rather than throwing an error.
Resolves http://opensimulator.org/mantis/view.php?id=7311
2014-09-12 23:37:44 +01:00
Justin Clark-Casey (justincc)
3f35c5a421 Add cinderblocks and bobshaffer2 to contributors. 2014-09-12 00:36:45 +01:00
Justin Clark-Casey (justincc)
70953dbfcd Fix issues where setting llSetTextureAnim(FALSE... did not work properly).
I ended up amalgamating patches from http://opensimulator.org/mantis/view.php?id=7313 and http://opensimulator.org/mantis/view.php?id=7318
Thanks a lot to both bobshaffer2 and cinderblocks.
2014-09-12 00:34:39 +01:00
Justin Clark-Casey (justincc)
a3bd708e77 Fix regression from recent a02dae5 where stand positions are no longer correct when a sit target is specified.
Adjusts stand position using just avatar position relative to the root prim instead.
Fixes http://opensimulator.org/mantis/view.php?id=7315 and preserves previous fix for http://opensimulator.org/mantis/view.php?id=7299
2014-09-11 20:59:20 +01:00
Justin Clark-Casey (justincc)
b4ce71df1e Make proper fix for last commit wrt Mantis 7317 by replacing disallowed c char and not literal 'c' 2014-09-09 18:57:02 +01:00
Justin Clark-Casey (justincc)
e271607bef For stat names containing periods, replace with '#' rather than throw exception
In relation to http://opensimulator.org/mantis/view.php?id=7317
2014-09-09 18:56:58 +01:00
Robert Adams
e5b269e9a0 Merge branch 'master' into bullet-2.82 2014-09-05 21:20:02 -07:00
Justin Clark-Casey (justincc)
41f2f3132b For monitoring purposes, start non-timeout tasks (which do not currently use a threadpool) via Watchdog.RunInThread() rather than Util.RunThreadNoTimeout()
The functionality is the same but this allow us to monitor such tasks via "show threads" and abort them for test purposes, etc.
Also extends thread names to provide more info (e.g. SendInitialDataToClient says what client the task is for).
2014-09-05 23:20:59 +01:00
Justin Clark-Casey (justincc)
e4d16e6795 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-04 18:24:59 +01:00
Robert Adams
47ac103df7 Merge branch 'master' into bullet-2.82 2014-09-03 21:21:01 -07:00
Justin Clark-Casey (justincc)
73e20b7f5f For processing outbound http requests in the XMLRPCModule, start the thread through Watchdog for monitoring and stat purposes. 2014-09-04 00:22:30 +01:00
Justin Clark-Casey (justincc)
0692ebfbc6 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 00:00:51 +01:00
Justin Clark-Casey (justincc)
4b04d22899 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-03 23:53:04 +01:00
Justin Clark-Casey (justincc)
6e6512eb4a 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-03 23:43:59 +01:00
Justin Clark-Casey (justincc)
29400538b7 minor: fix indenting from previous commit b08ab1e 2014-09-03 23:37:20 +01:00
Justin Clark-Casey (justincc)
b08ab1e375 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-03 23:35:18 +01:00
BlueWall
e19d1ecce8 Cleanup some unused code and configuration entries 2014-09-03 17:09:57 -04:00
Kevin Cozens
40c579addf Don't show the ScrLPS data twice in the WebStats based statistics page. 2014-09-03 14:17:37 -04:00
BlueWall
3e5bc75f89 Remove the 32 bit launchers as discussed at OpenSimulator Office Hour 9//2/14 http://opensimulator.org/wiki/Chat_log_from_the_meeting_on_2014-09-02. Find the binaries, sources and README in ./share/32BitLaunch if needed. 2014-09-03 13:00:09 -04:00
BlueWall
e8ca900ef8 Move the 32 bit launchers as discussed at OpenSimulator Office Hour 9//2/14 http://opensimulator.org/wiki/Chat_log_from_the_meeting_on_2014-09-02. 2014-09-03 12:57:29 -04:00
Justin Clark-Casey (justincc)
ac866a1c46 Add [EntityTransfer] AllowAvatarCrossing setting to determine whether avatars are allowed to cross regions at all.
Defaults to true.  For test purposes.
2014-09-03 00:25:56 +01:00
Justin Clark-Casey (justincc)
d582db6132 Fix recent regression from 473c5594 where camera started to judder on moving vehicles.
Other parts of OpenSimulator are relying on SP.Velocity == 0 for vehicles.
So add and use SP.GetWorldVelocity() instead when we need vehicle velocity, along the same lines as existing SP.GetWorldRotation()
2014-09-02 23:39:52 +01:00
Robert Adams
3d65d22138 Merge branch 'master' into bullet-2.82 2014-08-30 08:29:39 -07:00
Justin Clark-Casey (justincc)
473c559478 As per the LL grid, if an avatar is sitting then return it's velocity relative to the region rather than relative to its seat.
Resolves http://opensimulator.org/mantis/view.php?id=7175
2014-08-30 01:09:33 +01:00
Justin Clark-Casey (justincc)
bb7c88805a As per the LL grid, for attachments make llGetObjectDetails() OBJECT_VELOCITY return the avatar's velocity and not always Vector3.Zero.
This completes http://opensimulator.org/mantis/view.php?id=7177
2014-08-30 00:58:47 +01:00
Justin Clark-Casey (justincc)
4d8bc007e2 minor: fix wrong indentation in previous commit 0cc3cd 2014-08-30 00:54:36 +01:00
Justin Clark-Casey (justincc)
0cc3cdfb4e As per the LL grid, for attachments make llGetObjectDetails() OBJECT_ROT return the avatar's rotation.
This is already the behaviour of OBJECT_POS.
Partially satisfies http://opensimulator.org/mantis/view.php?id=7177
2014-08-30 00:48:59 +01:00
Justin Clark-Casey (justincc)
a02dae566c Fix issue where moving a seated avatar would not adjust their subsequent stand position.
Addresses http://opensimulator.org/mantis/view.php?id=7299
2014-08-30 00:26:18 +01:00
Justin Clark-Casey (justincc)
099212167b Implement STATUS_BLOCK_GRAB_OBJECT in llSetStatus()/llGetStatus() and correct effect of STATUS_BLOCK_GRAB
As per http://wiki.secondlife.com/wiki/LlSetStatus
Setting STATUS_BLOCK_GRAB_OBJECT prevents or allows move of a physical linkset by grab on any prim.
Setting STATUS_BLOCK_GRAB prevents or allows move of a physical linkset by grab on a particular prim.
Previously, setting STATUS_BLOCK_GRAB would prevent drag via all prims of the linkset.
2014-08-29 23:40:21 +01:00
Justin Clark-Casey (justincc)
1b75ec5647 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-08-29 19:08:23 +01:00
Justin Clark-Casey (justincc)
3555c0c3f3 Fix recent regression test TestDeserializeXmlObjectWithOtherParts() which was not meant to indent the input xml 2014-08-29 18:14:47 +01:00
Justin Clark-Casey (justincc)
305c3e668a Add regression test for deserializing xml objects with more than one non-root part. 2014-08-29 18:06:29 +01:00
Justin Clark-Casey (justincc)
1a3ffda852 minor: Eliminate more unnecessary code copying individual parameters for Vector3 copying in Scene - this is not necessary as Vector3 is a value type 2014-08-28 18:37:34 +01:00
Justin Clark-Casey (justincc)
f132f642b2 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-08-28 18:15:33 +01:00
Justin Clark-Casey (justincc)
b1ff78f4d8 Don't allow update timer to invoke another scene update if the previous is still active. 2014-08-26 18:52:09 +01:00
Justin Clark-Casey (justincc)
bafa82eb12 Remove race conditions from where SP.AbsolutePosition could change between the various property checks. 2014-08-26 18:25:14 +01:00
Justin Clark-Casey (justincc)
42bb122232 Fix frame times when updating scene on timer. 2014-08-26 18:13:38 +01:00
Justin Clark-Casey (justincc)
64f640f901 Implement experimental non-default mechanism to update scene via a timer rather than a persistent thread with sleep.
This is to see if an inaccuracy in sleep times under load is responsible for increase in frame times even when there is spare time still available.
Can currently only be activated by setting "debug scene set update-on-timer true".
Can be switched between timer and thread with sleep updates whilst the scene is running.
2014-08-26 18:13:38 +01:00
Robert Adams
b3e423303f Merge branch 'master' into bullet-2.82 2014-08-26 06:47:50 -07:00
BlueWall
aeadddf77a Add back URL endings in examples 2014-08-25 20:29:46 -04:00
Justin Clark-Casey (justincc)
fabab7414f Remove database connection locking in MySQLXAssetData. This is unnecessary as connections aren't shared and transactions are already in place where necessary. 2014-08-22 20:34:33 +01:00
Justin Clark-Casey (justincc)
0cb805a64c Remove query locking in MySQLUserProfileData. This is not necessary as the connection is not shared. 2014-08-22 20:28:56 +01:00
Justin Clark-Casey (justincc)
709038aa2a 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-08-22 20:23:48 +01:00
Justin Clark-Casey (justincc)
d899bdcb9b Remove lock in MySQLFramework. This is not necessary as the connection is not shared. 2014-08-22 19:52:03 +01:00
Justin Clark-Casey (justincc)
f129b824c3 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-08-22 19:46:46 +01:00
Robert Adams
7ba3b88fb6 Merge branch 'master' into bullet-2.82 2014-08-21 06:36:19 -07:00
Robert Adams
28ef6f83fc Fix typo in OpenSimDefaults.ini comment 2014-08-21 06:35:27 -07:00
Robert Adams
674be72225 BulletSim: add new Bullet 2.82 constraint type codes and rename the
BulletSim fixed constraint to not be confused with the native version.
2014-08-21 06:33:04 -07:00
Justin Clark-Casey (justincc)
4e03d352c3 Extend drop command to "debug lludp drop <in|out>..." to allow drop of inbound packets.
For test/debug purposes.
2014-08-19 18:43:21 +01:00
Justin Clark-Casey (justincc)
298376d5c7 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-08-19 18:34:17 +01:00
Justin Clark-Casey (justincc)
ce74418c20 minor:Give console feedback when we sit or stand pCampbot bots.
Also only write console lines for actually connected bots.
2014-08-19 00:58:33 +01:00
Justin Clark-Casey (justincc)
88b2fc61ff Add clientstack.<scene>.OQRERequestsWaiting stat
Only present if OQRE is enabled
2014-08-19 00:42:19 +01:00
Justin Clark-Casey (justincc)
84cea46c10 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-08-19 00:17:12 +01:00
Justin Clark-Casey (justincc)
b375f86f11 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-08-19 00:17:12 +01:00
Robert Adams
64cf75866e BulletSim: Windows and Linux 32 and 64 bit versions of Bullet 2.82 2014-08-18 15:52:49 -07:00
Kevin Cozens
321816b32c Prevent exception if inventory item in llGiveInventory() call doesn't exist. 2014-08-18 16:00:49 -04:00
Justin Clark-Casey (justincc)
3a643e2456 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-08-15 22:44:31 +01:00
Justin Clark-Casey (justincc)
1d2933ca51 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-08-15 22:41:00 +01:00
Justin Clark-Casey (justincc)
e0c6bfa81e 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-08-15 21:47:34 +01:00
Justin Clark-Casey (justincc)
91e1aaa5d4 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-08-15 21:47:34 +01:00
Kevin Cozens
626536b8cc Added RestrictEmail to make llEmail only send to avatars email address if true. 2014-08-14 02:40:06 -04:00
Justin Clark-Casey (justincc)
4c781db572 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-08-14 01:39:26 +01:00
Justin Clark-Casey (justincc)
6ea82ad48a Make some existing reprioritization values changeable outside the scene for test purposes, and use more consise property syntax.
No functional change.
2014-08-14 01:16:58 +01:00
BlueWall
dabb8e62f4 Update OpenID server handler with proper interface. fixes http://opensimulator.org/mantis/view.php?id=7301 2014-08-13 20:06:07 -04:00
Justin Clark-Casey (justincc)
bc0895c758 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-08-13 23:45:51 +01:00
Justin Clark-Casey (justincc)
0d2a25b477 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-08-13 23:11:32 +01:00
Justin Clark-Casey (justincc)
0db6f3a2bd Only set up the UnackedMethod for an outgoing message if that message is actually meant to get an ack (because it's reliable). 2014-08-13 22:57:14 +01:00
Justin Clark-Casey (justincc)
21176a3a90 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-08-13 22:38:27 +01:00
Justin Clark-Casey (justincc)
f1f935ed95 Add 'server' stats information to pCampbot, as used elsewhere in OpenSimulator
This adds the "show stats", "stats record", etc. commands and information on available Threadpool threads, etc.
It also adds the Watchdog which logs warnings if time between executions is unexpectedly large.
2014-08-13 19:53:42 +01:00
Justin Clark-Casey (justincc)
f1cec684e2 For pCampbot, set max number of permitted connections to an endpoint to int.MaxValue
This is to avoid issues where many bots connect to a single end point with multiple regions, where each region requires a long-lived poll connection for each bot.
2014-08-12 18:46:09 +01:00
Justin Clark-Casey (justincc)
fbdf507e98 Update libomv libraries with those built from commit 2208379.
This is to resolve some issues for pCampbot, chiefly with capability connection and inbound handling.
2014-08-12 01:53:48 +01:00
Melanie Thielker
37921c66e5 Avination's Dynamic Floater Module. This works with Singularity viewer only.
It's WIP in that a dialog builder is on it's way. For now, the XML needs to
be handmade.
2014-08-12 01:04:29 +02:00
Justin Clark-Casey (justincc)
8738445eb7 Move the inventory request lock introduced in git master a58152bd to HGInventoryBroker to preserve that behaviour there but allow 2 simultaneous inv requests (chiefly WebFetch) rather than 1
This lock serialized all requests and made the inventory throttling in WebFetch redundant.
By moving this lock, two simultaneous requests may now take place which may help with http://opensimulator.org/mantis/view.php?id=7054
2014-08-09 00:52:51 +01:00
Justin Clark-Casey (justincc)
30f1b424bb Change RootRotationUpdateTolerance from 0.01 to 0.1 in code as well. 2014-08-08 23:47:53 +01:00
Justin Clark-Casey (justincc)
36f01dce2d Change MaxPoolThreads default in code as well from 15 to 300 2014-08-08 23:47:03 +01:00
Justin Clark-Casey (justincc)
91f3be71e3 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-08-08 23:39:40 +01:00
Justin Clark-Casey (justincc)
a483525016 Change default max threads if SmartThreadPool is used as the main thread pool from 15 to 300
Running out of such threads under heavy load causes delayed packet processing which can lead to spurious UDP resends and knock on issues.
We already massively boost the min/max builtin pool worker and IOCP threads (which even with STP are still used for inbound network requests) without obvious adverse effects.
The threads are only instantiated if they are required.
This change does not affect other async_call_method options.
2014-08-08 23:34:49 +01:00
BlueWall
2924d250ab Fix short help string for show region command. 2014-08-06 21:41:53 -04:00
BlueWall
10a8d2852e OpenSimExtras
Move the experimental extra features functionality into the GridService. This sends default values for map, search and destination guide, plus ExportSupported control to the region on startup. Please watch http://opensimulator.org/wiki/SimulatorFeatures_Extras for changes and documentation.
2014-08-06 17:25:12 -04:00
Oren Hurvitz
e36e416637 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-06 19:02:15 +03:00
Justin Clark-Casey (justincc)
78ccadb27e 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-08-06 00:53:14 +01:00
Justin Clark-Casey (justincc)
961cb9cc77 refactor: Rename recent new Client*UpdateTolerance to Root*UpdateTolerance for better accuracy and consistency with other similar parameters 2014-08-06 00:35:26 +01:00
Oren Hurvitz
dc2471fedd Fixed premature closing of the connection in DataSnapshotManager 2014-08-05 19:09:11 +03:00
Justin Clark-Casey (justincc)
0e71e3889c 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-08-05 01:37:10 +01:00
Justin Clark-Casey (justincc)
fcc665a567 Put pCampbot "disconnect" command on separate thread like "connect" so that we can continue to run status commands whilst bots are disconnecting. 2014-08-05 01:15:07 +01:00
Justin Clark-Casey (justincc)
e57e9e95d4 Allow "show bots" pCampbot console command to quickly report status by not locking entire bot list for almost 100% of connection time. 2014-08-05 01:07:08 +01:00
Justin Clark-Casey (justincc)
d6890d78ad 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:52:04 +01:00
BlueWall
de3421b408 Fix typo in log message 2014-08-02 08:21:25 -04:00
Justin Clark-Casey (justincc)
7cec4997db Fix regression in SimulatorFeatures module that would stop OpenSimulator from starting if no [SimulatorFeatures] section was present in config. 2014-08-01 20:29:25 +01:00
Justin Clark-Casey (justincc)
dfd0c2a54a 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-07-31 21:32:20 +01:00
Justin Clark-Casey (justincc)
6ab463a446 Don't overwrite the null result with the true result is groups service REMOVEAGENTFROMGROUP call has failed because of missing parameters 2014-07-31 21:20:55 +01:00
BlueWall
cac910d401 Add region-side extra feature setting for destination guide 2014-07-31 08:20:06 -04:00
Robert Adams
50ed97aa1a BulletSim: thread safe handling of list of avatars.
Fix for 7284 which is an enumeration exception when starting up a region.
2014-07-30 21:49:57 -07:00
Justin Clark-Casey (justincc)
6c4eed5539 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-07-31 00:32:35 +01:00
BlueWall
3ec695e05b Add Chat module extra feature settings to GridExtraFeatures service 2014-07-30 15:01:26 -04:00
BlueWall
e0d8f42e6b Simulator Extra Features Service
Provide a means for regions to fetch extra features supported by modern viewers from a central location
.
2014-07-30 11:24:39 -04:00
Justin Clark-Casey (justincc)
a4107cb6c7 In TerrainModule, lock m_perClientPatchUpdates when removing entries.
This may have been the trigger CheckSendingPatchesToClients() dictionary out of sync exceptions in today's load test.
Don't need to check ContainsKey() since Remove() returns false on a request to remove a key that it doesn't have
2014-07-29 23:39:10 +01:00
Justin Clark-Casey (justincc)
fcf5fb5dfd 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-07-29 18:54:16 +01:00
Justin Clark-Casey (justincc)
0f87a99e54 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-07-29 18:09:11 +01:00
Justin Clark-Casey (justincc)
5cd21516a4 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-07-29 03:26:14 +01:00
Justin Clark-Casey (justincc)
f54fccba1e 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-07-29 03:13:10 +01:00
Justin Clark-Casey (justincc)
3654ae8d8c 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-07-29 01:21:15 +01:00
Justin Clark-Casey (justincc)
df816b38ac minor: make "debug scene set" usage command accurate again from last commit f6f7585 2014-07-29 00:20:35 +01:00
Justin Clark-Casey (justincc)
f6f7585ec5 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-07-29 00:13:29 +01:00
Robert Adams
9c804466e5 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-07-26 16:03:43 -07:00
Justin Clark-Casey (justincc)
327632dc66 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.)
2014-07-26 02:17:04 +01:00
Justin Clark-Casey (justincc)
56a623ac0c Fix issue with TestTextureNotFound in previous commit 1e3027a
Stop failure by actually giving the test handler a path instead of null
2014-07-26 01:56:42 +01:00
Justin Clark-Casey (justincc)
1e3027afb1 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-07-26 01:41:03 +01:00
Justin Clark-Casey (justincc)
c0c92a95bf Add undocumented RemoteRequestTimeout seconds parameter to xinventory requests
This is for testing purposes (chiefly http://opensimulator.org/mantis/view.php?id=7054) so many not be permanent
Setting this will change the xinventory request timeout from the simulator from the default 100 seconds
2014-07-25 23:06:23 +01:00
Justin Clark-Casey (justincc)
8c5c9806d7 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-07-25 23:00:41 +01:00
Michael Cerquoni
46781253c3 fix comments in physics section of [Startup] to reflect the actual default engine. 2014-07-25 12:30:09 -04:00
Justin Clark-Casey (justincc)
e85291329b Add suppression of grid-side "show regions" command in simulator console for Hypergrid setups as well as normal grid.
Should have been done in recent commit 6048dfcd
Resolves http://opensimulator.org/mantis/view.php?id=7281
2014-07-25 02:02:07 +01:00
Justin Clark-Casey (justincc)
cc61681484 Revert "Write UDP statistics to the log, not just the console (e.g., "show queues")"
Fixes http://opensimulator.org/mantis/view.php?id=7280
It can't be done this way because the stats data needs to show up on the console at all log levels, not just debug.
But this means setting it to log at fatal, which is not appropriate for this stuff in the log.
I understand the desire but this has to be done some other way, perhaps by (yet another) config parameter.
Also, this was already being done with the ClientStatsReport but that also should be done in another way, I think.

This reverts commit 5d53412766.
2014-07-25 01:56:41 +01:00
Justin Clark-Casey (justincc)
086bc6f748 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-07-24 20:03:19 +01:00
Justin Clark-Casey (justincc)
3a87cce2e0 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-07-22 18:04:28 +01:00
Justin Clark-Casey (justincc)
36920adb96 minor: convert tabs to spaces that got in on recent commit 4a9282e 2014-07-21 23:58:30 +01:00
Justin Clark-Casey (justincc)
3c6becd524 On login and first HG entrance to a foreign grid, perform query access checks before proceeding. 2014-07-21 23:53:33 +01:00
Justin Clark-Casey (justincc)
3355bedaeb 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-07-21 23:08:15 +01:00
Justin Clark-Casey (justincc)
200dcee1b7 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-07-21 22:55:38 +01:00
root
1a9c14b041 Revert "Removed unused files: Texture/Mesh server connectors"
This reverts commit f6ea5088f4.
2014-07-21 21:25:48 +00:00
BlueWall
4a9282e681 Add missing parts to profiles - classified delete 2014-07-21 12:46:26 -04:00
Oren Hurvitz
899bcb7acd 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-07-21 09:29:51 +01:00
Oren Hurvitz
712c50e0bf Don't append attachments multiple times 2014-07-21 09:29:50 +01:00
Oren Hurvitz
feacae173e Fixed avatar hovering above the ground. The avatar physics capsule was too tall.
This is related to http://opensimulator.org/mantis/view.php?id=7067 .
But that bug complains about BulletSim, and this fix is for ODE.
2014-07-21 09:27:57 +01:00
Oren Hurvitz
4804edf77f Allow reading the BulletSim detail log while the sim is running 2014-07-21 09:27:57 +01:00
Oren Hurvitz
2d034e20c4 XBakes: store the assets only in the sim's local assets cache; not in the main assets server. Also, some cleanup. 2014-07-21 09:27:56 +01:00
Oren Hurvitz
11031abf26 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-07-21 09:27:47 +01:00
Oren Hurvitz
6b57b61836 Log RestClient requests similarly to WebClient (e.g, "debug http all 6" logs the entire request and response) 2014-07-21 09:24:45 +01:00
Oren Hurvitz
4c5d7d4683 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-07-21 09:23:13 +01:00
Oren Hurvitz
b481711fa6 Added locking in AccessModule to prevent possible errors when shutting down a simulator that has >1 region 2014-07-21 09:19:05 +01:00
Oren Hurvitz
05cacf6eb6 Eliminated common but un-useful log messages 2014-07-21 09:18:20 +01:00
Oren Hurvitz
f94b3bbe0f Minor: changed "existant" to "existent" 2014-07-21 09:15:05 +01:00
Oren Hurvitz
3cb31e9685 Removed warning about YieldProlog 2014-07-21 09:12:30 +01:00
Oren Hurvitz
46c1d4e319 pCamBot: download Meshes
The "Sculpt" field in prims is used for both Sculpties (where the assets are Textures), and real meshes. Meshes require a different download URL than textures.
2014-07-21 09:12:16 +01:00
Oren Hurvitz
470161ae2e Write some pCampBot messages to the log 2014-07-21 09:11:51 +01:00
Oren Hurvitz
af3498efdb In "show throttles", show the maximum drip rate. This shows whether a client is being throttled due to past poor performance. 2014-07-21 09:10:50 +01:00
Oren Hurvitz
5d53412766 Write UDP statistics to the log, not just the console (e.g., "show queues") 2014-07-21 09:10:19 +01:00
Oren Hurvitz
0d70033a5d 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-07-21 09:09:17 +01:00
Oren Hurvitz
528704bc04 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-07-21 08:31:20 +01:00
Oren Hurvitz
a57b4b81b9 Fixed the logic that decides if a packet was queued (it was reversed) 2014-07-21 08:31:09 +01:00
Oren Hurvitz
f6ea5088f4 Removed unused files: Texture/Mesh server connectors 2014-07-21 08:30:23 +01:00
Oren Hurvitz
48d1cca303 Better logging of threadpool activity in Overload mode: if we didn't log "Queue threadfunc" for a particular thread then don't log "Run threadfunc" or "End threadfunc" for that thread either. 2014-07-21 08:30:17 +01:00
Oren Hurvitz
9fa8d84598 Eliminated some warnings 2014-07-21 08:30:10 +01:00
Oren Hurvitz
99ac770abb Close streams immediately when we finish using them 2014-07-21 08:30:03 +01:00
Robert Adams
b81187db5a Set "[Terrain]SendTerrainUpdatesByViewDistance=true" by default.
This, by default, enables terrain patches being sent to each avatar
from the avatar away (rather than the old outside-in pattern), only
sending terrain patches within the avatars view distance (making
view loading quicker), and sending multiple terrain patches per
protocol packet (making terrain loading and editing quicker).
2014-07-20 10:56:52 -07:00
Robert Adams
aa8b44c001 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-07-20 10:34:09 -07:00
Vegaslon
738c60459c BulletSim: Modify first and default vehicle vertical attractor to be feature complete with use of the Limit Roll Only Flag.
Signed-off-by: Robert Adams <misterblue@misterblue.com>
2014-07-18 19:07:00 -07:00
Justin Clark-Casey (justincc)
d1b7c2ece3 minor: remove long unused RegionInfo.ignoreIncomingConfiguration 2014-07-19 01:15:15 +01:00
Justin Clark-Casey (justincc)
29d5950838 minor: remove long unused RegionInfo.commFailTF 2014-07-19 01:10:53 +01:00
Justin Clark-Casey (justincc)
4dc0aaa03f minor: Add meters unit to water height console display 2014-07-18 23:57:33 +01:00
Justin Clark-Casey (justincc)
1bdf0bed9c Add "show region" command which will show parameters for current region.
This shows static data (e.g. region agent limit) whereas "show scene" shows live data (sim fps, current prims, etc.)
2014-07-18 23:52:49 +01:00
Justin Clark-Casey (justincc)
6048dfcd71 In grid mode, add SuppressConsoleCommands flag to [GridService] so that we can stop misleading grid service only console commands from registering.
We need to do this because the simulator initializes and internal copy of the GridService in grid mode for internal purposes
2014-07-18 22:57:04 +01:00
Justin Clark-Casey (justincc)
a26d1ffc66 minor: add method doc to ICommands.HasCommand() 2014-07-18 22:31:04 +01:00
Justin Clark-Casey (justincc)
9be935ac6d Add ICommands.HasCommand() method so that we can detect whether a command has already been registered without needing to also run it 2014-07-18 22:27:39 +01:00
Justin Clark-Casey (justincc)
f0853139d5 refactor: slightly adjust some code in ODECharacter.Move() to eliminate a condition check without changing the logic 2014-07-18 18:13:38 +01:00
Justin Clark-Casey (justincc)
cfbfca6447 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-07-18 18:03:30 +01:00
Robert Adams
1daec26ba0 BulletSim: rearrange code to prevent using null pointers when a
child mesh is not available when building a linkset.
2014-07-17 21:41:39 -07:00
Michael Cerquoni
e455374a4b fix all instances of "non-existant" to "non-existent" (spelling mistakes) thanks Ai Austin for pointing this out. 2014-07-17 09:37:24 -04:00
Justin Clark-Casey (justincc)
8cd7ca568d Change default script stop method to co-op instead of abort.
co-op should be more stable as it doesn't abort threads, which can trigger virtual machine instability
This change will be invisible to users as script DLLs are recompiled automatically where necessary, though the change won't take affect until the next simulator restart.
This change has no effect on existing script state.
If you want to continue using abort, set ScriptStopStrategy = abort in the [XEngine] section of OpenSim.ini
2014-07-16 22:58:38 +01:00
Justin Clark-Casey (justincc)
d62acc7e37 Update information in OpenSimDefaults to reflect the fact that ScriptStopStrategy in [XEngine] can now be changed without manually deleting old compiled scripts. 2014-07-14 20:53:06 +01:00
Justin Clark-Casey (justincc)
0c8f3dddd8 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-07-14 20:08:11 +01:00
Justin Clark-Casey (justincc)
e008d54cd4 minor: Remove compiler warning in GridService 2014-07-14 19:28:43 +01:00
Dev Random
4e92b55231 Call RemoveScriptInstance when removing from inventory 2014-07-14 18:06:24 +01:00
Justin Clark-Casey (justincc)
2766bf3fef minor: Move debug xengine script console command to Debug help section where other debug commands live. 2014-07-11 00:18:39 +01:00
Justin Clark-Casey (justincc)
15b38f0036 minor: further cleanup of old vb and yield prolog script engine references that were removed some time ago 2014-07-11 00:15:47 +01:00
Justin Clark-Casey (justincc)
d7b9260496 If [XEngine] ScriptStopStrategy is changed between abort and co-op, for the existing session use the previous strategy for that script rather than not starting the script at all.
We have to do this since we can't unload existing DLLs if they're all in the same AppDomain.
But we can still update the underlying DLL which will be used in the next simulator session.
2014-07-11 00:03:02 +01:00
Justin Clark-Casey (justincc)
6d3b409af2 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-07-10 19:40:44 +01:00
Justin Clark-Casey (justincc)
fea18a909f Fix bug in "show modules" comamnd that was showing shared modules as non-shared and non-shared as shared 2014-07-09 23:24:12 +01:00
Justin Clark-Casey (justincc)
a8860d79d8 Turn RestClient.Request() logging down the debug and comment out for now. 2014-07-09 23:12:14 +01:00
Justin Clark-Casey (justincc)
8ae5ab809f 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-07-08 18:49:57 +01:00
324 changed files with 22041 additions and 16043 deletions

1
.gitignore vendored
View File

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

View File

@@ -72,10 +72,12 @@ what it is today.
* Allen Kerensky
* BigFootAg
* BlueWall Slade
* bobshaffer2
* brianw/Sir_Ahzz
* CharlieO
* ChrisDown
* Chris Yeoh (IBM)
* cinderblocks
* controlbreak
* coyled
* ctrlaltdavid (David Rowe)
@@ -88,6 +90,7 @@ what it is today.
* DoranZemlja
* dr0b3rts
* dslake
* eeyore
* FredoChaplin
* Garmin Kawaguichi
* Gerhard

View File

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

View File

@@ -325,6 +325,13 @@ namespace OpenSim.Groups
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
im.toAgentID = im.fromAgentID;
im.fromGroup = true;

View File

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

View File

@@ -32,6 +32,7 @@ using System.Reflection;
using System.Text;
using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces;
@@ -560,7 +561,7 @@ namespace OpenSim.Groups
// so we have the list of urls to send the notice to
// this may take a long time...
Util.RunThreadNoTimeout(delegate
Watchdog.RunInThread(delegate
{
foreach (string u in urls)
{
@@ -571,7 +572,7 @@ namespace OpenSim.Groups
hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID));
}
}
}, "AddGroupNotice", null);
}, string.Format("AddGroupNotice (agent {0}, group {1})", RequestingAgentID, groupID) , null);
return true;
}

View File

@@ -209,11 +209,13 @@ namespace OpenSim.Groups
string agentID = request["AgentID"].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);
result["RESULT"] = "true";
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
}

View File

@@ -285,11 +285,13 @@ namespace OpenSim.Groups
string agentID = request["AgentID"].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);
result["RESULT"] = "true";
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
}

View File

@@ -69,6 +69,7 @@ namespace OpenSim.Groups
GroupPowers.DeleteRole |
GroupPowers.Eject |
GroupPowers.FindPlaces |
GroupPowers.HostEvent |
GroupPowers.Invite |
GroupPowers.JoinChat |
GroupPowers.LandChangeIdentity |
@@ -150,7 +151,8 @@ namespace OpenSim.Groups
data.Data["ShowInList"] = showInList ? "1" : "0";
data.Data["AllowPublish"] = allowPublish ? "1" : "0";
data.Data["MaturePublish"] = maturePublish ? "1" : "0";
data.Data["OwnerRoleID"] = UUID.Random().ToString();
UUID roleID = UUID.Random();
data.Data["OwnerRoleID"] = roleID.ToString();
if (!m_Database.StoreGroup(data))
return UUID.Zero;
@@ -159,7 +161,6 @@ namespace OpenSim.Groups
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, UUID.Zero, "Everyone", "Everyone in the group", "Member of " + name, (ulong)DefaultEveryonePowers, true);
// Create Owner role
UUID roleID = UUID.Random();
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, roleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true);
// Add founder to group
@@ -247,6 +248,9 @@ namespace OpenSim.Groups
if (group == null)
return members;
// Unfortunately this doesn't quite work on legacy group data because of a bug
// that's also being fixed here on CreateGroup. The OwnerRoleID sent to the DB was wrong.
// See how to find the ownerRoleID a few lines below.
UUID ownerRoleID = new UUID(group.Data["OwnerRoleID"]);
RoleData[] roles = m_Database.RetrieveRoles(GroupID);
@@ -255,6 +259,11 @@ namespace OpenSim.Groups
return members;
List<RoleData> rolesList = new List<RoleData>(roles);
// Let's find the "real" ownerRoleID
RoleData ownerRole = rolesList.Find(r => r.Data["Powers"] == ((long)OwnerPowers).ToString());
if (ownerRole != null)
ownerRoleID = ownerRole.RoleID;
// Check visibility?
// When we don't want to check visibility, we pass it "all" as the requestingAgentID
bool checkVisibility = !RequestingAgentID.Equals(UUID.Zero.ToString());
@@ -291,17 +300,17 @@ namespace OpenSim.Groups
{
m.Title = selected.Data["Title"];
m.AgentPowers = UInt64.Parse(selected.Data["Powers"]);
m.AgentID = d.PrincipalID;
m.AcceptNotices = d.Data["AcceptNotices"] == "1" ? true : false;
m.Contribution = Int32.Parse(d.Data["Contribution"]);
m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
// Is this person an owner of the group?
m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
members.Add(m);
}
m.AgentID = d.PrincipalID;
m.AcceptNotices = d.Data["AcceptNotices"] == "1" ? true : false;
m.Contribution = Int32.Parse(d.Data["Contribution"]);
m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
// Is this person an owner of the group?
m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
members.Add(m);
}
return members;
@@ -393,13 +402,15 @@ namespace OpenSim.Groups
return true;
}
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
public bool RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
{
// check perms
if (RequestingAgentID != AgentID && !HasPower(RequestingAgentID, GroupID, GroupPowers.Eject))
return;
return false;
_RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
return true;
}
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)

View File

@@ -131,19 +131,27 @@ namespace OpenSim.Groups
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
MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
if (membership != null)
{
if (token != string.Empty && token.Equals(membership.Data["AccessToken"]))
RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
{
return RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
}
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);
return false;
}
}
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string groupName, string token)

View File

@@ -215,18 +215,7 @@ namespace OpenSim.OfflineIM
rootElement.AppendChild(result);
return 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();
return Util.DocToBytes(doc);
}
#endregion

View File

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

View File

@@ -68,7 +68,10 @@ namespace OpenSim.Framework.Capabilities
/// <returns></returns>
public static object LLSDDeserialize(byte[] b)
{
return LLSDDeserialize(new MemoryStream(b, false));
using (MemoryStream ms = new MemoryStream(b, false))
{
return LLSDDeserialize(ms);
}
}
/// <summary>
@@ -78,21 +81,23 @@ namespace OpenSim.Framework.Capabilities
/// <returns></returns>
public static object LLSDDeserialize(Stream st)
{
XmlTextReader reader = new XmlTextReader(st);
reader.Read();
SkipWS(reader);
using (XmlTextReader reader = new XmlTextReader(st))
{
reader.Read();
SkipWS(reader);
if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "llsd")
throw new LLSDParseException("Expected <llsd>");
if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "llsd")
throw new LLSDParseException("Expected <llsd>");
reader.Read();
object ret = LLSDParseOne(reader);
SkipWS(reader);
reader.Read();
object ret = LLSDParseOne(reader);
SkipWS(reader);
if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != "llsd")
throw new LLSDParseException("Expected </llsd>");
if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != "llsd")
throw new LLSDParseException("Expected </llsd>");
return ret;
return ret;
}
}
/// <summary>

View File

@@ -52,12 +52,12 @@ namespace OpenSim.Data
public int sizeY;
/// <summary>
/// Return the x-coordinate of this region.
/// Return the x-coordinate of this region in region units.
/// </summary>
public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } }
/// <summary>
/// Return the y-coordinate of this region.
/// Return the y-coordinate of this region in region units.
/// </summary>
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 string m_connectionString;
private object m_dbLock = new object();
protected virtual Assembly Assembly
{
@@ -107,47 +106,46 @@ namespace OpenSim.Data.MySQL
override public AssetBase GetAsset(UUID assetID)
{
AssetBase asset = null;
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(
"SELECT name, description, assetType, local, temporary, asset_flags, CreatorID, data FROM assets WHERE id=?id",
dbcon))
{
dbcon.Open();
cmd.Parameters.AddWithValue("?id", assetID.ToString());
using (MySqlCommand cmd = new MySqlCommand(
"SELECT name, description, assetType, local, temporary, asset_flags, CreatorID, data FROM assets WHERE id=?id",
dbcon))
try
{
cmd.Parameters.AddWithValue("?id", assetID.ToString());
try
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
if (dbReader.Read())
{
if (dbReader.Read())
{
asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"], dbReader["CreatorID"].ToString());
asset.Data = (byte[])dbReader["data"];
asset.Description = (string)dbReader["description"];
asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"], dbReader["CreatorID"].ToString());
asset.Data = (byte[])dbReader["data"];
asset.Description = (string)dbReader["description"];
string local = dbReader["local"].ToString();
if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
asset.Local = true;
else
asset.Local = false;
string local = dbReader["local"].ToString();
if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
asset.Local = true;
else
asset.Local = false;
asset.Temporary = Convert.ToBoolean(dbReader["temporary"]);
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
}
asset.Temporary = Convert.ToBoolean(dbReader["temporary"]);
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
}
}
catch (Exception e)
{
m_log.Error(
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e);
}
}
catch (Exception e)
{
m_log.Error(
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e);
}
}
}
return asset;
}
@@ -158,100 +156,94 @@ namespace OpenSim.Data.MySQL
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
override public void StoreAsset(AssetBase asset)
{
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
dbcon.Open();
using (MySqlCommand cmd =
new MySqlCommand(
"replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" +
"VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)",
dbcon))
using (MySqlCommand cmd =
new MySqlCommand(
"replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" +
"VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)",
dbcon))
{
string assetName = asset.Name;
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
{
string assetName = asset.Name;
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
m_log.WarnFormat(
"[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
}
string assetDescription = asset.Description;
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
{
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
m_log.WarnFormat(
"[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
}
try
{
using (cmd)
{
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
m_log.WarnFormat(
"[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
}
string assetDescription = asset.Description;
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
{
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
m_log.WarnFormat(
"[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
}
try
{
using (cmd)
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?name", assetName);
cmd.Parameters.AddWithValue("?description", assetDescription);
cmd.Parameters.AddWithValue("?assetType", asset.Type);
cmd.Parameters.AddWithValue("?local", asset.Local);
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
cmd.Parameters.AddWithValue("?create_time", now);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.Error(
string.Format(
"[ASSET DB]: MySQL failure creating asset {0} with name {1}. Exception ",
asset.FullID, asset.Name)
, e);
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?name", assetName);
cmd.Parameters.AddWithValue("?description", assetDescription);
cmd.Parameters.AddWithValue("?assetType", asset.Type);
cmd.Parameters.AddWithValue("?local", asset.Local);
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
cmd.Parameters.AddWithValue("?create_time", now);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.Error(
string.Format(
"[ASSET DB]: MySQL failure creating asset {0} with name {1}. Exception ",
asset.FullID, asset.Name)
, e);
}
}
}
}
private void UpdateAccessTime(AssetBase asset)
{
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
dbcon.Open();
using (MySqlCommand cmd
= new MySqlCommand("update assets set access_time=?access_time where id=?id", dbcon))
using (MySqlCommand cmd
= new MySqlCommand("update assets set access_time=?access_time where id=?id", dbcon))
{
try
{
try
using (cmd)
{
using (cmd)
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.Error(
string.Format(
"[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ",
asset.FullID, asset.Name),
e);
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.Error(
string.Format(
"[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ",
asset.FullID, asset.Name),
e);
}
}
}
}
@@ -271,20 +263,17 @@ namespace OpenSim.Data.MySQL
string ids = "'" + string.Join("','", uuids) + "'";
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
using (MySqlDataReader dbReader = cmd.ExecuteReader())
{
using (MySqlDataReader dbReader = cmd.ExecuteReader())
while (dbReader.Read())
{
while (dbReader.Read())
{
UUID id = DBGuid.FromDB(dbReader["id"]);
exist.Add(id);
}
UUID id = DBGuid.FromDB(dbReader["id"]);
exist.Add(id);
}
}
}
@@ -309,50 +298,47 @@ namespace OpenSim.Data.MySQL
{
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();
using (MySqlCommand cmd
= new MySqlCommand(
"SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count",
dbcon))
using (MySqlCommand cmd
= new MySqlCommand(
"SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count",
dbcon))
{
cmd.Parameters.AddWithValue("?start", start);
cmd.Parameters.AddWithValue("?count", count);
try
{
cmd.Parameters.AddWithValue("?start", start);
cmd.Parameters.AddWithValue("?count", count);
try
using (MySqlDataReader dbReader = cmd.ExecuteReader())
{
using (MySqlDataReader dbReader = cmd.ExecuteReader())
while (dbReader.Read())
{
while (dbReader.Read())
{
AssetMetadata metadata = new AssetMetadata();
metadata.Name = (string)dbReader["name"];
metadata.Description = (string)dbReader["description"];
metadata.Type = (sbyte)dbReader["assetType"];
metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct.
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
metadata.FullID = DBGuid.FromDB(dbReader["id"]);
metadata.CreatorID = dbReader["CreatorID"].ToString();
// Current SHA1s are not stored/computed.
metadata.SHA1 = new byte[] { };
retList.Add(metadata);
}
AssetMetadata metadata = new AssetMetadata();
metadata.Name = (string)dbReader["name"];
metadata.Description = (string)dbReader["description"];
metadata.Type = (sbyte)dbReader["assetType"];
metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct.
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
metadata.FullID = DBGuid.FromDB(dbReader["id"]);
metadata.CreatorID = dbReader["CreatorID"].ToString();
// Current SHA1s are not stored/computed.
metadata.SHA1 = new byte[] { };
retList.Add(metadata);
}
}
catch (Exception e)
{
m_log.Error(
string.Format(
"[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ",
start, count),
e);
}
}
catch (Exception e)
{
m_log.Error(
string.Format(
"[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ",
start, count),
e);
}
}
}
@@ -362,17 +348,14 @@ namespace OpenSim.Data.MySQL
public override bool Delete(string id)
{
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon))
{
cmd.Parameters.AddWithValue("?id", id);
cmd.ExecuteNonQuery();
}
using (MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon))
{
cmd.Parameters.AddWithValue("?id", id);
cmd.ExecuteNonQuery();
}
}

View File

@@ -45,38 +45,29 @@ namespace OpenSim.Data.MySQL
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
protected string m_connectionString;
protected object m_dbLock = new object();
protected MySqlFramework(string connectionString)
{
m_connectionString = connectionString;
}
//////////////////////////////////////////////////////////////
//
// All non queries are funneled through one connection
// to increase performance a little
//
protected int ExecuteNonQuery(MySqlCommand cmd)
{
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
cmd.Connection = dbcon;
dbcon.Open();
cmd.Connection = dbcon;
try
{
return cmd.ExecuteNonQuery();
}
catch (Exception e)
{
m_log.Error(e.Message, e);
return 0;
}
try
{
return cmd.ExecuteNonQuery();
}
catch (Exception e)
{
m_log.Error(e.Message, e);
return 0;
}
}
}
}
}
}

View File

@@ -51,6 +51,15 @@ namespace OpenSim.Data.MySQL
private static string LogHeader = "[REGION DB MYSQL]";
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();
protected virtual Assembly Assembly
@@ -738,95 +747,92 @@ namespace OpenSim.Data.MySQL
RegionLightShareData nWP = new RegionLightShareData();
nWP.OnSave += StoreRegionWindlightSettings;
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
dbcon.Open();
string command = "select * from `regionwindlight` where region_id = ?regionID";
using (MySqlCommand cmd = new MySqlCommand(command))
{
dbcon.Open();
string command = "select * from `regionwindlight` where region_id = ?regionID";
using (MySqlCommand cmd = new MySqlCommand(command))
cmd.Connection = dbcon;
cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
IDataReader result = ExecuteReader(cmd);
if (!result.Read())
{
cmd.Connection = dbcon;
cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
IDataReader result = ExecuteReader(cmd);
if (!result.Read())
{
//No result, so store our default windlight profile and return it
nWP.regionID = regionUUID;
//No result, so store our default windlight profile and return it
nWP.regionID = regionUUID;
// StoreRegionWindlightSettings(nWP);
return nWP;
}
else
{
nWP.regionID = DBGuid.FromDB(result["region_id"]);
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
nWP.valid = true;
}
return nWP;
}
else
{
nWP.regionID = DBGuid.FromDB(result["region_id"]);
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
nWP.valid = true;
}
}
}
@@ -876,124 +882,118 @@ namespace OpenSim.Data.MySQL
public void StoreRegionWindlightSettings(RegionLightShareData wl)
{
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, ";
cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, ";
cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, ";
cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, ";
cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, ";
cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, ";
cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, ";
cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, ";
cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, ";
cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, ";
cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, ";
cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, ";
cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, ";
cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, ";
cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, ";
cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, ";
cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, ";
cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, ";
cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, ";
cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, ";
cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, ";
cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, ";
cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, ";
cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, ";
cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)";
cmd.Parameters.AddWithValue("region_id", wl.regionID);
cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
ExecuteNonQuery(cmd);
}
cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, ";
cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, ";
cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, ";
cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, ";
cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, ";
cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, ";
cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, ";
cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, ";
cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, ";
cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, ";
cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, ";
cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, ";
cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, ";
cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, ";
cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, ";
cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, ";
cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, ";
cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, ";
cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, ";
cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, ";
cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, ";
cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, ";
cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, ";
cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, ";
cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)";
cmd.Parameters.AddWithValue("region_id", wl.regionID);
cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
ExecuteNonQuery(cmd);
}
}
}
public void RemoveRegionWindlightSettings(UUID regionID)
{
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID";
cmd.Parameters.AddWithValue("?regionID", regionID.ToString());
ExecuteNonQuery(cmd);
}
cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID";
cmd.Parameters.AddWithValue("?regionID", regionID.ToString());
ExecuteNonQuery(cmd);
}
}
}
@@ -1001,29 +1001,26 @@ namespace OpenSim.Data.MySQL
#region RegionEnvironmentSettings
public string LoadRegionEnvironmentSettings(UUID regionUUID)
{
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
dbcon.Open();
string command = "select * from `regionenvironment` where region_id = ?region_id";
using (MySqlCommand cmd = new MySqlCommand(command))
{
dbcon.Open();
string command = "select * from `regionenvironment` where region_id = ?region_id";
using (MySqlCommand cmd = new MySqlCommand(command))
cmd.Connection = dbcon;
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
IDataReader result = ExecuteReader(cmd);
if (!result.Read())
{
cmd.Connection = dbcon;
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
IDataReader result = ExecuteReader(cmd);
if (!result.Read())
{
return String.Empty;
}
else
{
return Convert.ToString(result["llsd_settings"]);
}
return String.Empty;
}
else
{
return Convert.ToString(result["llsd_settings"]);
}
}
}
@@ -1031,39 +1028,33 @@ namespace OpenSim.Data.MySQL
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
{
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)";
cmd.Parameters.AddWithValue("region_id", regionUUID);
cmd.Parameters.AddWithValue("llsd_settings", settings);
ExecuteNonQuery(cmd);
}
cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)";
cmd.Parameters.AddWithValue("region_id", regionUUID);
cmd.Parameters.AddWithValue("llsd_settings", settings);
ExecuteNonQuery(cmd);
}
}
}
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
{
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id";
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
ExecuteNonQuery(cmd);
}
cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id";
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
ExecuteNonQuery(cmd);
}
}
}
@@ -1071,57 +1062,55 @@ namespace OpenSim.Data.MySQL
public void StoreRegionSettings(RegionSettings rs)
{
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
dbcon.Open();
cmd.CommandText = "replace into regionsettings (regionUUID, " +
"block_terraform, block_fly, allow_damage, " +
"restrict_pushing, allow_land_resell, " +
"allow_land_join_divide, block_show_in_search, " +
"agent_limit, object_bonus, maturity, " +
"disable_scripts, disable_collisions, " +
"disable_physics, terrain_texture_1, " +
"terrain_texture_2, terrain_texture_3, " +
"terrain_texture_4, elevation_1_nw, " +
"elevation_2_nw, elevation_1_ne, " +
"elevation_2_ne, elevation_1_se, " +
"elevation_2_se, elevation_1_sw, " +
"elevation_2_sw, water_height, " +
"terrain_raise_limit, terrain_lower_limit, " +
"use_estate_sun, fixed_sun, sun_position, " +
"covenant, covenant_datetime, Sandbox, sunvectorx, sunvectory, " +
"sunvectorz, loaded_creation_datetime, " +
"loaded_creation_id, map_tile_ID, " +
"TelehubObject, parcel_tile_ID) " +
"values (?RegionUUID, ?BlockTerraform, " +
"?BlockFly, ?AllowDamage, ?RestrictPushing, " +
"?AllowLandResell, ?AllowLandJoinDivide, " +
"?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " +
"?Maturity, ?DisableScripts, ?DisableCollisions, " +
"?DisablePhysics, ?TerrainTexture1, " +
"?TerrainTexture2, ?TerrainTexture3, " +
"?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " +
"?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " +
"?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " +
"?WaterHeight, ?TerrainRaiseLimit, " +
"?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " +
"?SunPosition, ?Covenant, ?CovenantChangedDateTime, ?Sandbox, " +
"?SunVectorX, ?SunVectorY, ?SunVectorZ, " +
"?LoadedCreationDateTime, ?LoadedCreationID, " +
"?TerrainImageID, " +
"?TelehubObject, ?ParcelImageID)";
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "replace into regionsettings (regionUUID, " +
"block_terraform, block_fly, allow_damage, " +
"restrict_pushing, allow_land_resell, " +
"allow_land_join_divide, block_show_in_search, " +
"agent_limit, object_bonus, maturity, " +
"disable_scripts, disable_collisions, " +
"disable_physics, terrain_texture_1, " +
"terrain_texture_2, terrain_texture_3, " +
"terrain_texture_4, elevation_1_nw, " +
"elevation_2_nw, elevation_1_ne, " +
"elevation_2_ne, elevation_1_se, " +
"elevation_2_se, elevation_1_sw, " +
"elevation_2_sw, water_height, " +
"terrain_raise_limit, terrain_lower_limit, " +
"use_estate_sun, fixed_sun, sun_position, " +
"covenant, covenant_datetime, Sandbox, sunvectorx, sunvectory, " +
"sunvectorz, loaded_creation_datetime, " +
"loaded_creation_id, map_tile_ID, " +
"TelehubObject, parcel_tile_ID) " +
"values (?RegionUUID, ?BlockTerraform, " +
"?BlockFly, ?AllowDamage, ?RestrictPushing, " +
"?AllowLandResell, ?AllowLandJoinDivide, " +
"?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " +
"?Maturity, ?DisableScripts, ?DisableCollisions, " +
"?DisablePhysics, ?TerrainTexture1, " +
"?TerrainTexture2, ?TerrainTexture3, " +
"?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " +
"?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " +
"?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " +
"?WaterHeight, ?TerrainRaiseLimit, " +
"?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " +
"?SunPosition, ?Covenant, ?CovenantChangedDateTime, ?Sandbox, " +
"?SunVectorX, ?SunVectorY, ?SunVectorZ, " +
"?LoadedCreationDateTime, ?LoadedCreationID, " +
"?TerrainImageID, " +
"?TelehubObject, ?ParcelImageID)";
FillRegionSettingsCommand(cmd, rs);
FillRegionSettingsCommand(cmd, rs);
ExecuteNonQuery(cmd);
}
ExecuteNonQuery(cmd);
}
}
SaveSpawnPoints(rs);
}
@@ -2043,41 +2032,35 @@ namespace OpenSim.Data.MySQL
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))
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
dbcon.Open();
cmd.CommandText = "replace into regionextra values (?RegionID, ?Name, ?value)";
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
cmd.Parameters.AddWithValue("?Name", name);
cmd.Parameters.AddWithValue("?value", val);
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "replace into regionextra values (?RegionID, ?Name, ?value)";
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
cmd.Parameters.AddWithValue("?Name", name);
cmd.Parameters.AddWithValue("?value", val);
cmd.ExecuteNonQuery();
}
cmd.ExecuteNonQuery();
}
}
}
public void RemoveExtra(UUID regionID, string name)
{
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
dbcon.Open();
cmd.CommandText = "delete from regionextra where RegionID=?RegionID and Name=?Name";
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
cmd.Parameters.AddWithValue("?Name", name);
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from regionextra where RegionID=?RegionID and Name=?Name";
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
cmd.Parameters.AddWithValue("?Name", name);
cmd.ExecuteNonQuery();
}
cmd.ExecuteNonQuery();
}
}
}
@@ -2086,22 +2069,19 @@ namespace OpenSim.Data.MySQL
{
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();
using (MySqlCommand cmd = dbcon.CreateCommand())
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "select * from regionextra where RegionID=?RegionID";
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
using (IDataReader r = cmd.ExecuteReader())
{
cmd.CommandText = "select * from regionextra where RegionID=?RegionID";
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
using (IDataReader r = cmd.ExecuteReader())
while (r.Read())
{
while (r.Read())
{
ret[r["Name"].ToString()] = r["value"].ToString();
}
ret[r["Name"].ToString()] = r["value"].ToString();
}
}
}

View File

@@ -46,11 +46,6 @@ namespace OpenSim.Data.MySQL
{
get; set;
}
protected object Lock
{
get; set;
}
protected virtual Assembly Assembly
{
@@ -116,7 +111,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": UserAccount exception {0}", e.Message);
}
n.Add("classifieduuid", OSD.FromUUID(Id));
@@ -237,7 +232,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": ClassifiedesUpdate exception {0}", e.Message);
result = e.Message;
return false;
@@ -250,7 +245,7 @@ namespace OpenSim.Data.MySQL
string query = string.Empty;
query += "DELETE FROM classifieds WHERE ";
query += "classifieduuid = ?ClasifiedId";
query += "classifieduuid = ?recordId";
try
{
@@ -260,18 +255,14 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("?ClassifiedId", recordId.ToString());
lock(Lock)
{
cmd.ExecuteNonQuery();
}
cmd.Parameters.AddWithValue("?recordId", recordId.ToString());
cmd.ExecuteNonQuery();
}
}
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": DeleteClassifiedRecord exception {0}", e.Message);
return false;
}
@@ -321,7 +312,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetPickInfo exception {0}", e.Message);
}
return true;
@@ -365,7 +356,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetAvatarPicks exception {0}", e.Message);
}
return data;
@@ -406,6 +397,7 @@ namespace OpenSim.Data.MySQL
UUID.TryParse((string)reader["parceluuid"], out pick.ParcelId);
UUID.TryParse((string)reader["snapshotuuid"], out pick.SnapshotId);
pick.GlobalPos = (string)reader["posglobal"];
pick.Gatekeeper = (string)reader["gatekeeper"];
bool.TryParse((string)reader["toppick"], out pick.TopPick);
bool.TryParse((string)reader["enabled"], out pick.Enabled);
pick.Name = (string)reader["name"];
@@ -422,7 +414,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetPickInfo exception {0}", e.Message);
}
return pick;
@@ -445,14 +437,16 @@ namespace OpenSim.Data.MySQL
query += "?SimName,";
query += "?GlobalPos,";
query += "?SortOrder,";
query += "?Enabled) ";
query += "?Enabled,";
query += "?Gatekeeper)";
query += "ON DUPLICATE KEY UPDATE ";
query += "parceluuid=?ParcelId,";
query += "name=?Name,";
query += "description=?Desc,";
query += "snapshotuuid=?SnapshotId,";
query += "pickuuid=?PickId,";
query += "posglobal=?GlobalPos";
query += "posglobal=?GlobalPos,";
query += "gatekeeper=?Gatekeeper";
try
{
@@ -472,6 +466,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?Original", pick.OriginalName.ToString());
cmd.Parameters.AddWithValue("?SimName",pick.SimName.ToString());
cmd.Parameters.AddWithValue("?GlobalPos", pick.GlobalPos);
cmd.Parameters.AddWithValue("?Gatekeeper",pick.Gatekeeper);
cmd.Parameters.AddWithValue("?SortOrder", pick.SortOrder.ToString ());
cmd.Parameters.AddWithValue("?Enabled", pick.Enabled.ToString());
@@ -481,7 +476,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": UpdateAvatarNotes exception {0}", e.Message);
return false;
}
@@ -511,7 +506,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": DeleteUserPickRecord exception {0}", e.Message);
return false;
}
@@ -556,7 +551,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetAvatarNotes exception {0}", e.Message);
}
return true;
@@ -604,7 +599,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": UpdateAvatarNotes exception {0}", e.Message);
return false;
}
@@ -722,7 +717,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": Requst properties exception {0}", e.Message);
result = e.Message;
return false;
@@ -762,7 +757,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": AgentPropertiesUpdate exception {0}", e.Message);
return false;
@@ -804,7 +799,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": AgentInterestsUpdate exception {0}", e.Message);
result = e.Message;
return false;
@@ -887,7 +882,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetAvatarNotes exception {0}", e.Message);
}
return data;
@@ -920,7 +915,7 @@ namespace OpenSim.Data.MySQL
reader.Read();
bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail);
bool.TryParse((string)reader["visible"], out pref.Visible);
pref.EMail = (string)reader["email"];
pref.EMail = (string)reader["email"];
}
else
{
@@ -945,7 +940,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": Get preferences exception {0}", e.Message);
result = e.Message;
return false;
@@ -959,7 +954,8 @@ namespace OpenSim.Data.MySQL
query += "UPDATE usersettings SET ";
query += "imviaemail=?ImViaEmail, ";
query += "visible=?Visible ";
query += "visible=?Visible, ";
query += "email=?EMail ";
query += "WHERE useruuid=?uuid";
try
@@ -971,7 +967,8 @@ namespace OpenSim.Data.MySQL
{
cmd.Parameters.AddWithValue("?ImViaEmail", pref.IMViaEmail.ToString().ToLower());
cmd.Parameters.AddWithValue("?Visible", pref.Visible.ToString().ToLower());
cmd.Parameters.AddWithValue("?uuid", pref.UserId.ToString());
cmd.Parameters.AddWithValue("?uuid", pref.UserId.ToString());
cmd.Parameters.AddWithValue("?EMail", pref.EMail.ToString().ToLower());
cmd.ExecuteNonQuery();
}
@@ -979,8 +976,8 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
": AgentInterestsUpdate exception {0}", e.Message);
m_log.ErrorFormat("[PROFILES_DATA]" +
": UserPreferencesUpdate exception {0} {1}", e.Message, e.InnerException);
result = e.Message;
return false;
}
@@ -1029,11 +1026,8 @@ namespace OpenSim.Data.MySQL
put.Parameters.AddWithValue("?TagId", props.TagId.ToString());
put.Parameters.AddWithValue("?DataKey", props.DataKey.ToString());
put.Parameters.AddWithValue("?DataVal", props.DataVal.ToString());
lock(Lock)
{
put.ExecuteNonQuery();
}
put.ExecuteNonQuery();
}
}
}
@@ -1042,7 +1036,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": Requst application data exception {0}", e.Message);
result = e.Message;
return false;
@@ -1069,20 +1063,17 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("?UserId", props.UserId.ToString());
cmd.Parameters.AddWithValue("?TagId", props.TagId.ToString ());
cmd.Parameters.AddWithValue("?DataKey", props.DataKey.ToString ());
cmd.Parameters.AddWithValue("?DataVal", props.DataKey.ToString ());
lock(Lock)
{
cmd.ExecuteNonQuery();
}
cmd.Parameters.AddWithValue("?TagId", props.TagId.ToString());
cmd.Parameters.AddWithValue("?DataKey", props.DataKey.ToString());
cmd.Parameters.AddWithValue("?DataVal", props.DataKey.ToString());
cmd.ExecuteNonQuery();
}
}
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": SetUserData exception {0}", e.Message);
return false;
}
@@ -1090,5 +1081,4 @@ namespace OpenSim.Data.MySQL
}
#endregion Integration
}
}
}

View File

@@ -57,7 +57,6 @@ namespace OpenSim.Data.MySQL
private bool m_enableCompression = false;
private string m_connectionString;
private object m_dbLock = new object();
/// <summary>
/// We can reuse this for all hashing since all methods are single-threaded through m_dbBLock
@@ -131,60 +130,58 @@ namespace OpenSim.Data.MySQL
// m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID);
AssetBase asset = null;
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(
"SELECT Name, Description, AccessTime, AssetType, Local, Temporary, AssetFlags, CreatorID, Data FROM XAssetsMeta JOIN XAssetsData ON XAssetsMeta.Hash = XAssetsData.Hash WHERE ID=?ID",
dbcon))
{
dbcon.Open();
cmd.Parameters.AddWithValue("?ID", assetID.ToString());
using (MySqlCommand cmd = new MySqlCommand(
"SELECT Name, Description, AccessTime, AssetType, Local, Temporary, AssetFlags, CreatorID, Data FROM XAssetsMeta JOIN XAssetsData ON XAssetsMeta.Hash = XAssetsData.Hash WHERE ID=?ID",
dbcon))
try
{
cmd.Parameters.AddWithValue("?ID", assetID.ToString());
try
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
if (dbReader.Read())
{
if (dbReader.Read())
asset = new AssetBase(assetID, (string)dbReader["Name"], (sbyte)dbReader["AssetType"], dbReader["CreatorID"].ToString());
asset.Data = (byte[])dbReader["Data"];
asset.Description = (string)dbReader["Description"];
string local = dbReader["Local"].ToString();
if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
asset.Local = true;
else
asset.Local = false;
asset.Temporary = Convert.ToBoolean(dbReader["Temporary"]);
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
if (m_enableCompression)
{
asset = new AssetBase(assetID, (string)dbReader["Name"], (sbyte)dbReader["AssetType"], dbReader["CreatorID"].ToString());
asset.Data = (byte[])dbReader["Data"];
asset.Description = (string)dbReader["Description"];
string local = dbReader["Local"].ToString();
if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
asset.Local = true;
else
asset.Local = false;
asset.Temporary = Convert.ToBoolean(dbReader["Temporary"]);
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
if (m_enableCompression)
using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress))
{
using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress))
{
MemoryStream outputStream = new MemoryStream();
WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue);
// int compressedLength = asset.Data.Length;
asset.Data = outputStream.ToArray();
// m_log.DebugFormat(
// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}",
// asset.ID, asset.Name, asset.Data.Length, compressedLength);
}
}
MemoryStream outputStream = new MemoryStream();
WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue);
// int compressedLength = asset.Data.Length;
asset.Data = outputStream.ToArray();
UpdateAccessTime(asset.Metadata, (int)dbReader["AccessTime"]);
// m_log.DebugFormat(
// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}",
// asset.ID, asset.Name, asset.Data.Length, compressedLength);
}
}
UpdateAccessTime(asset.Metadata, (int)dbReader["AccessTime"]);
}
}
catch (Exception e)
{
m_log.Error(string.Format("[MYSQL XASSET DATA]: Failure fetching asset {0}", assetID), e);
}
}
catch (Exception e)
{
m_log.Error(string.Format("[MYSQL XASSET DATA]: Failure fetching asset {0}", assetID), e);
}
}
}
@@ -201,113 +198,110 @@ namespace OpenSim.Data.MySQL
{
// 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();
using (MySqlTransaction transaction = dbcon.BeginTransaction())
{
dbcon.Open();
using (MySqlTransaction transaction = dbcon.BeginTransaction())
string assetName = asset.Name;
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
{
string assetName = asset.Name;
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
{
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
m_log.WarnFormat(
"[XASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
}
string assetDescription = asset.Description;
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
{
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
m_log.WarnFormat(
"[XASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
}
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
m_log.WarnFormat(
"[XASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
}
if (m_enableCompression)
string assetDescription = asset.Description;
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
{
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
m_log.WarnFormat(
"[XASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
}
if (m_enableCompression)
{
MemoryStream outputStream = new MemoryStream();
using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress, false))
{
MemoryStream outputStream = new MemoryStream();
using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress, false))
{
// Console.WriteLine(WebUtil.CopyTo(new MemoryStream(asset.Data), compressionStream, int.MaxValue));
// We have to close the compression stream in order to make sure it writes everything out to the underlying memory output stream.
compressionStream.Close();
byte[] compressedData = outputStream.ToArray();
asset.Data = compressedData;
}
// Console.WriteLine(WebUtil.CopyTo(new MemoryStream(asset.Data), compressionStream, int.MaxValue));
// We have to close the compression stream in order to make sure it writes everything out to the underlying memory output stream.
compressionStream.Close();
byte[] compressedData = outputStream.ToArray();
asset.Data = compressedData;
}
}
byte[] hash = hasher.ComputeHash(asset.Data);
byte[] hash = hasher.ComputeHash(asset.Data);
// m_log.DebugFormat(
// "[XASSET DB]: Compressed data size for {0} {1}, hash {2} is {3}",
// asset.ID, asset.Name, hash, compressedData.Length);
try
{
using (MySqlCommand cmd =
new MySqlCommand(
"replace INTO XAssetsMeta(ID, Hash, Name, Description, AssetType, Local, Temporary, CreateTime, AccessTime, AssetFlags, CreatorID)" +
"VALUES(?ID, ?Hash, ?Name, ?Description, ?AssetType, ?Local, ?Temporary, ?CreateTime, ?AccessTime, ?AssetFlags, ?CreatorID)",
dbcon))
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?ID", asset.ID);
cmd.Parameters.AddWithValue("?Hash", hash);
cmd.Parameters.AddWithValue("?Name", assetName);
cmd.Parameters.AddWithValue("?Description", assetDescription);
cmd.Parameters.AddWithValue("?AssetType", asset.Type);
cmd.Parameters.AddWithValue("?Local", asset.Local);
cmd.Parameters.AddWithValue("?Temporary", asset.Temporary);
cmd.Parameters.AddWithValue("?CreateTime", now);
cmd.Parameters.AddWithValue("?AccessTime", now);
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
cmd.Parameters.AddWithValue("?AssetFlags", (int)asset.Flags);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset metadata {0} with name \"{1}\". Error: {2}",
asset.FullID, asset.Name, e.Message);
transaction.Rollback();
return;
}
if (!ExistsData(dbcon, transaction, hash))
{
try
{
using (MySqlCommand cmd =
new MySqlCommand(
"replace INTO XAssetsMeta(ID, Hash, Name, Description, AssetType, Local, Temporary, CreateTime, AccessTime, AssetFlags, CreatorID)" +
"VALUES(?ID, ?Hash, ?Name, ?Description, ?AssetType, ?Local, ?Temporary, ?CreateTime, ?AccessTime, ?AssetFlags, ?CreatorID)",
"INSERT INTO XAssetsData(Hash, Data) VALUES(?Hash, ?Data)",
dbcon))
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?ID", asset.ID);
cmd.Parameters.AddWithValue("?Hash", hash);
cmd.Parameters.AddWithValue("?Name", assetName);
cmd.Parameters.AddWithValue("?Description", assetDescription);
cmd.Parameters.AddWithValue("?AssetType", asset.Type);
cmd.Parameters.AddWithValue("?Local", asset.Local);
cmd.Parameters.AddWithValue("?Temporary", asset.Temporary);
cmd.Parameters.AddWithValue("?CreateTime", now);
cmd.Parameters.AddWithValue("?AccessTime", now);
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
cmd.Parameters.AddWithValue("?AssetFlags", (int)asset.Flags);
cmd.Parameters.AddWithValue("?Data", asset.Data);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset metadata {0} with name \"{1}\". Error: {2}",
m_log.ErrorFormat("[XASSET DB]: MySQL failure creating asset data {0} with name \"{1}\". Error: {2}",
asset.FullID, asset.Name, e.Message);
transaction.Rollback();
return;
}
if (!ExistsData(dbcon, transaction, hash))
{
try
{
using (MySqlCommand cmd =
new MySqlCommand(
"INSERT INTO XAssetsData(Hash, Data) VALUES(?Hash, ?Data)",
dbcon))
{
cmd.Parameters.AddWithValue("?Hash", hash);
cmd.Parameters.AddWithValue("?Data", asset.Data);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.ErrorFormat("[XASSET DB]: MySQL failure creating asset data {0} with name \"{1}\". Error: {2}",
asset.FullID, asset.Name, e.Message);
transaction.Rollback();
return;
}
}
transaction.Commit();
}
transaction.Commit();
}
}
}
@@ -328,31 +322,28 @@ namespace OpenSim.Data.MySQL
if ((now - Utils.UnixTimeToDateTime(accessTime)).TotalDays < DaysBetweenAccessTimeUpdates)
return;
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd =
new MySqlCommand("update XAssetsMeta set AccessTime=?AccessTime where ID=?ID", dbcon);
dbcon.Open();
MySqlCommand cmd =
new MySqlCommand("update XAssetsMeta set AccessTime=?AccessTime where ID=?ID", dbcon);
try
try
{
using (cmd)
{
using (cmd)
{
// create unix epoch time
cmd.Parameters.AddWithValue("?ID", assetMetadata.ID);
cmd.Parameters.AddWithValue("?AccessTime", (int)Utils.DateTimeToUnixTime(now));
cmd.ExecuteNonQuery();
}
}
catch (Exception)
{
m_log.ErrorFormat(
"[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}",
assetMetadata.ID, assetMetadata.Name);
// create unix epoch time
cmd.Parameters.AddWithValue("?ID", assetMetadata.ID);
cmd.Parameters.AddWithValue("?AccessTime", (int)Utils.DateTimeToUnixTime(now));
cmd.ExecuteNonQuery();
}
}
catch (Exception)
{
m_log.ErrorFormat(
"[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}",
assetMetadata.ID, assetMetadata.Name);
}
}
}
@@ -411,20 +402,17 @@ namespace OpenSim.Data.MySQL
string ids = "'" + string.Join("','", uuids) + "'";
string sql = string.Format("SELECT ID FROM assets WHERE ID IN ({0})", ids);
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
using (MySqlDataReader dbReader = cmd.ExecuteReader())
{
using (MySqlDataReader dbReader = cmd.ExecuteReader())
while (dbReader.Read())
{
while (dbReader.Read())
{
UUID id = DBGuid.FromDB(dbReader["ID"]);
exists.Add(id);
}
UUID id = DBGuid.FromDB(dbReader["ID"]);
exists.Add(id);
}
}
}
@@ -449,43 +437,40 @@ namespace OpenSim.Data.MySQL
{
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();
MySqlCommand cmd = new MySqlCommand("SELECT Name, Description, AccessTime, AssetType, Temporary, ID, AssetFlags, CreatorID FROM XAssetsMeta LIMIT ?start, ?count", dbcon);
cmd.Parameters.AddWithValue("?start", start);
cmd.Parameters.AddWithValue("?count", count);
try
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand("SELECT Name, Description, AccessTime, AssetType, Temporary, ID, AssetFlags, CreatorID FROM XAssetsMeta LIMIT ?start, ?count", dbcon);
cmd.Parameters.AddWithValue("?start", start);
cmd.Parameters.AddWithValue("?count", count);
try
using (MySqlDataReader dbReader = cmd.ExecuteReader())
{
using (MySqlDataReader dbReader = cmd.ExecuteReader())
while (dbReader.Read())
{
while (dbReader.Read())
{
AssetMetadata metadata = new AssetMetadata();
metadata.Name = (string)dbReader["Name"];
metadata.Description = (string)dbReader["Description"];
metadata.Type = (sbyte)dbReader["AssetType"];
metadata.Temporary = Convert.ToBoolean(dbReader["Temporary"]); // Not sure if this is correct.
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
metadata.FullID = DBGuid.FromDB(dbReader["ID"]);
metadata.CreatorID = dbReader["CreatorID"].ToString();
AssetMetadata metadata = new AssetMetadata();
metadata.Name = (string)dbReader["Name"];
metadata.Description = (string)dbReader["Description"];
metadata.Type = (sbyte)dbReader["AssetType"];
metadata.Temporary = Convert.ToBoolean(dbReader["Temporary"]); // Not sure if this is correct.
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
metadata.FullID = DBGuid.FromDB(dbReader["ID"]);
metadata.CreatorID = dbReader["CreatorID"].ToString();
// We'll ignore this for now - it appears unused!
// We'll ignore this for now - it appears unused!
// metadata.SHA1 = dbReader["hash"]);
UpdateAccessTime(metadata, (int)dbReader["AccessTime"]);
UpdateAccessTime(metadata, (int)dbReader["AccessTime"]);
retList.Add(metadata);
}
retList.Add(metadata);
}
}
catch (Exception e)
{
m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
}
}
catch (Exception e)
{
m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
}
}
@@ -496,21 +481,18 @@ namespace OpenSim.Data.MySQL
{
// 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();
using (MySqlCommand cmd = new MySqlCommand("delete from XAssetsMeta where ID=?ID", dbcon))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand("delete from XAssetsMeta where ID=?ID", dbcon))
{
cmd.Parameters.AddWithValue("?ID", id);
cmd.ExecuteNonQuery();
}
// TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we
// keep a reference count (?)
cmd.Parameters.AddWithValue("?ID", id);
cmd.ExecuteNonQuery();
}
// TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we
// keep a reference count (?)
}
return true;

View File

@@ -90,4 +90,9 @@ CREATE TABLE IF NOT EXISTS `usersettings` (
`email` varchar(254) NOT NULL,
PRIMARY KEY (`useruuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
commit;
commit;
:VERSION 4 # -------------------------------
begin;
ALTER TABLE userpicks ADD COLUMN gatekeeper varchar(255);
commit;

View File

@@ -298,22 +298,26 @@ namespace OpenSim.Data.PGSQL
return new UserAccountData[0];
string sql = "";
UUID scope_id;
UUID.TryParse(scopeID.ToString(), out scope_id);
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
using (NpgsqlCommand cmd = new NpgsqlCommand())
{
if (words.Length == 1)
{
sql = String.Format(@"select * from {0} where (""ScopeID""=:ScopeID or ""ScopeID""='00000000-0000-0000-0000-000000000000') and (""FirstName"" ilike :search or ""LastName"" ilike :search)", m_Realm);
cmd.Parameters.Add(m_database.CreateParameter("scopeID", scopeID));
sql = String.Format(@"select * from {0} where (""ScopeID""=:ScopeID or ""ScopeID""=:UUIDZero) and (""FirstName"" ilike :search or ""LastName"" ilike :search)", m_Realm);
cmd.Parameters.Add(m_database.CreateParameter("scopeID", (UUID)scope_id));
cmd.Parameters.Add (m_database.CreateParameter("UUIDZero", (UUID)UUID.Zero));
cmd.Parameters.Add(m_database.CreateParameter("search", "%" + words[0] + "%"));
}
else
{
sql = String.Format(@"select * from {0} where (""ScopeID""=:ScopeID or ""ScopeID""='00000000-0000-0000-0000-000000000000') and (""FirstName"" ilike :searchFirst or ""LastName"" ilike :searchLast)", m_Realm);
sql = String.Format(@"select * from {0} where (""ScopeID""=:ScopeID or ""ScopeID""=:UUIDZero) and (""FirstName"" ilike :searchFirst or ""LastName"" ilike :searchLast)", m_Realm);
cmd.Parameters.Add(m_database.CreateParameter("searchFirst", "%" + words[0] + "%"));
cmd.Parameters.Add(m_database.CreateParameter("searchLast", "%" + words[1] + "%"));
cmd.Parameters.Add(m_database.CreateParameter("ScopeID", scopeID.ToString()));
cmd.Parameters.Add (m_database.CreateParameter("UUIDZero", (UUID)UUID.Zero));
cmd.Parameters.Add(m_database.CreateParameter("ScopeID", (UUID)scope_id));
}
cmd.Connection = conn;
cmd.CommandText = sql;

View File

@@ -40,6 +40,8 @@ namespace OpenSim.Data.PGSQL
public class UserProfilesData: IProfilesData
{
static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected PGSQLManager m_database;
#region Properites
string ConnectionString
@@ -74,6 +76,7 @@ namespace OpenSim.Data.PGSQL
Migration m = new Migration(dbcon, Assembly, "UserProfiles");
m.Update();
m_database = new PGSQLManager(ConnectionString);
}
}
#endregion Member Functions
@@ -94,11 +97,11 @@ namespace OpenSim.Data.PGSQL
using (NpgsqlConnection dbcon = new NpgsqlConnection(ConnectionString))
{
string query = @"SELECT ""classifieduuid"", ""name"" FROM classifieds WHERE ""creatoruuid"" = :Id";
string query = @"SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = :Id";
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("Id", creatorId);
cmd.Parameters.Add(m_database.CreateParameter("Id", creatorId));
using( NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default))
{
if(reader.HasRows)
@@ -111,12 +114,12 @@ namespace OpenSim.Data.PGSQL
string Name = null;
try
{
UUID.TryParse(Convert.ToString( reader["classifieduuid"]), out Id);
Id = DBGuid.FromDB(reader["classifieduuid"]);
Name = Convert.ToString(reader["name"]);
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": UserAccount exception {0}", e.Message);
}
n.Add("classifieduuid", OSD.FromUUID(Id));
@@ -132,28 +135,25 @@ namespace OpenSim.Data.PGSQL
public bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result)
{
string query = @"INSERT INTO classifieds ( ""classifieduuid"",""creatoruuid"", ""creationdate"", ""expirationdate"", ""category"",
""name"", ""description"", ""parceluuid"", ""parentestate"", ""snapshotuuid"", ""simname"",
""posglobal"", ""parcelname"", ""classifiedflags"", ""priceforlisting"")
Select :ClassifiedId, :CreatorId, :CreatedDate, :ExpirationDate, :Category,
:Name, :Description, :ParcelId, :ParentEstate, :SnapshotId, :SimName
:GlobalPos, :ParcelName, :Flags, :ListingPrice
Where not exists( Select ""classifieduuid"" from classifieds where ""classifieduuid"" = :ClassifiedId );
string query = string.Empty;
query = @"WITH upsert AS (
UPDATE classifieds SET
classifieduuid = :ClassifiedId, creatoruuid = :CreatorId, creationdate = :CreatedDate,
expirationdate = :ExpirationDate,category =:Category, name = :Name, description = :Description,
parceluuid = :ParcelId, parentestate = :ParentEstate, snapshotuuid = :SnapshotId,
simname = :SimName, posglobal = :GlobalPos, parcelname = :ParcelName, classifiedflags = :Flags,
priceforlisting = :ListingPrice
RETURNING * )
INSERT INTO classifieds (classifieduuid,creatoruuid,creationdate,expirationdate,category,name,
description,parceluuid,parentestate,snapshotuuid,simname,posglobal,parcelname,classifiedflags,
priceforlisting)
SELECT
:ClassifiedId,:CreatorId,:CreatedDate,:ExpirationDate,:Category,:Name,:Description,
:ParcelId,:ParentEstate,:SnapshotId,:SimName,:GlobalPos,:ParcelName,:Flags,:ListingPrice
WHERE NOT EXISTS (
SELECT * FROM upsert )";
update classifieds
set category =:Category,
expirationdate = :ExpirationDate,
name = :Name,
description = :Description,
parentestate = :ParentEstate,
posglobal = :GlobalPos,
parcelname = :ParcelName,
classifiedflags = :Flags,
priceforlisting = :ListingPrice,
snapshotuuid = :SnapshotId
where classifieduuid = :ClassifiedId ;
";
if(string.IsNullOrEmpty(ad.ParcelName))
ad.ParcelName = "Unknown";
if(ad.ParcelId == null)
@@ -190,21 +190,21 @@ namespace OpenSim.Data.PGSQL
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("ClassifiedId", ad.ClassifiedId.ToString());
cmd.Parameters.AddWithValue("CreatorId", ad.CreatorId.ToString());
cmd.Parameters.AddWithValue("CreatedDate", ad.CreationDate.ToString());
cmd.Parameters.AddWithValue("ExpirationDate", ad.ExpirationDate.ToString());
cmd.Parameters.AddWithValue("Category", ad.Category.ToString());
cmd.Parameters.AddWithValue("Name", ad.Name.ToString());
cmd.Parameters.AddWithValue("Description", ad.Description.ToString());
cmd.Parameters.AddWithValue("ParcelId", ad.ParcelId.ToString());
cmd.Parameters.AddWithValue("ParentEstate", ad.ParentEstate.ToString());
cmd.Parameters.AddWithValue("SnapshotId", ad.SnapshotId.ToString ());
cmd.Parameters.AddWithValue("SimName", ad.SimName.ToString());
cmd.Parameters.AddWithValue("GlobalPos", ad.GlobalPos.ToString());
cmd.Parameters.AddWithValue("ParcelName", ad.ParcelName.ToString());
cmd.Parameters.AddWithValue("Flags", ad.Flags.ToString());
cmd.Parameters.AddWithValue("ListingPrice", ad.Price.ToString ());
cmd.Parameters.Add(m_database.CreateParameter("ClassifiedId", ad.ClassifiedId));
cmd.Parameters.Add(m_database.CreateParameter("CreatorId", ad.CreatorId));
cmd.Parameters.Add(m_database.CreateParameter("CreatedDate", (int)ad.CreationDate));
cmd.Parameters.Add(m_database.CreateParameter("ExpirationDate", (int)ad.ExpirationDate));
cmd.Parameters.Add(m_database.CreateParameter("Category", ad.Category.ToString()));
cmd.Parameters.Add(m_database.CreateParameter("Name", ad.Name.ToString()));
cmd.Parameters.Add(m_database.CreateParameter("Description", ad.Description.ToString()));
cmd.Parameters.Add(m_database.CreateParameter("ParcelId", ad.ParcelId));
cmd.Parameters.Add(m_database.CreateParameter("ParentEstate", (int)ad.ParentEstate));
cmd.Parameters.Add(m_database.CreateParameter("SnapshotId", ad.SnapshotId));
cmd.Parameters.Add(m_database.CreateParameter("SimName", ad.SimName.ToString()));
cmd.Parameters.Add(m_database.CreateParameter("GlobalPos", ad.GlobalPos.ToString()));
cmd.Parameters.Add(m_database.CreateParameter("ParcelName", ad.ParcelName.ToString()));
cmd.Parameters.Add(m_database.CreateParameter("Flags", (int)Convert.ToInt32(ad.Flags)));
cmd.Parameters.Add(m_database.CreateParameter("ListingPrice", (int)Convert.ToInt32(ad.Price)));
cmd.ExecuteNonQuery();
}
@@ -212,7 +212,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": ClassifiedesUpdate exception {0}", e.Message);
result = e.Message;
return false;
@@ -235,7 +235,7 @@ namespace OpenSim.Data.PGSQL
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("ClassifiedId", recordId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("ClassifiedId", recordId));
lock(Lock)
{
@@ -246,7 +246,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": DeleteClassifiedRecord exception {0}", e.Message);
return false;
}
@@ -267,15 +267,15 @@ namespace OpenSim.Data.PGSQL
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("AdId", ad.ClassifiedId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("AdId", ad.ClassifiedId));
using (NpgsqlDataReader reader = cmd.ExecuteReader())
{
if(reader.Read ())
{
ad.CreatorId = GetUUID(reader["creatoruuid"]);
ad.ParcelId = GetUUID(reader["parceluuid"]);
ad.SnapshotId = GetUUID(reader["snapshotuuid"]);
ad.CreatorId = DBGuid.FromDB(reader["creatoruuid"]);
ad.ParcelId = DBGuid.FromDB(reader["parceluuid"]);
ad.SnapshotId = DBGuid.FromDB(reader["snapshotuuid"]);
ad.CreationDate = Convert.ToInt32(reader["creationdate"]);
ad.ExpirationDate = Convert.ToInt32(reader["expirationdate"]);
ad.ParentEstate = Convert.ToInt32(reader["parentestate"]);
@@ -287,7 +287,6 @@ namespace OpenSim.Data.PGSQL
ad.SimName = reader["simname"].ToString();
ad.GlobalPos = reader["posglobal"].ToString();
ad.ParcelName = reader["parcelname"].ToString();
}
}
}
@@ -296,8 +295,8 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
": GetPickInfo exception {0}", e.Message);
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetClassifiedInfo exception {0}", e.Message);
}
return true;
}
@@ -330,7 +329,7 @@ namespace OpenSim.Data.PGSQL
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("Id", avatarId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("Id", avatarId));
using (NpgsqlDataReader reader = cmd.ExecuteReader())
{
@@ -340,7 +339,7 @@ namespace OpenSim.Data.PGSQL
{
OSDMap record = new OSDMap();
record.Add("pickuuid",OSD.FromString((string)reader["pickuuid"]));
record.Add("pickuuid",OSD.FromUUID(DBGuid.FromDB(reader["pickuuid"])));
record.Add("name",OSD.FromString((string)reader["name"]));
data.Add(record);
}
@@ -351,7 +350,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetAvatarPicks exception {0}", e.Message);
}
return data;
@@ -373,8 +372,8 @@ namespace OpenSim.Data.PGSQL
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("CreatorId", avatarId.ToString());
cmd.Parameters.AddWithValue("PickId", pickId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("CreatorId", avatarId));
cmd.Parameters.Add(m_database.CreateParameter("PickId", pickId));
using (NpgsqlDataReader reader = cmd.ExecuteReader())
{
@@ -387,18 +386,18 @@ namespace OpenSim.Data.PGSQL
if (string.IsNullOrEmpty(description))
description = "No description given.";
UUID.TryParse((string)reader["pickuuid"], out pick.PickId);
UUID.TryParse((string)reader["creatoruuid"], out pick.CreatorId);
UUID.TryParse((string)reader["parceluuid"], out pick.ParcelId);
UUID.TryParse((string)reader["snapshotuuid"], out pick.SnapshotId);
pick.GlobalPos = (string)reader["posglobal"];
bool.TryParse((string)reader["toppick"], out pick.TopPick);
bool.TryParse((string)reader["enabled"], out pick.Enabled);
pick.Name = (string)reader["name"];
pick.Desc = description;
pick.User = (string)reader["user"];
pick.OriginalName = (string)reader["originalname"];
pick.SimName = (string)reader["simname"];
pick.PickId = DBGuid.FromDB(reader["pickuuid"]);
pick.CreatorId = DBGuid.FromDB(reader["creatoruuid"]);
pick.ParcelId = DBGuid.FromDB(reader["parceluuid"]);
pick.SnapshotId = DBGuid.FromDB(reader["snapshotuuid"]);
pick.GlobalPos = (string)reader["posglobal"].ToString();
pick.TopPick = Convert.ToBoolean(reader["toppick"]);
pick.Enabled = Convert.ToBoolean(reader["enabled"]);
pick.Name = reader["name"].ToString ();
pick.Desc = reader["description"].ToString();
pick.User = reader["user"].ToString();
pick.OriginalName = reader["originalname"].ToString();
pick.SimName = reader["simname"].ToString();
pick.SortOrder = (int)reader["sortorder"];
}
}
@@ -408,7 +407,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetPickInfo exception {0}", e.Message);
}
return pick;
@@ -418,20 +417,22 @@ namespace OpenSim.Data.PGSQL
{
string query = string.Empty;
query = @"INSERT INTO userpicks VALUES ( :PickId, :CreatorId, :TopPick, :ParcelId,:Name, :Desc, :SnapshotId,:User,
:Original, :SimName, :GlobalPos, :SortOrder, :Enabled)
where not exists ( select pickid from userpicks where pickid = :pickid);
Update userpicks
set parceluuid = :ParcelId,
name = :Name,
description = :Desc,
snapshotuuid = :SnapshotId,
pickuuid = :PickId,
posglobal = :GlobalPos
where pickid = :PickId;
";
query = @"WITH upsert AS (
UPDATE userpicks SET
pickuuid = :PickId, creatoruuid = :CreatorId, toppick = :TopPick, parceluuid = :ParcelId,
name = :Name, description = :Desc, snapshotuuid = :SnapshotId, ""user"" = :User,
originalname = :Original, simname = :SimName, posglobal = :GlobalPos,
sortorder = :SortOrder, enabled = :Enabled
RETURNING * )
INSERT INTO userpicks (pickuuid,creatoruuid,toppick,parceluuid,name,description,
snapshotuuid,""user"",originalname,simname,posglobal,sortorder,enabled)
SELECT
:PickId,:CreatorId,:TopPick,:ParcelId,:Name,:Desc,:SnapshotId,:User,
:Original,:SimName,:GlobalPos,:SortOrder,:Enabled
WHERE NOT EXISTS (
SELECT * FROM upsert )";
try
{
using (NpgsqlConnection dbcon = new NpgsqlConnection(ConnectionString))
@@ -439,19 +440,19 @@ namespace OpenSim.Data.PGSQL
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("PickId", pick.PickId.ToString());
cmd.Parameters.AddWithValue("CreatorId", pick.CreatorId.ToString());
cmd.Parameters.AddWithValue("TopPick", pick.TopPick.ToString());
cmd.Parameters.AddWithValue("ParcelId", pick.ParcelId.ToString());
cmd.Parameters.AddWithValue("Name", pick.Name.ToString());
cmd.Parameters.AddWithValue("Desc", pick.Desc.ToString());
cmd.Parameters.AddWithValue("SnapshotId", pick.SnapshotId.ToString());
cmd.Parameters.AddWithValue("User", pick.User.ToString());
cmd.Parameters.AddWithValue("Original", pick.OriginalName.ToString());
cmd.Parameters.AddWithValue("SimName",pick.SimName.ToString());
cmd.Parameters.AddWithValue("GlobalPos", pick.GlobalPos);
cmd.Parameters.AddWithValue("SortOrder", pick.SortOrder.ToString ());
cmd.Parameters.AddWithValue("Enabled", pick.Enabled.ToString());
cmd.Parameters.Add(m_database.CreateParameter("PickId", pick.PickId));
cmd.Parameters.Add(m_database.CreateParameter("CreatorId", pick.CreatorId));
cmd.Parameters.Add(m_database.CreateParameter("TopPick", pick.TopPick));
cmd.Parameters.Add(m_database.CreateParameter("ParcelId", pick.ParcelId));
cmd.Parameters.Add(m_database.CreateParameter("Name", pick.Name));
cmd.Parameters.Add(m_database.CreateParameter("Desc", pick.Desc));
cmd.Parameters.Add(m_database.CreateParameter("SnapshotId", pick.SnapshotId));
cmd.Parameters.Add(m_database.CreateParameter("User", pick.User));
cmd.Parameters.Add(m_database.CreateParameter("Original", pick.OriginalName));
cmd.Parameters.Add(m_database.CreateParameter("SimName",pick.SimName));
cmd.Parameters.Add(m_database.CreateParameter("GlobalPos", pick.GlobalPos));
cmd.Parameters.Add(m_database.CreateParameter("SortOrder", pick.SortOrder));
cmd.Parameters.Add(m_database.CreateParameter("Enabled", pick.Enabled));
cmd.ExecuteNonQuery();
}
@@ -459,7 +460,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": UpdateAvatarNotes exception {0}", e.Message);
return false;
}
@@ -481,7 +482,7 @@ namespace OpenSim.Data.PGSQL
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("PickId", pickId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("PickId", pickId));
cmd.ExecuteNonQuery();
}
@@ -489,7 +490,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": DeleteUserPickRecord exception {0}", e.Message);
return false;
}
@@ -514,8 +515,8 @@ namespace OpenSim.Data.PGSQL
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("Id", notes.UserId.ToString());
cmd.Parameters.AddWithValue("TargetId", notes.TargetId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("Id", notes.UserId));
cmd.Parameters.Add(m_database.CreateParameter("TargetId", notes.TargetId));
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
@@ -530,7 +531,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetAvatarNotes exception {0}", e.Message);
}
return true;
@@ -551,14 +552,14 @@ namespace OpenSim.Data.PGSQL
else
{
remove = false;
query = @"INSERT INTO usernotes VALUES ( :UserId, :TargetId, :Notes )
where not exists ( Select useruuid from usernotes where useruuid = :UserId and targetuuid = :TargetId );
update usernotes
set notes = :Notes
where useruuid = :UserId
and targetuuid = :TargetId;
";
query = @"WITH upsert AS (
UPDATE usernotes SET notes = :Notes, useruuid = :UserId, targetuuid = :TargetId RETURNING * )
INSERT INTO usernotes (notes,useruuid,targetuuid)
SELECT :Notes,:UserId,:TargetId
WHERE NOT EXISTS (
SELECT * FROM upsert
)";
}
try
@@ -569,9 +570,9 @@ namespace OpenSim.Data.PGSQL
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
if(!remove)
cmd.Parameters.AddWithValue("Notes", note.Notes);
cmd.Parameters.AddWithValue("TargetId", note.TargetId.ToString ());
cmd.Parameters.AddWithValue("UserId", note.UserId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("Notes", note.Notes));
cmd.Parameters.Add(m_database.CreateParameter("TargetId", note.TargetId));
cmd.Parameters.Add(m_database.CreateParameter("UserId", note.UserId));
cmd.ExecuteNonQuery();
}
@@ -579,7 +580,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": UpdateAvatarNotes exception {0}", e.Message);
return false;
}
@@ -603,21 +604,21 @@ namespace OpenSim.Data.PGSQL
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("Id", props.UserId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("Id", props.UserId));
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if(reader.HasRows)
{
m_log.DebugFormat("[PROFILES_DATA]" +
": Getting data for {0}.", props.UserId);
// m_log.DebugFormat("[PROFILES_DATA]" +
// ": Getting data for {0}.", props.UserId);
reader.Read();
props.WebUrl = (string)reader["profileURL"];
UUID.TryParse((string)reader["profileImage"], out props.ImageId);
props.WebUrl = (string)reader["profileURL"].ToString();
props.ImageId = DBGuid.FromDB(reader["profileImage"]);
props.AboutText = (string)reader["profileAboutText"];
UUID.TryParse((string)reader["profileFirstImage"], out props.FirstLifeImageId);
props.FirstLifeImageId = DBGuid.FromDB(reader["profileFirstImage"]);
props.FirstLifeText = (string)reader["profileFirstText"];
UUID.TryParse((string)reader["profilePartner"], out props.PartnerId);
props.PartnerId = DBGuid.FromDB(reader["profilePartner"]);
props.WantToMask = (int)reader["profileWantToMask"];
props.WantToText = (string)reader["profileWantToText"];
props.SkillsMask = (int)reader["profileSkillsMask"];
@@ -626,8 +627,8 @@ namespace OpenSim.Data.PGSQL
}
else
{
m_log.DebugFormat("[PROFILES_DATA]" +
": No data for {0}", props.UserId);
//m_log.DebugFormat("[PROFILES_DATA]" +
// ": No data for {0}", props.UserId);
props.WebUrl = string.Empty;
props.ImageId = UUID.Zero;
@@ -645,19 +646,19 @@ namespace OpenSim.Data.PGSQL
query = "INSERT INTO userprofile (";
query += "useruuid, ";
query += "profilePartner, ";
query += "profileAllowPublish, ";
query += "profileMaturePublish, ";
query += "profileURL, ";
query += "profileWantToMask, ";
query += "profileWantToText, ";
query += "profileSkillsMask, ";
query += "profileSkillsText, ";
query += "profileLanguages, ";
query += "profileImage, ";
query += "profileAboutText, ";
query += "profileFirstImage, ";
query += "profileFirstText) VALUES (";
query += "\"profilePartner\", ";
query += "\"profileAllowPublish\", ";
query += "\"profileMaturePublish\", ";
query += "\"profileURL\", ";
query += "\"profileWantToMask\", ";
query += "\"profileWantToText\", ";
query += "\"profileSkillsMask\", ";
query += "\"profileSkillsText\", ";
query += "\"profileLanguages\", ";
query += "\"profileImage\", ";
query += "\"profileAboutText\", ";
query += "\"profileFirstImage\", ";
query += "\"profileFirstText\") VALUES (";
query += ":userId, ";
query += ":profilePartner, ";
query += ":profileAllowPublish, ";
@@ -678,20 +679,23 @@ namespace OpenSim.Data.PGSQL
using (NpgsqlCommand put = new NpgsqlCommand(query, dbcon))
{
put.Parameters.AddWithValue("userId", props.UserId.ToString());
put.Parameters.AddWithValue("profilePartner", props.PartnerId.ToString());
put.Parameters.AddWithValue("profileAllowPublish", props.PublishProfile);
put.Parameters.AddWithValue("profileMaturePublish", props.PublishMature);
put.Parameters.AddWithValue("profileURL", props.WebUrl);
put.Parameters.AddWithValue("profileWantToMask", props.WantToMask);
put.Parameters.AddWithValue("profileWantToText", props.WantToText);
put.Parameters.AddWithValue("profileSkillsMask", props.SkillsMask);
put.Parameters.AddWithValue("profileSkillsText", props.SkillsText);
put.Parameters.AddWithValue("profileLanguages", props.Language);
put.Parameters.AddWithValue("profileImage", props.ImageId.ToString());
put.Parameters.AddWithValue("profileAboutText", props.AboutText);
put.Parameters.AddWithValue("profileFirstImage", props.FirstLifeImageId.ToString());
put.Parameters.AddWithValue("profileFirstText", props.FirstLifeText);
//m_log.DebugFormat("[PROFILES_DATA]" +
// ": Adding new data for {0}", props.UserId);
put.Parameters.Add(m_database.CreateParameter("userId", props.UserId));
put.Parameters.Add(m_database.CreateParameter("profilePartner", props.PartnerId));
put.Parameters.Add(m_database.CreateParameter("profileAllowPublish", props.PublishProfile));
put.Parameters.Add(m_database.CreateParameter("profileMaturePublish", props.PublishMature));
put.Parameters.Add(m_database.CreateParameter("profileURL", props.WebUrl));
put.Parameters.Add(m_database.CreateParameter("profileWantToMask", props.WantToMask));
put.Parameters.Add(m_database.CreateParameter("profileWantToText", props.WantToText));
put.Parameters.Add(m_database.CreateParameter("profileSkillsMask", props.SkillsMask));
put.Parameters.Add(m_database.CreateParameter("profileSkillsText", props.SkillsText));
put.Parameters.Add(m_database.CreateParameter("profileLanguages", props.Language));
put.Parameters.Add(m_database.CreateParameter("profileImage", props.ImageId));
put.Parameters.Add(m_database.CreateParameter("profileAboutText", props.AboutText));
put.Parameters.Add(m_database.CreateParameter("profileFirstImage", props.FirstLifeImageId));
put.Parameters.Add(m_database.CreateParameter("profileFirstText", props.FirstLifeText));
put.ExecuteNonQuery();
}
@@ -702,8 +706,8 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
": Requst properties exception {0}", e.Message);
m_log.ErrorFormat("[PROFILES_DATA]" +
": Requst properties exception {0}", e.Message);
result = e.Message;
return false;
}
@@ -715,12 +719,12 @@ namespace OpenSim.Data.PGSQL
string query = string.Empty;
query += "UPDATE userprofile SET ";
query += "profileURL=:profileURL, ";
query += "profileImage=:image, ";
query += "profileAboutText=:abouttext,";
query += "profileFirstImage=:firstlifeimage,";
query += "profileFirstText=:firstlifetext ";
query += "WHERE useruuid=:uuid";
query += "\"profileURL\"=:profileURL, ";
query += "\"profileImage\"=:image, ";
query += "\"profileAboutText\"=:abouttext,";
query += "\"profileFirstImage\"=:firstlifeimage,";
query += "\"profileFirstText\"=:firstlifetext ";
query += "WHERE \"useruuid\"=:uuid";
try
{
@@ -729,12 +733,12 @@ namespace OpenSim.Data.PGSQL
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("profileURL", props.WebUrl);
cmd.Parameters.AddWithValue("image", props.ImageId.ToString());
cmd.Parameters.AddWithValue("abouttext", props.AboutText);
cmd.Parameters.AddWithValue("firstlifeimage", props.FirstLifeImageId.ToString());
cmd.Parameters.AddWithValue("firstlifetext", props.FirstLifeText);
cmd.Parameters.AddWithValue("uuid", props.UserId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("profileURL", props.WebUrl));
cmd.Parameters.Add(m_database.CreateParameter("image", props.ImageId));
cmd.Parameters.Add(m_database.CreateParameter("abouttext", props.AboutText));
cmd.Parameters.Add(m_database.CreateParameter("firstlifeimage", props.FirstLifeImageId));
cmd.Parameters.Add(m_database.CreateParameter("firstlifetext", props.FirstLifeText));
cmd.Parameters.Add(m_database.CreateParameter("uuid", props.UserId));
cmd.ExecuteNonQuery();
}
@@ -742,7 +746,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": AgentPropertiesUpdate exception {0}", e.Message);
return false;
@@ -757,12 +761,12 @@ namespace OpenSim.Data.PGSQL
string query = string.Empty;
query += "UPDATE userprofile SET ";
query += "profileWantToMask=:WantMask, ";
query += "profileWantToText=:WantText,";
query += "profileSkillsMask=:SkillsMask,";
query += "profileSkillsText=:SkillsText, ";
query += "profileLanguages=:Languages ";
query += "WHERE useruuid=:uuid";
query += "\"profileWantToMask\"=:WantMask, ";
query += "\"profileWantToText\"=:WantText,";
query += "\"profileSkillsMask\"=:SkillsMask,";
query += "\"profileSkillsText\"=:SkillsText, ";
query += "\"profileLanguages\"=:Languages ";
query += "WHERE \"useruuid\"=:uuid";
try
{
@@ -771,12 +775,12 @@ namespace OpenSim.Data.PGSQL
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("WantMask", up.WantToMask);
cmd.Parameters.AddWithValue("WantText", up.WantToText);
cmd.Parameters.AddWithValue("SkillsMask", up.SkillsMask);
cmd.Parameters.AddWithValue("SkillsText", up.SkillsText);
cmd.Parameters.AddWithValue("Languages", up.Language);
cmd.Parameters.AddWithValue("uuid", up.UserId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("WantMask", up.WantToMask));
cmd.Parameters.Add(m_database.CreateParameter("WantText", up.WantToText));
cmd.Parameters.Add(m_database.CreateParameter("SkillsMask", up.SkillsMask));
cmd.Parameters.Add(m_database.CreateParameter("SkillsText", up.SkillsText));
cmd.Parameters.Add(m_database.CreateParameter("Languages", up.Language));
cmd.Parameters.Add(m_database.CreateParameter("uuid", up.UserId));
cmd.ExecuteNonQuery();
}
@@ -784,7 +788,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": AgentInterestsUpdate exception {0}", e.Message);
result = e.Message;
return false;
@@ -798,9 +802,6 @@ namespace OpenSim.Data.PGSQL
OSDArray data = new OSDArray();
string query = "SELECT \"snapshotuuid\" FROM {0} WHERE \"creatoruuid\" = :Id";
// Get classified image assets
try
{
using (NpgsqlConnection dbcon = new NpgsqlConnection(ConnectionString))
@@ -809,7 +810,7 @@ namespace OpenSim.Data.PGSQL
using (NpgsqlCommand cmd = new NpgsqlCommand(string.Format (query,"\"classifieds\""), dbcon))
{
cmd.Parameters.AddWithValue("Id", avatarId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("Id", avatarId));
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
@@ -817,7 +818,7 @@ namespace OpenSim.Data.PGSQL
{
while (reader.Read())
{
data.Add(new OSDString((string)reader["snapshotuuid"].ToString ()));
data.Add(new OSDString((string)reader["snapshotuuid"]));
}
}
}
@@ -828,7 +829,7 @@ namespace OpenSim.Data.PGSQL
using (NpgsqlCommand cmd = new NpgsqlCommand(string.Format (query,"\"userpicks\""), dbcon))
{
cmd.Parameters.AddWithValue("Id", avatarId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("Id", avatarId));
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
@@ -836,7 +837,7 @@ namespace OpenSim.Data.PGSQL
{
while (reader.Read())
{
data.Add(new OSDString((string)reader["snapshotuuid"].ToString ()));
data.Add(new OSDString((string)reader["snapshotuuid"]));
}
}
}
@@ -849,7 +850,7 @@ namespace OpenSim.Data.PGSQL
using (NpgsqlCommand cmd = new NpgsqlCommand(string.Format (query,"\"userpicks\""), dbcon))
{
cmd.Parameters.AddWithValue("Id", avatarId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("Id", avatarId));
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
@@ -857,8 +858,8 @@ namespace OpenSim.Data.PGSQL
{
while (reader.Read())
{
data.Add(new OSDString((string)reader["profileImage"].ToString ()));
data.Add(new OSDString((string)reader["profileFirstImage"].ToString ()));
data.Add(new OSDString((string)reader["profileImage"]));
data.Add(new OSDString((string)reader["profileFirstImage"]));
}
}
}
@@ -867,7 +868,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetAvatarNotes exception {0}", e.Message);
}
return data;
@@ -891,7 +892,7 @@ namespace OpenSim.Data.PGSQL
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("Id", pref.UserId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("Id", pref.UserId));
using (NpgsqlDataReader reader = cmd.ExecuteReader())
{
@@ -900,7 +901,7 @@ namespace OpenSim.Data.PGSQL
reader.Read();
bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail);
bool.TryParse((string)reader["visible"], out pref.Visible);
pref.EMail = (string)reader["email"];
pref.EMail = (string)reader["email"];
}
else
{
@@ -921,7 +922,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": Get preferences exception {0}", e.Message);
result = e.Message;
}
@@ -934,7 +935,8 @@ namespace OpenSim.Data.PGSQL
query += "UPDATE usersettings SET ";
query += "imviaemail=:ImViaEmail, ";
query += "visible=:Visible,";
query += "visible=:Visible, ";
query += "email=:Email ";
query += "WHERE useruuid=:uuid";
try
@@ -944,9 +946,10 @@ namespace OpenSim.Data.PGSQL
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("ImViaEmail", pref.IMViaEmail.ToString().ToLower ());
cmd.Parameters.AddWithValue("Visible", pref.Visible.ToString().ToLower ());
cmd.Parameters.AddWithValue("uuid", pref.UserId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("ImViaEmail", pref.IMViaEmail.ToString().ToLower ()));
cmd.Parameters.Add(m_database.CreateParameter("Visible", pref.Visible.ToString().ToLower ()));
cmd.Parameters.Add(m_database.CreateParameter("EMail", pref.EMail.ToString().ToLower ()));
cmd.Parameters.Add(m_database.CreateParameter("uuid", pref.UserId.ToString()));
lock(Lock)
{
@@ -957,7 +960,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": AgentInterestsUpdate exception {0}", e.Message);
result = e.Message;
return false;
@@ -982,8 +985,8 @@ namespace OpenSim.Data.PGSQL
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("Id", props.UserId.ToString());
cmd.Parameters.AddWithValue (":TagId", props.TagId.ToString());
cmd.Parameters.Add(m_database.CreateParameter("Id", props.UserId));
cmd.Parameters.Add(m_database.CreateParameter(":TagId", props.TagId));
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
@@ -1003,10 +1006,10 @@ namespace OpenSim.Data.PGSQL
using (NpgsqlCommand put = new NpgsqlCommand(query, dbcon))
{
put.Parameters.AddWithValue("Id", props.UserId.ToString());
put.Parameters.AddWithValue("TagId", props.TagId.ToString());
put.Parameters.AddWithValue("DataKey", props.DataKey.ToString());
put.Parameters.AddWithValue("DataVal", props.DataVal.ToString());
put.Parameters.Add(m_database.CreateParameter("Id", props.UserId));
put.Parameters.Add(m_database.CreateParameter("TagId", props.TagId));
put.Parameters.Add(m_database.CreateParameter("DataKey", props.DataKey.ToString()));
put.Parameters.Add(m_database.CreateParameter("DataVal", props.DataVal.ToString()));
lock(Lock)
{
@@ -1020,7 +1023,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": Requst application data exception {0}", e.Message);
result = e.Message;
return false;
@@ -1046,10 +1049,10 @@ namespace OpenSim.Data.PGSQL
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("UserId", props.UserId.ToString());
cmd.Parameters.AddWithValue("TagId", props.TagId.ToString ());
cmd.Parameters.AddWithValue("DataKey", props.DataKey.ToString ());
cmd.Parameters.AddWithValue("DataVal", props.DataKey.ToString ());
cmd.Parameters.Add(m_database.CreateParameter("UserId", props.UserId.ToString()));
cmd.Parameters.Add(m_database.CreateParameter("TagId", props.TagId.ToString ()));
cmd.Parameters.Add(m_database.CreateParameter("DataKey", props.DataKey.ToString ()));
cmd.Parameters.Add(m_database.CreateParameter("DataVal", props.DataKey.ToString ()));
lock(Lock)
{
@@ -1060,7 +1063,7 @@ namespace OpenSim.Data.PGSQL
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": SetUserData exception {0}", e.Message);
return false;
}

View File

@@ -56,6 +56,7 @@ namespace OpenSim.Data.PGSQL
private const int DaysBetweenAccessTimeUpdates = 30;
private bool m_enableCompression = false;
private PGSQLManager m_database;
private string m_connectionString;
private object m_dbLock = new object();
@@ -92,6 +93,7 @@ namespace OpenSim.Data.PGSQL
m_log.ErrorFormat("[PGSQL XASSETDATA]: ***********************************************************");
m_connectionString = connect;
m_database = new PGSQLManager(m_connectionString);
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
{
@@ -138,12 +140,12 @@ namespace OpenSim.Data.PGSQL
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(
@"SELECT ""Name"", ""Description"", ""AccessTime"", ""AssetType"", ""Local"", ""Temporary"", ""AssetFlags"", ""CreatorID"", ""Data""
@"SELECT name, description, access_time, ""AssetType"", local, temporary, asset_flags, creatorid, data
FROM XAssetsMeta
JOIN XAssetsData ON XAssetsMeta.Hash = XAssetsData.Hash WHERE ""ID""=:ID",
JOIN XAssetsData ON XAssetsMeta.hash = XAssetsData.Hash WHERE id=:ID",
dbcon))
{
cmd.Parameters.AddWithValue("ID", assetID.ToString());
cmd.Parameters.Add(m_database.CreateParameter("ID", assetID));
try
{
@@ -151,18 +153,23 @@ namespace OpenSim.Data.PGSQL
{
if (dbReader.Read())
{
asset = new AssetBase(assetID, (string)dbReader["Name"], (sbyte)dbReader["AssetType"], dbReader["CreatorID"].ToString());
asset.Data = (byte[])dbReader["Data"];
asset.Description = (string)dbReader["Description"];
asset = new AssetBase(
assetID,
(string)dbReader["name"],
Convert.ToSByte(dbReader["AssetType"]),
dbReader["creatorid"].ToString());
string local = dbReader["Local"].ToString();
asset.Data = (byte[])dbReader["data"];
asset.Description = (string)dbReader["description"];
string local = dbReader["local"].ToString();
if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
asset.Local = true;
else
asset.Local = false;
asset.Temporary = Convert.ToBoolean(dbReader["Temporary"]);
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
asset.Temporary = Convert.ToBoolean(dbReader["temporary"]);
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
if (m_enableCompression)
{
@@ -179,7 +186,7 @@ namespace OpenSim.Data.PGSQL
}
}
UpdateAccessTime(asset.Metadata, (int)dbReader["AccessTime"]);
UpdateAccessTime(asset.Metadata, (int)dbReader["access_time"]);
}
}
}
@@ -245,6 +252,9 @@ namespace OpenSim.Data.PGSQL
byte[] hash = hasher.ComputeHash(asset.Data);
UUID asset_id;
UUID.TryParse(asset.ID, out asset_id);
// m_log.DebugFormat(
// "[XASSET DB]: Compressed data size for {0} {1}, hash {2} is {3}",
// asset.ID, asset.Name, hash, compressedData.Length);
@@ -253,31 +263,33 @@ namespace OpenSim.Data.PGSQL
{
using (NpgsqlCommand cmd =
new NpgsqlCommand(
@"insert INTO XAssetsMeta(""ID"", ""Hash"", ""Name"", ""Description"", ""AssetType"", ""Local"", ""Temporary"", ""CreateTime"", ""AccessTime"", ""AssetFlags"", ""CreatorID"")
@"insert INTO XAssetsMeta(id, hash, name, description, ""AssetType"", local, temporary, create_time, access_time, asset_flags, creatorid)
Select :ID, :Hash, :Name, :Description, :AssetType, :Local, :Temporary, :CreateTime, :AccessTime, :AssetFlags, :CreatorID
where not exists( Select ""ID"" from XAssetsMeta where ""ID"" = :ID ;
where not exists( Select id from XAssetsMeta where id = :ID);
update XAssetsMeta
set ""ID"" = :ID, ""Hash"" = :Hash, ""Name"" = :Name, ""Description"" = :Description,
""AssetType"" = :AssetType, ""Local"" = :Local, ""Temporary"" = :Temporary, ""CreateTime"" = :CreateTime,
""AccessTime"" = :AccessTime, ""AssetFlags"" = :AssetFlags, ""CreatorID"" = :CreatorID
where ""ID"" = :ID;
set id = :ID, hash = :Hash, name = :Name, description = :Description,
""AssetType"" = :AssetType, local = :Local, temporary = :Temporary, create_time = :CreateTime,
access_time = :AccessTime, asset_flags = :AssetFlags, creatorid = :CreatorID
where id = :ID;
",
dbcon))
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("ID", asset.ID);
cmd.Parameters.AddWithValue("Hash", hash);
cmd.Parameters.AddWithValue("Name", assetName);
cmd.Parameters.AddWithValue("Description", assetDescription);
cmd.Parameters.AddWithValue("AssetType", asset.Type);
cmd.Parameters.AddWithValue("Local", asset.Local);
cmd.Parameters.AddWithValue("Temporary", asset.Temporary);
cmd.Parameters.AddWithValue("CreateTime", now);
cmd.Parameters.AddWithValue("AccessTime", now);
cmd.Parameters.AddWithValue("CreatorID", asset.Metadata.CreatorID);
cmd.Parameters.AddWithValue("AssetFlags", (int)asset.Flags);
cmd.Parameters.Add(m_database.CreateParameter("ID", asset_id));
cmd.Parameters.Add(m_database.CreateParameter("Hash", hash));
cmd.Parameters.Add(m_database.CreateParameter("Name", assetName));
cmd.Parameters.Add(m_database.CreateParameter("Description", assetDescription));
cmd.Parameters.Add(m_database.CreateParameter("AssetType", asset.Type));
cmd.Parameters.Add(m_database.CreateParameter("Local", asset.Local));
cmd.Parameters.Add(m_database.CreateParameter("Temporary", asset.Temporary));
cmd.Parameters.Add(m_database.CreateParameter("CreateTime", now));
cmd.Parameters.Add(m_database.CreateParameter("AccessTime", now));
cmd.Parameters.Add(m_database.CreateParameter("CreatorID", asset.Metadata.CreatorID));
cmd.Parameters.Add(m_database.CreateParameter("AssetFlags", (int)asset.Flags));
cmd.ExecuteNonQuery();
}
}
@@ -297,11 +309,11 @@ namespace OpenSim.Data.PGSQL
{
using (NpgsqlCommand cmd =
new NpgsqlCommand(
@"INSERT INTO XAssetsData(""Hash"", ""Data"") VALUES(:Hash, :Data)",
@"INSERT INTO XAssetsData(hash, data) VALUES(:Hash, :Data)",
dbcon))
{
cmd.Parameters.AddWithValue("Hash", hash);
cmd.Parameters.AddWithValue("Data", asset.Data);
cmd.Parameters.Add(m_database.CreateParameter("Hash", hash));
cmd.Parameters.Add(m_database.CreateParameter("Data", asset.Data));
cmd.ExecuteNonQuery();
}
}
@@ -344,15 +356,18 @@ namespace OpenSim.Data.PGSQL
{
dbcon.Open();
NpgsqlCommand cmd =
new NpgsqlCommand(@"update XAssetsMeta set ""AccessTime""=:AccessTime where ID=:ID", dbcon);
new NpgsqlCommand(@"update XAssetsMeta set access_time=:AccessTime where id=:ID", dbcon);
try
{
UUID asset_id;
UUID.TryParse(assetMetadata.ID, out asset_id);
using (cmd)
{
// create unix epoch time
cmd.Parameters.AddWithValue("ID", assetMetadata.ID);
cmd.Parameters.AddWithValue("AccessTime", (int)Utils.DateTimeToUnixTime(now));
cmd.Parameters.Add(m_database.CreateParameter("id", asset_id));
cmd.Parameters.Add(m_database.CreateParameter("access_time", (int)Utils.DateTimeToUnixTime(now)));
cmd.ExecuteNonQuery();
}
}
@@ -380,9 +395,9 @@ namespace OpenSim.Data.PGSQL
bool exists = false;
using (NpgsqlCommand cmd = new NpgsqlCommand(@"SELECT ""Hash"" FROM XAssetsData WHERE ""Hash""=:Hash", dbcon))
using (NpgsqlCommand cmd = new NpgsqlCommand(@"SELECT hash FROM XAssetsData WHERE hash=:Hash", dbcon))
{
cmd.Parameters.AddWithValue("Hash", hash);
cmd.Parameters.Add(m_database.CreateParameter("Hash", hash));
try
{
@@ -419,7 +434,7 @@ namespace OpenSim.Data.PGSQL
HashSet<UUID> exist = new HashSet<UUID>();
string ids = "'" + string.Join("','", uuids) + "'";
string sql = string.Format(@"SELECT ""ID"" FROM XAssetsMeta WHERE ""ID"" IN ({0})", ids);
string sql = string.Format(@"SELECT id FROM XAssetsMeta WHERE id IN ({0})", ids);
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
{
@@ -459,9 +474,9 @@ namespace OpenSim.Data.PGSQL
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
{
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(@"SELECT ""ID"" FROM XAssetsMeta WHERE ""ID""=:ID", dbcon))
using (NpgsqlCommand cmd = new NpgsqlCommand(@"SELECT id FROM XAssetsMeta WHERE id=:ID", dbcon))
{
cmd.Parameters.AddWithValue("ID", uuid.ToString());
cmd.Parameters.Add(m_database.CreateParameter("id", uuid));
try
{
@@ -503,11 +518,11 @@ namespace OpenSim.Data.PGSQL
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
{
dbcon.Open();
NpgsqlCommand cmd = new NpgsqlCommand( @"SELECT ""Name"", ""Description"", ""AccessTime"", ""AssetType"", ""Temporary"", ""ID"", ""AssetFlags"", ""CreatorID""
NpgsqlCommand cmd = new NpgsqlCommand( @"SELECT name, description, access_time, ""AssetType"", temporary, id, asset_flags, creatorid
FROM XAssetsMeta
LIMIT :start, :count", dbcon);
cmd.Parameters.AddWithValue("start", start);
cmd.Parameters.AddWithValue("count", count);
cmd.Parameters.Add(m_database.CreateParameter("start", start));
cmd.Parameters.Add(m_database.CreateParameter("count", count));
try
{
@@ -516,18 +531,18 @@ namespace OpenSim.Data.PGSQL
while (dbReader.Read())
{
AssetMetadata metadata = new AssetMetadata();
metadata.Name = (string)dbReader["Name"];
metadata.Description = (string)dbReader["Description"];
metadata.Type = (sbyte)dbReader["AssetType"];
metadata.Temporary = Convert.ToBoolean(dbReader["Temporary"]); // Not sure if this is correct.
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
metadata.FullID = DBGuid.FromDB(dbReader["ID"]);
metadata.CreatorID = dbReader["CreatorID"].ToString();
metadata.Name = (string)dbReader["name"];
metadata.Description = (string)dbReader["description"];
metadata.Type = Convert.ToSByte(dbReader["AssetType"]);
metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]);
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
metadata.FullID = DBGuid.FromDB(dbReader["id"]);
metadata.CreatorID = dbReader["creatorid"].ToString();
// We'll ignore this for now - it appears unused!
// metadata.SHA1 = dbReader["hash"]);
UpdateAccessTime(metadata, (int)dbReader["AccessTime"]);
UpdateAccessTime(metadata, (int)dbReader["access_time"]);
retList.Add(metadata);
}
@@ -553,9 +568,9 @@ namespace OpenSim.Data.PGSQL
{
dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(@"delete from XAssetsMeta where ""ID""=:ID", dbcon))
using (NpgsqlCommand cmd = new NpgsqlCommand(@"delete from XAssetsMeta where id=:ID", dbcon))
{
cmd.Parameters.AddWithValue("ID", id);
cmd.Parameters.Add(m_database.CreateParameter(id, id));
cmd.ExecuteNonQuery();
}

View File

@@ -89,4 +89,58 @@ CREATE TABLE usersettings (
"visible" bytea NOT NULL,
PRIMARY KEY ("useruuid")
);
commit;
commit;
:VERSION 4
BEGIN;
-- Classifieds
ALTER TABLE classifieds DROP CONSTRAINT classifiedspk;
ALTER TABLE classifieds ALTER COLUMN classifieduuid SET DATA TYPE uuid using classifieduuid::uuid;
ALTER TABLE classifieds ALTER COLUMN creatoruuid SET DATA TYPE uuid using creatoruuid::uuid;
ALTER TABLE classifieds ALTER COLUMN parceluuid SET DATA TYPE uuid using parceluuid::uuid;
ALTER TABLE classifieds ALTER COLUMN snapshotuuid SET DATA TYPE uuid using snapshotuuid::uuid;
ALTER TABLE classifieds ADD CONSTRAINT classifiedspk PRIMARY KEY (classifieduuid);
-- Notes
ALTER TABLE usernotes DROP CONSTRAINT usernoteuk;
ALTER TABLE usernotes ALTER COLUMN useruuid SET DATA TYPE uuid USING useruuid::uuid;
ALTER TABLE usernotes ALTER COLUMN targetuuid SET DATA TYPE uuid USING targetuuid::uuid;
ALTER TABLE usernotes ADD CONSTRAINT usernoteuk UNIQUE (useruuid,targetuuid);
-- Userpicks
ALTER TABLE userpicks DROP CONSTRAINT userpicks_pkey;
ALTER TABLE userpicks ALTER COLUMN pickuuid SET DATA TYPE uuid USING pickuuid::uuid;
ALTER TABLE userpicks ALTER COLUMN creatoruuid SET DATA TYPE uuid USING creatoruuid::uuid;
ALTER TABLE userpicks ALTER COLUMN parceluuid SET DATA TYPE uuid USING parceluuid::uuid;
ALTER TABLE userpicks ALTER COLUMN parceluuid SET DATA TYPE uuid USING parceluuid::uuid;
ALTER TABLE userpicks ADD PRIMARY KEY (pickuuid);
-- Userprofile
ALTER TABLE userprofile DROP CONSTRAINT userprofile_pkey;
ALTER TABLE userprofile ALTER COLUMN useruuid SET DATA TYPE uuid USING useruuid::uuid;
ALTER TABLE userprofile ALTER COLUMN "profilePartner" SET DATA TYPE uuid USING "profilePartner"::uuid;
-- Force column conversions
ALTER TABLE userprofile ALTER COLUMN "profileAllowPublish" SET DATA TYPE boolean USING CASE WHEN false THEN false ELSE true END;
ALTER TABLE userprofile ALTER COLUMN "profileMaturePublish" SET DATA TYPE boolean USING CASE WHEN false THEN false ELSE true END;
ALTER TABLE userprofile ALTER COLUMN "profileImage" SET DATA TYPE uuid USING "profileImage"::uuid;
ALTER TABLE userprofile ALTER COLUMN "profileFirstImage" SET DATA TYPE uuid USING "profileFirstImage"::uuid;
ALTER TABLE userprofile ADD PRIMARY KEY (useruuid);
-- Userdata
ALTER TABLE userdata DROP CONSTRAINT userdata_pkey;
ALTER TABLE userdata ALTER COLUMN "UserId" SET DATA TYPE uuid USING "UserId"::uuid;
ALTER TABLE userdata ALTER COLUMN "UserId" SET DATA TYPE uuid USING "UserId"::uuid;
ALTER TABLE userdata ADD PRIMARY KEY ("UserId","TagId");
-- Usersettings
ALTER TABLE usersettings DROP CONSTRAINT usersettings_pkey;
ALTER TABLE usersettings ALTER COLUMN useruuid SET DATA TYPE uuid USING useruuid::uuid;
ALTER TABLE usersettings ALTER COLUMN visible SET DATA TYPE boolean USING CASE WHEN false THEN false ELSE true END;
ALTER TABLE usersettings ADD COLUMN email varchar(254) NOT NULL;
ALTER TABLE usersettings ADD PRIMARY KEY (useruuid);
COMMIT;

View File

@@ -25,3 +25,51 @@ CREATE TABLE XAssetsData (
);
COMMIT;
:VERSION 2
BEGIN;
ALTER TABLE xassetsmeta ALTER COLUMN "Local" SET DATA TYPE boolean USING CASE WHEN '0' THEN FALSE ELSE TRUE END;
ALTER TABLE xassetsmeta ALTER COLUMN "Temporary" SET DATA TYPE boolean USING CASE WHEN '0' THEN FALSE ELSE TRUE END;
ALTER TABLE xassetsmeta ALTER COLUMN "Hash" SET DATA TYPE char(66);
ALTER TABLE xassetsdata ALTER COLUMN "Hash" SET DATA TYPE char(66);
COMMIT;
:VERSION 3
BEGIN;
ALTER TABLE xassetsmeta RENAME COLUMN "ID" TO id;
ALTER TABLE xassetsmeta RENAME COLUMN "Hash" TO hash;
ALTER TABLE xassetsmeta RENAME COLUMN "Name" TO name;
ALTER TABLE xassetsmeta RENAME COLUMN "Description" TO description;
ALTER TABLE xassetsmeta RENAME COLUMN "Local" to local;
ALTER TABLE xassetsmeta RENAME COLUMN "Temporary" TO temporary;
ALTER TABLE xassetsmeta RENAME COLUMN "CreateTime" TO create_time;
ALTER TABLE xassetsmeta RENAME COLUMN "AccessTime" TO access_time;
ALTER TABLE xassetsmeta RENAME COLUMN "AssetFlags" TO asset_flags;
ALTER TABLE xassetsmeta RENAME COLUMN "CreatorID" TO creatorid;
ALTER TABLE xassetsmeta DROP CONSTRAINT xassetsmeta_pkey;
ALTER TABLE xassetsmeta ADD PRIMARY KEY (id);
ALTER TABLE xassetsdata RENAME COLUMN "Hash" TO hash;
ALTER TABLE xassetsdata RENAME COLUMN "Data" TO data;
ALTER TABLE xassetsdata DROP CONSTRAINT xassetsdata_pkey;
ALTER TABLE xassetsdata ADD PRIMARY KEY (hash);
COMMIT;
:VERSION 4
BEGIN;
ALTER TABLE xassetsmeta ALTER COLUMN id SET DATA TYPE uuid USING id::uuid;
ALTER TABLE xassetsmeta ALTER COLUMN hash SET DATA TYPE bytea USING hash::bytea;
ALTER TABLE xassetsdata ALTER COLUMN hash SET DATA TYPE bytea USING hash::bytea;
COMMIT;

View File

@@ -92,3 +92,110 @@ BEGIN;
COMMIT;
:VERSION 3
BEGIN;
-- Not a pretty way to do this, but it did not work as-is
-- and nothing was found about converting between existing data
-- and the new type.
-- Since there should be nothing to preserve ...
DROP TABLE IF EXISTS os_groups_groups CASCADE;
CREATE TABLE os_groups_groups (
"GroupID" uuid PRIMARY KEY NOT NULL,
"Location" varchar(255) NOT NULL DEFAULT '',
"Name" varchar(255) NOT NULL DEFAULT '',
"Charter" text NOT NULL,
"InsigniaID" uuid NOT NULL,
"FounderID" uuid NOT NULL,
"MembershipFee" integer NOT NULL DEFAULT '0',
"OpenEnrollment" varchar(255) NOT NULL DEFAULT '',
"ShowInList" integer NOT NULL DEFAULT '0',
"AllowPublish" integer NOT NULL DEFAULT '0',
"MaturePublish" integer NOT NULL DEFAULT '0',
"OwnerRoleID" uuid NOT NULL
);
DROP TABLE IF EXISTS os_groups_membership;
CREATE TABLE os_groups_membership (
"GroupID"uuid NOT NULL,
"PrincipalID" VARCHAR(255) NOT NULL DEFAULT '',
"SelectedRoleID" uuid NOT NULL,
"Contribution" integer NOT NULL DEFAULT '0',
"ListInProfile" integer NOT NULL DEFAULT '1',
"AcceptNotices" integer NOT NULL DEFAULT '1',
"AccessToken" uuid NOT NULL,
constraint os_groupmemberpk PRIMARY KEY ("GroupID", "PrincipalID")
);
DROP TABLE IF EXISTS os_groups_roles;
CREATE TABLE os_groups_roles (
"GroupID" uuid NOT NULL,
"RoleID" uuid NOT NULL,
"Name" varchar(255) NOT NULL DEFAULT '',
"Description" varchar(255) NOT NULL DEFAULT '',
"Title" varchar(255) NOT NULL DEFAULT '',
"Powers" varchar(36) NOT NULL DEFAULT '',
constraint os_grouprolepk PRIMARY KEY ("GroupID","RoleID")
);
DROP TABLE IF EXISTS os_groups_rolemembership;
CREATE TABLE os_groups_rolemembership (
"GroupID" uuid NOT NULL,
"RoleID" uuid NOT NULL,
"PrincipalID" VARCHAR(255) NOT NULL DEFAULT '',
constraint os_grouprolememberpk PRIMARY KEY ("GroupID","RoleID","PrincipalID")
);
DROP TABLE IF EXISTS os_groups_invites;
CREATE TABLE os_groups_invites (
"InviteID" uuid NOT NULL,
"GroupID" uuid NOT NULL,
"RoleID" uuid NOT NULL,
"PrincipalID" VARCHAR(255) NOT NULL DEFAULT '',
"TMStamp" timestamp NOT NULL DEFAULT now(),
constraint os_groupinvitespk PRIMARY KEY ("InviteID")
);
DROP TABLE IF EXISTS os_groups_notices;
CREATE TABLE os_groups_notices (
"GroupID" uuid NOT NULL,
"NoticeID" uuid NOT NULL,
"TMStamp" integer NOT NULL DEFAULT '0',
"FromName" varchar(255) NOT NULL DEFAULT '',
"Subject" varchar(255) NOT NULL DEFAULT '',
"Message" text NOT NULL,
"HasAttachment" integer NOT NULL DEFAULT '0',
"AttachmentType" integer NOT NULL DEFAULT '0',
"AttachmentName" varchar(128) NOT NULL DEFAULT '',
"AttachmentItemID" uuid NOT NULL,
"AttachmentOwnerID" varchar(255) NOT NULL DEFAULT '',
constraint os_groupsnoticespk PRIMARY KEY ("NoticeID")
);
DROP TABLE IF EXISTS os_groups_principals;
CREATE TABLE os_groups_principals (
"PrincipalID" VARCHAR(255) NOT NULL DEFAULT '',
"ActiveGroupID" uuid NOT NULL,
constraint os_groupprincpk PRIMARY KEY ("PrincipalID")
);
COMMIT;

View File

@@ -239,7 +239,7 @@ namespace OpenSim.Data.SQLite
if (inventoryRow == null)
{
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();
fillFolderRow(inventoryRow, folder);
@@ -298,7 +298,7 @@ namespace OpenSim.Data.SQLite
if (inventoryRow == null)
{
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();
fillItemRow(inventoryRow, item);

View File

@@ -114,7 +114,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": UserAccount exception {0}", e.Message);
}
n.Add("classifieduuid", OSD.FromUUID(Id));
@@ -217,7 +217,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": ClassifiedesUpdate exception {0}", e.Message);
result = e.Message;
return false;
@@ -243,7 +243,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": DeleteClassifiedRecord exception {0}", e.Message);
return false;
}
@@ -289,7 +289,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetPickInfo exception {0}", e.Message);
}
return true;
@@ -326,7 +326,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetAvatarPicks exception {0}", e.Message);
}
return data;
@@ -378,7 +378,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetPickInfo exception {0}", e.Message);
}
return pick;
@@ -446,7 +446,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": UpdateAvatarNotes exception {0}", e.Message);
return false;
}
@@ -471,7 +471,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": DeleteUserPickRecord exception {0}", e.Message);
return false;
}
@@ -507,7 +507,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetAvatarNotes exception {0}", e.Message);
}
return true;
@@ -550,7 +550,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": UpdateAvatarNotes exception {0}", e.Message);
return false;
}
@@ -577,7 +577,7 @@ namespace OpenSim.Data.SQLite
}
catch(Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetAvatarProperties exception {0}", e.Message);
result = e.Message;
return false;
@@ -696,7 +696,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": AgentPropertiesUpdate exception {0}", e.Message);
return false;
@@ -733,7 +733,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": AgentInterestsUpdate exception {0}", e.Message);
result = e.Message;
return false;
@@ -747,7 +747,8 @@ namespace OpenSim.Data.SQLite
query += "UPDATE usersettings SET ";
query += "imviaemail=:ImViaEmail, ";
query += "visible=:Visible ";
query += "visible=:Visible, ";
query += "email=:EMail ";
query += "WHERE useruuid=:uuid";
try
@@ -757,6 +758,7 @@ namespace OpenSim.Data.SQLite
cmd.CommandText = query;
cmd.Parameters.AddWithValue(":ImViaEmail", pref.IMViaEmail);
cmd.Parameters.AddWithValue(":Visible", pref.Visible);
cmd.Parameters.AddWithValue(":EMail", pref.EMail);
cmd.Parameters.AddWithValue(":uuid", pref.UserId.ToString());
cmd.ExecuteNonQuery();
@@ -764,7 +766,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": AgentInterestsUpdate exception {0}", e.Message);
result = e.Message;
return false;
@@ -796,7 +798,7 @@ namespace OpenSim.Data.SQLite
{
bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail);
bool.TryParse((string)reader["visible"], out pref.Visible);
pref.EMail = (string)reader["email"];
pref.EMail = (string)reader["email"];
}
else
{
@@ -816,7 +818,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": Get preferences exception {0}", e.Message);
result = e.Message;
return false;
@@ -871,7 +873,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": Requst application data exception {0}", e.Message);
result = e.Message;
return false;
@@ -904,7 +906,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": SetUserData exception {0}", e.Message);
return false;
}
@@ -968,7 +970,7 @@ namespace OpenSim.Data.SQLite
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
m_log.ErrorFormat("[PROFILES_DATA]" +
": GetAvatarNotes exception {0}", e.Message);
}
return data;

View File

@@ -520,6 +520,12 @@ namespace OpenSim.Framework
if (!m_attachments.ContainsKey(attach.AttachPoint))
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);
}
}

View File

@@ -54,6 +54,7 @@ namespace OpenSim.Framework
public int assetThrottle;
public int textureThrottle;
public int totalThrottle;
public int maxThrottle;
public Dictionary<string, int> SyncRequests = 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
/// invoked by the caller in either synchronous mode or asynchronous modes.
/// </remarks>
public class RestClient
public class RestClient : IDisposable
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -148,6 +148,33 @@ namespace OpenSim.Framework.Communications
#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>
/// Add a path element to the query, e.g. assets
/// </summary>
@@ -320,6 +347,10 @@ namespace OpenSim.Framework.Communications
if (auth != null)
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);
try
{
@@ -366,6 +397,9 @@ namespace OpenSim.Framework.Communications
_resource.Seek(0, SeekOrigin.Begin);
}
if (WebUtil.DebugLevel >= 5)
WebUtil.LogResponseDetail(reqnum, _resource);
return _resource;
}
}
@@ -382,16 +416,18 @@ namespace OpenSim.Framework.Communications
if (auth != null)
auth.AddAuthorization(_request.Headers);
m_log.InfoFormat("[REST]: Request Length {0}", _request.ContentLength);
m_log.InfoFormat("[REST]: Sending Web Request {0}", buildUri());
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();
m_log.Info("[REST]: GetRequestStream is ok");
byte[] buf = new byte[1024];
int length = src.Read(buf, 0, 1024);
m_log.Info("[REST]: First Read is ok");
while (length > 0)
{
dst.Write(buf, 0, length);
@@ -406,14 +442,29 @@ namespace OpenSim.Framework.Communications
{
m_log.WarnFormat("[REST]: Request {0} {1} failed with status {2} and message {3}",
RequestMethod, _request.RequestUri, e.Status, e.Message);
return null;
}
catch (Exception e)
{
m_log.WarnFormat(
"[REST]: Request {0} {1} failed with exception {2} {3}",
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);

View File

@@ -424,9 +424,9 @@ namespace OpenSim.Framework.Console
return new string[] { new List<string>(current.Keys)[0] };
}
public string[] Resolve(string[] cmd)
private CommandInfo ResolveCommand(string[] cmd, out string[] result)
{
string[] result = cmd;
result = cmd;
int index = -1;
Dictionary<string, object> current = tree;
@@ -458,7 +458,7 @@ namespace OpenSim.Framework.Console
}
else if (found.Count > 0)
{
return new string[0];
return null;
}
else
{
@@ -467,21 +467,37 @@ namespace OpenSim.Framework.Console
}
if (current.ContainsKey(String.Empty))
return (CommandInfo)current[String.Empty];
return null;
}
public bool HasCommand(string command)
{
string[] result;
return ResolveCommand(Parser.Parse(command), out result) != null;
}
public string[] Resolve(string[] cmd)
{
string[] result;
CommandInfo ci = ResolveCommand(cmd, out result);
if (ci == null)
return new string[0];
if (ci.fn.Count == 0)
return new string[0];
foreach (CommandDelegate fn in ci.fn)
{
CommandInfo ci = (CommandInfo)current[String.Empty];
if (ci.fn.Count == 0)
if (fn != null)
fn(ci.module, result);
else
return new string[0];
foreach (CommandDelegate fn in ci.fn)
{
if (fn != null)
fn(ci.module, result);
else
return new string[0];
}
return result;
}
return new string[0];
return result;
}
public XmlElement GetXml(XmlDocument doc)

View File

@@ -156,7 +156,7 @@ namespace OpenSim.Framework.Console
}
/// <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>
/// <param name='console'>Can be null if no console is available.</param>
/// <param name='rawConsoleVector'>/param>
@@ -176,7 +176,7 @@ namespace OpenSim.Framework.Console
}
/// <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>
/// <param name='console'>Can be null if no console is available.</param>
/// <param name='rawConsoleInt'>/param>
@@ -195,6 +195,46 @@ namespace OpenSim.Framework.Console
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>
/// Convert a console integer to a natural int, automatically complaining if a console is given.
/// </summary>

View File

@@ -32,6 +32,8 @@ using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.IO;
using Nini.Config;
using log4net;
namespace OpenSim.Framework.Console
@@ -41,7 +43,9 @@ namespace OpenSim.Framework.Console
/// </summary>
public class LocalConsole : CommandConsole
{
// 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_historyPath;
private bool m_historyEnable;
// private readonly object m_syncRoot = new object();
private const string LOGLEVEL_NONE = "(none)";
@@ -79,8 +83,54 @@ namespace OpenSim.Framework.Console
return Colors[(Math.Abs(input.ToUpper().GetHashCode()) % Colors.Length)];
}
public LocalConsole(string defaultPrompt) : base(defaultPrompt)
public LocalConsole(string defaultPrompt, IConfig startupConfig = null) : base(defaultPrompt)
{
if (startupConfig == null) return;
m_historyEnable = startupConfig.GetBoolean("ConsoleHistoryFileEnabled", false);
if (!m_historyEnable)
{
m_log.Info("[LOCAL CONSOLE]: Persistent command line history from file is Disabled");
return;
}
string m_historyFile = startupConfig.GetString("ConsoleHistoryFile", "OpenSimConsoleHistory.txt");
int m_historySize = startupConfig.GetInt("ConsoleHistoryFileLines", 100);
m_historyPath = Path.GetFullPath(Path.Combine(Util.configDir(), m_historyFile));
m_log.InfoFormat("[LOCAL CONSOLE]: Persistent command line history is Enabled, up to {0} lines from file {1}", m_historySize, m_historyPath);
if (File.Exists(m_historyPath))
{
using (StreamReader history_file = new StreamReader(m_historyPath))
{
string line;
while ((line = history_file.ReadLine()) != null)
{
m_history.Add(line);
}
}
if (m_history.Count > m_historySize)
{
while (m_history.Count > m_historySize)
m_history.RemoveAt(0);
using (StreamWriter history_file = new StreamWriter(m_historyPath))
{
foreach (string line in m_history)
{
history_file.WriteLine(line);
}
}
}
m_log.InfoFormat("[LOCAL CONSOLE]: Read {0} lines of command line history from file {1}", m_history.Count, m_historyPath);
}
else
{
m_log.InfoFormat("[LOCAL CONSOLE]: Creating new empty command line history file {0}", m_historyPath);
File.Create(m_historyPath).Dispose();
}
}
private void AddToHistory(string text)
@@ -89,6 +139,10 @@ namespace OpenSim.Framework.Console
m_history.RemoveAt(0);
m_history.Add(text);
if (m_historyEnable)
{
File.AppendAllText(m_historyPath, text + Environment.NewLine);
}
}
/// <summary>

View File

@@ -82,6 +82,7 @@ namespace OpenSim.Framework.Console
public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn) {}
public void AddCommand(string module, bool shared, string command, string help, string longhelp, string descriptivehelp, CommandDelegate fn) {}
public string[] FindNextOption(string[] cmd, bool term) { return null; }
public bool HasCommand(string cmd) { return false; }
public string[] Resolve(string[] cmd) { return null; }
public XmlElement GetXml(XmlDocument doc) { return null; }
}

View File

@@ -67,9 +67,16 @@ namespace OpenSim.Framework
string help, string longhelp, string descriptivehelp,
CommandDelegate fn);
string[] FindNextOption(string[] cmd, bool term);
/// <summary>
/// Has the given command already been registered?
/// </summary>
/// <returns></returns>
/// <param name="command">Command.</param>
bool HasCommand(string command);
string[] Resolve(string[] cmd);
string[] FindNextOption(string[] command, bool term);
string[] Resolve(string[] command);
XmlElement GetXml(XmlDocument doc);
}

View File

@@ -65,13 +65,18 @@ namespace OpenSim.Framework
/// </remarks>
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>
/// Send initial scene data to the client controlling this agent
/// </summary>
/// <remarks>
/// This includes scene object data and the appearance data of other avatars.
/// </remarks>
void SendInitialDataToMe();
void SendInitialDataToClient();
/// <summary>
/// Direction in which the scene presence is looking.

View File

@@ -0,0 +1,312 @@
/*
* 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;
namespace OpenSim.Framework.Monitoring
{
public class Job
{
public string Name;
public WaitCallback Callback;
public object O;
public Job(string name, WaitCallback callback, object o)
{
Name = name;
Callback = callback;
O = o;
}
}
public class JobEngine
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public int LogLevel { get; set; }
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<Job> m_requestQueue;
private CancellationTokenSource m_cancelSource = new CancellationTokenSource();
private Stat m_requestsWaitingStat;
private Job m_currentJob;
/// <summary>
/// Used to signal that we are ready to complete stop.
/// </summary>
private ManualResetEvent m_finishedProcessingAfterStop = new ManualResetEvent(false);
public JobEngine()
{
RequestProcessTimeoutOnStop = 5000;
MainConsole.Instance.Commands.AddCommand(
"Debug",
false,
"debug jobengine",
"debug jobengine <start|stop|status>",
"Start, stop or get status of the job engine.",
"If stopped then all jobs are processed immediately.",
HandleControlCommand);
}
public void Start()
{
lock (this)
{
if (IsRunning)
return;
IsRunning = true;
m_finishedProcessingAfterStop.Reset();
m_requestQueue = new BlockingCollection<Job>(new ConcurrentQueue<Job>(), 5000);
m_requestsWaitingStat =
new Stat(
"JobsWaiting",
"Number of jobs waiting for processing.",
"",
"",
"server",
"jobengine",
StatType.Pull,
MeasuresOfInterest.None,
stat => stat.Value = m_requestQueue.Count,
StatVerbosity.Debug);
StatsManager.RegisterStat(m_requestsWaitingStat);
Watchdog.StartThread(
ProcessRequests,
"JobEngineThread",
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("[JOB 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(
"[JOB 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_requestsWaitingStat);
m_requestsWaitingStat = null;
m_requestQueue = null;
}
}
}
public bool QueueRequest(string name, WaitCallback req, object o)
{
if (LogLevel >= 1)
m_log.DebugFormat("[JOB ENGINE]: Queued job {0}", name);
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 Job(name, req, o));
if (!m_warnOverMaxQueue)
m_warnOverMaxQueue = true;
return true;
}
else
{
if (m_warnOverMaxQueue)
{
// m_log.WarnFormat(
// "[JOB ENGINE]: Request queue at maximum capacity, not recording request from {0} in {1}",
// client.AgentID, m_udpServer.Scene.Name);
m_log.WarnFormat("[JOB ENGINE]: Request queue at maximum capacity, not recording job");
m_warnOverMaxQueue = false;
}
return false;
}
}
private void ProcessRequests()
{
try
{
while (IsRunning || m_requestQueue.Count > 0)
{
m_currentJob = 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);
// }
// }
if (LogLevel >= 1)
m_log.DebugFormat("[JOB ENGINE]: Processing job {0}", m_currentJob.Name);
m_currentJob.Callback.Invoke(m_currentJob.O);
if (LogLevel >= 1)
m_log.DebugFormat("[JOB ENGINE]: Processed job {0}", m_currentJob.Name);
m_currentJob = null;
}
}
catch (OperationCanceledException)
{
}
m_finishedProcessingAfterStop.Set();
}
private void HandleControlCommand(string module, string[] args)
{
// if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
// return;
if (args.Length < 3)
{
MainConsole.Instance.Output("Usage: debug jobengine <stop|start|status|loglevel>");
return;
}
string subCommand = args[2];
if (subCommand == "stop")
{
Stop();
MainConsole.Instance.OutputFormat("Stopped job engine.");
}
else if (subCommand == "start")
{
Start();
MainConsole.Instance.OutputFormat("Started job engine.");
}
else if (subCommand == "status")
{
MainConsole.Instance.OutputFormat("Job engine running: {0}", IsRunning);
MainConsole.Instance.OutputFormat("Current job {0}", m_currentJob != null ? m_currentJob.Name : "none");
MainConsole.Instance.OutputFormat(
"Jobs waiting: {0}", IsRunning ? m_requestQueue.Count.ToString() : "n/a");
MainConsole.Instance.OutputFormat("Log Level: {0}", LogLevel);
}
else if (subCommand == "loglevel")
{
// int logLevel;
int logLevel = int.Parse(args[3]);
// if (ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out logLevel))
// {
LogLevel = logLevel;
MainConsole.Instance.OutputFormat("Set log level to {0}", LogLevel);
// }
}
else
{
MainConsole.Instance.OutputFormat("Unrecognized job engine subcommand {0}", subCommand);
}
}
}
}

View File

@@ -82,6 +82,9 @@ namespace OpenSim.Framework.Monitoring
// IRegionModuleBase.Initialize
public void Initialise(IConfigSource source)
{
if (source == null)
return;
IConfig cfg = source.Configs["Monitoring"];
if (cfg != null)
@@ -141,19 +144,19 @@ namespace OpenSim.Framework.Monitoring
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.
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);
StatsManager.RegisterStat(tempStat);
RegisteredStats.Add(tempName, tempStat);
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,
(s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; });
(s) => { s.Value = Math.Round(Process.GetCurrentProcess().UserProcessorTime.TotalSeconds, 3); });
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,
(s) => { s.Value = Process.GetCurrentProcess().Threads.Count; });
@@ -253,11 +256,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
// "Mono Performance Counters": http://www.mono-project.com/Mono_Performance_Counters
private delegate double PerfCounterNextValue();
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)
{
@@ -265,16 +265,13 @@ namespace OpenSim.Framework.Monitoring
{
try
{
// Kludge for factor to run double duty. If -1, subtract the value from one
if (factor == -1)
stat.Value = 1 - perfControl.perfCounter.NextValue();
else
stat.Value = perfControl.perfCounter.NextValue() / factor;
stat.Value = Math.Round(perfControl.perfCounter.NextValue(), 3);
}
catch (Exception e)
{
m_log.ErrorFormat("{0} Exception on NextValue fetching {1}: {2}", LogHeader, stat.Name, e);
}
perfControl.lastFetch = Util.EnvironmentTickCount();
}
}

View File

@@ -171,7 +171,8 @@ namespace OpenSim.Framework.Monitoring
foreach (char c in DisallowedShortNameCharacters)
{
if (shortName.IndexOf(c) != -1)
throw new Exception(string.Format("Stat name {0} cannot contain character {1}", shortName, c));
shortName = shortName.Replace(c, '#');
// throw new Exception(string.Format("Stat name {0} cannot contain character {1}", shortName, c));
}
ShortName = shortName;

View File

@@ -70,18 +70,18 @@ namespace OpenSim.Framework.Monitoring
{
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;
}
if (cmd[3] == "start")
if (cmd[2] == "start")
{
Start();
con.OutputFormat("Now recording all stats to file every {0}ms", m_statsLogIntervalMs);
}
else if (cmd[3] == "stop")
else if (cmd[2] == "stop")
{
Stop();
con.Output("Stopped recording stats to file.");

View File

@@ -87,7 +87,7 @@ namespace OpenSim.Framework.Monitoring
/// </summary>
public Stat Stat { get; set; }
public ThreadWatchdogInfo(Thread thread, int timeout)
public ThreadWatchdogInfo(Thread thread, int timeout, string name)
{
Thread = thread;
Timeout = timeout;
@@ -96,8 +96,8 @@ namespace OpenSim.Framework.Monitoring
Stat
= new Stat(
thread.Name,
string.Format("Last update of thread {0}", thread.Name),
name,
string.Format("Last update of thread {0}", name),
"",
"ms",
"server",
@@ -133,6 +133,8 @@ namespace OpenSim.Framework.Monitoring
/// /summary>
public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout;
public static JobEngine JobEngine { get; private set; }
/// <summary>
/// Is this watchdog active?
/// </summary>
@@ -173,6 +175,7 @@ namespace OpenSim.Framework.Monitoring
static Watchdog()
{
JobEngine = new JobEngine();
m_threads = new Dictionary<int, ThreadWatchdogInfo>();
m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
m_watchdogTimer.AutoReset = false;
@@ -187,15 +190,16 @@ namespace OpenSim.Framework.Monitoring
/// <param name="priority">Priority to run the thread at</param>
/// <param name="isBackground">True to run this thread as a background thread, otherwise false</param>
/// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
/// <param name="log">If true then creation of thread is logged.</param>
/// <returns>The newly created Thread object</returns>
public static Thread StartThread(
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout)
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, bool log = true)
{
return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS);
return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS, log);
}
/// <summary>
/// Start a new thread that is tracked by the watchdog timer
/// Start a new thread that is tracked by the watchdog
/// </summary>
/// <param name="start">The method that will be executed in a new thread</param>
/// <param name="name">A name to give to the new thread</param>
@@ -208,31 +212,67 @@ namespace OpenSim.Framework.Monitoring
/// Normally, this will just return some useful debugging information.
/// </param>
/// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
/// <param name="log">If true then creation of thread is logged.</param>
/// <returns>The newly created Thread object</returns>
public static Thread StartThread(
ThreadStart start, string name, ThreadPriority priority, bool isBackground,
bool alarmIfTimeout, Func<string> alarmMethod, int timeout)
bool alarmIfTimeout, Func<string> alarmMethod, int timeout, bool log = true)
{
Thread thread = new Thread(start);
thread.Name = name;
thread.Priority = priority;
thread.IsBackground = isBackground;
ThreadWatchdogInfo twi
= new ThreadWatchdogInfo(thread, timeout)
= new ThreadWatchdogInfo(thread, timeout, name)
{ AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
m_log.DebugFormat(
"[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
if (log)
m_log.DebugFormat(
"[WATCHDOG]: Started tracking thread {0}, ID {1}", name, twi.Thread.ManagedThreadId);
lock (m_threads)
m_threads.Add(twi.Thread.ManagedThreadId, twi);
thread.Start();
thread.Name = name;
return thread;
}
/// <summary>
/// Run the callback in a new thread immediately. If the thread exits with an exception log it but do
/// not propogate it.
/// </summary>
/// <param name="callback">Code for the thread to execute.</param>
/// <param name="name">Name of the thread</param>
/// <param name="obj">Object to pass to the thread.</param>
public static void RunInThread(WaitCallback callback, string name, object obj, bool log = false)
{
if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
{
Culture.SetCurrentCulture();
callback(obj);
return;
}
ThreadStart ts = new ThreadStart(delegate()
{
try
{
Culture.SetCurrentCulture();
callback(obj);
Watchdog.RemoveThread(log:false);
}
catch (Exception e)
{
m_log.Error(string.Format("[WATCHDOG]: Exception in thread {0}.", name), e);
}
});
StartThread(ts, name, ThreadPriority.Normal, true, false, log:log);
}
/// <summary>
/// Marks the current thread as alive
/// </summary>
@@ -244,24 +284,26 @@ namespace OpenSim.Framework.Monitoring
/// <summary>
/// Stops watchdog tracking on the current thread
/// </summary>
/// <param name="log">If true then normal events in thread removal are not logged.</param>
/// <returns>
/// True if the thread was removed from the list of tracked
/// threads, otherwise false
/// </returns>
public static bool RemoveThread()
public static bool RemoveThread(bool log = true)
{
return RemoveThread(Thread.CurrentThread.ManagedThreadId);
return RemoveThread(Thread.CurrentThread.ManagedThreadId, log);
}
private static bool RemoveThread(int threadID)
private static bool RemoveThread(int threadID, bool log = true)
{
lock (m_threads)
{
ThreadWatchdogInfo twi;
if (m_threads.TryGetValue(threadID, out twi))
{
m_log.DebugFormat(
"[WATCHDOG]: Removing thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
if (log)
m_log.DebugFormat(
"[WATCHDOG]: Removing thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
twi.Cleanup();
m_threads.Remove(threadID);
@@ -411,5 +453,20 @@ namespace OpenSim.Framework.Monitoring
m_watchdogTimer.Start();
}
public static void RunWhenPossible(string jobType, WaitCallback callback, string name, object obj, bool log = false)
{
if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
{
Culture.SetCurrentCulture();
callback(obj);
return;
}
if (JobEngine.IsRunning)
JobEngine.QueueRequest(name, callback, obj);
else
RunInThread(callback, name, obj, log);
}
}
}

View File

@@ -101,7 +101,6 @@ namespace OpenSim.Framework
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[REGION INFO]";
public bool commFailTF = false;
public string RegionFile = String.Empty;
public bool isSandbox = false;
public bool Persistent = true;
@@ -128,7 +127,6 @@ namespace OpenSim.Framework
private int m_objectCapacity = 0;
private int m_maxPrimsPerUser = -1;
private int m_linksetCapacity = 0;
private int m_agentCapacity = 0;
private string m_regionType = String.Empty;
private RegionLightShareData m_windlight = new RegionLightShareData();
protected uint m_httpPort;
@@ -352,10 +350,7 @@ namespace OpenSim.Framework
get { return m_linksetCapacity; }
}
public int AgentCapacity
{
get { return m_agentCapacity; }
}
public int AgentCapacity { get; set; }
public byte AccessLevel
{
@@ -749,7 +744,7 @@ namespace OpenSim.Framework
#endregion
m_agentCapacity = config.GetInt("MaxAgents", 100);
AgentCapacity = config.GetInt("MaxAgents", 100);
allKeys.Remove("MaxAgents");
// Multi-tenancy
@@ -865,8 +860,8 @@ namespace OpenSim.Framework
if (m_linksetCapacity > 0)
config.Set("LinksetPrims", m_linksetCapacity);
if (m_agentCapacity > 0)
config.Set("MaxAgents", m_agentCapacity);
if (AgentCapacity > 0)
config.Set("MaxAgents", AgentCapacity);
if (ScopeID != UUID.Zero)
config.Set("ScopeID", ScopeID.ToString());
@@ -881,11 +876,6 @@ namespace OpenSim.Framework
config.Set("MaptileStaticFile", MaptileStaticFile);
}
public bool ignoreIncomingConfiguration(string configuration_key, object configuration_result)
{
return true;
}
public void SaveRegionToFile(string description, string filename)
{
if (filename.ToLower().EndsWith(".ini"))

View File

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

View File

@@ -46,8 +46,8 @@ namespace OpenSim.Framework.Serialization.External
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static Dictionary<string, Action<InventoryItemBase, XmlTextReader>> m_InventoryItemXmlProcessors
= new Dictionary<string, Action<InventoryItemBase, XmlTextReader>>();
private static Dictionary<string, Action<InventoryItemBase, XmlReader>> m_InventoryItemXmlProcessors
= new Dictionary<string, Action<InventoryItemBase, XmlReader>>();
#region InventoryItemBase Processor initialization
static UserInventoryItemSerializer()
@@ -76,103 +76,103 @@ namespace OpenSim.Framework.Serialization.External
#endregion
#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);
}
private static void ProcessID(InventoryItemBase item, XmlTextReader reader)
private static void ProcessID(InventoryItemBase item, XmlReader reader)
{
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);
}
private static void ProcessCreatorUUID(InventoryItemBase item, XmlTextReader reader)
private static void ProcessCreatorUUID(InventoryItemBase item, XmlReader reader)
{
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
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);
}
private static void ProcessOwner(InventoryItemBase item, XmlTextReader reader)
private static void ProcessOwner(InventoryItemBase item, XmlReader reader)
{
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);
}
private static void ProcessAssetType(InventoryItemBase item, XmlTextReader reader)
private static void ProcessAssetType(InventoryItemBase item, XmlReader reader)
{
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");
}
private static void ProcessSaleType(InventoryItemBase item, XmlTextReader reader)
private static void ProcessSaleType(InventoryItemBase item, XmlReader reader)
{
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);
}
private static void ProcessBasePermissions(InventoryItemBase item, XmlTextReader reader)
private static void ProcessBasePermissions(InventoryItemBase item, XmlReader reader)
{
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);
}
private static void ProcessEveryOnePermissions(InventoryItemBase item, XmlTextReader reader)
private static void ProcessEveryOnePermissions(InventoryItemBase item, XmlReader reader)
{
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);
}
private static void ProcessFlags(InventoryItemBase item, XmlTextReader reader)
private static void ProcessFlags(InventoryItemBase item, XmlReader reader)
{
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");
}
private static void ProcessGroupOwned(InventoryItemBase item, XmlTextReader reader)
private static void ProcessGroupOwned(InventoryItemBase item, XmlReader 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);
}

View File

@@ -832,28 +832,40 @@ namespace OpenSim.Framework.Servers.HttpServer
return; // never log these; they're just binary data
Stream inputStream = Util.Copy(request.InputStream);
if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip"))
inputStream = new GZipStream(inputStream, System.IO.Compression.CompressionMode.Decompress);
using (StreamReader reader = new StreamReader(inputStream, Encoding.UTF8))
Stream innerStream = null;
try
{
string output;
if (DebugLevel == 5)
if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip"))
{
char[] chars = new char[WebUtil.MaxRequestDiagLength + 1]; // +1 so we know to add "..." only if needed
int len = reader.Read(chars, 0, WebUtil.MaxRequestDiagLength + 1);
output = new string(chars, 0, Math.Min(len, WebUtil.MaxRequestDiagLength));
if (len > WebUtil.MaxRequestDiagLength)
output += "...";
}
else
{
output = reader.ReadToEnd();
innerStream = inputStream;
inputStream = new GZipStream(innerStream, System.IO.Compression.CompressionMode.Decompress);
}
m_log.DebugFormat("[LOGHTTP] {0}", Util.BinaryToASCII(output));
using (StreamReader reader = new StreamReader(inputStream, Encoding.UTF8))
{
string output;
if (DebugLevel == 5)
{
char[] chars = new char[WebUtil.MaxRequestDiagLength + 1]; // +1 so we know to add "..." only if needed
int len = reader.Read(chars, 0, WebUtil.MaxRequestDiagLength + 1);
output = new string(chars, 0, Math.Min(len, WebUtil.MaxRequestDiagLength));
if (len > WebUtil.MaxRequestDiagLength)
output += "...";
}
else
{
output = reader.ReadToEnd();
}
m_log.DebugFormat("[LOGHTTP] {0}", Util.BinaryToASCII(output));
}
}
finally
{
if (innerStream != null)
innerStream.Dispose();
inputStream.Dispose();
}
}
@@ -981,19 +993,33 @@ namespace OpenSim.Framework.Servers.HttpServer
/// <param name="response"></param>
private byte[] HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response)
{
String requestBody;
Stream requestStream = request.InputStream;
Stream innerStream = null;
try
{
if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip"))
{
innerStream = requestStream;
requestStream = new GZipStream(innerStream, System.IO.Compression.CompressionMode.Decompress);
}
if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip"))
requestStream = new GZipStream(requestStream, System.IO.Compression.CompressionMode.Decompress);
using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8))
{
requestBody = reader.ReadToEnd();
}
}
finally
{
if (innerStream != null)
innerStream.Dispose();
requestStream.Dispose();
}
Encoding encoding = Encoding.UTF8;
StreamReader reader = new StreamReader(requestStream, encoding);
string requestBody = reader.ReadToEnd();
reader.Close();
requestStream.Close();
//m_log.Debug(requestBody);
requestBody = requestBody.Replace("<base64></base64>", "");
string responseString = String.Empty;
XmlRpcRequest xmlRprcRequest = null;
@@ -1089,18 +1115,16 @@ namespace OpenSim.Framework.Servers.HttpServer
response.ContentType = "text/xml";
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;
XmlRpcResponseSerializer.Singleton.Serialize(writer, xmlRpcResponse);
writer.Flush();
outs.Flush();
outs.Position = 0;
using (StreamReader sr = new StreamReader(outs))
{
writer.Formatting = Formatting.None;
XmlRpcResponseSerializer.Singleton.Serialize(writer, xmlRpcResponse);
writer.Flush();
outs.Flush();
outs.Position = 0;
using (StreamReader sr = new StreamReader(outs))
{
responseString = sr.ReadToEnd();
}
responseString = sr.ReadToEnd();
}
}
}

View File

@@ -26,6 +26,7 @@
*/
using System;
using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers.HttpServer
{
@@ -61,6 +62,24 @@ namespace OpenSim.Framework.Servers.HttpServer
Description = description;
m_httpMethod = httpMethod;
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

View File

@@ -70,9 +70,9 @@ namespace OpenSim.Framework.Servers.HttpServer
_id = id;
_engine = new Thread(new ThreadStart(Engine));
_engine.Name = EngineID;
_engine.IsBackground = true;
_engine.Start();
_engine.Name = string.Format ("Engine:{0}",EngineID);
ThreadTracker.Add(_engine);
}
@@ -91,9 +91,9 @@ namespace OpenSim.Framework.Servers.HttpServer
public void Start()
{
_engine = new Thread(new ThreadStart(Engine));
_engine.Name = EngineID;
_engine.IsBackground = true;
_engine.Start();
_engine.Name = string.Format ("Engine:{0}",EngineID);
ThreadTracker.Add(_engine);
}

View File

@@ -150,9 +150,9 @@ namespace OpenSim.Framework.Servers.HttpServer
public void Start()
{
_engine = new Thread(new ThreadStart(Engine));
_engine.Name = _engineId;
_engine.IsBackground = true;
_engine.Start();
_engine.Name = string.Format ("Engine:{0}",_engineId);
ThreadTracker.Add(_engine);

View File

@@ -52,23 +52,25 @@ namespace OpenSim.Framework.Servers.HttpServer
request.Method = verb;
request.ContentType = "text/xml";
MemoryStream buffer = new MemoryStream();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
using (MemoryStream buffer = new MemoryStream())
{
XmlSerializer serializer = new XmlSerializer(type);
serializer.Serialize(writer, obj);
writer.Flush();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
{
XmlSerializer serializer = new XmlSerializer(type);
serializer.Serialize(writer, obj);
writer.Flush();
}
int length = (int)buffer.Length;
request.ContentLength = length;
using (Stream requestStream = request.GetRequestStream())
requestStream.Write(buffer.ToArray(), 0, length);
}
int length = (int) buffer.Length;
request.ContentLength = length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(buffer.ToArray(), 0, length);
// IAsyncResult result = request.BeginGetResponse(AsyncCallback, request);
request.BeginGetResponse(AsyncCallback, request);
}

View File

@@ -60,24 +60,25 @@ namespace OpenSim.Framework.Servers.HttpServer
request.ContentType = "text/xml";
request.Timeout = 10000;
MemoryStream buffer = new MemoryStream();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
using (MemoryStream buffer = new MemoryStream())
{
XmlSerializer serializer = new XmlSerializer(type);
serializer.Serialize(writer, obj);
writer.Flush();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
{
XmlSerializer serializer = new XmlSerializer(type);
serializer.Serialize(writer, obj);
writer.Flush();
}
int length = (int)buffer.Length;
request.ContentLength = length;
using (Stream requestStream = request.GetRequestStream())
requestStream.Write(buffer.ToArray(), 0, length);
}
int length = (int) buffer.Length;
request.ContentLength = length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(buffer.ToArray(), 0, length);
requestStream.Close();
// IAsyncResult result = request.BeginGetResponse(AsyncCallback, request);
request.BeginGetResponse(AsyncCallback, request);
}

View File

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

View File

@@ -32,7 +32,6 @@ using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
using Animation = OpenSim.Framework.Animation;
namespace OpenSim.Framework.Tests

View File

@@ -25,55 +25,48 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Net;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using System;
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
namespace OpenSim.Framework
{
/// <summary>
/// Mock scene for unit tests
/// 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 MockScene : SceneBase
public class ThreadSafeRandom : Random
{
public int ObjectNameCallsReceived
{
get { return m_objectNameCallsReceived; }
}
protected int m_objectNameCallsReceived;
public MockScene() : base(new RegionInfo(1000, 1000, null, null))
{
m_regStatus = RegionStatus.Up;
}
public override void Update(int frames) {}
public override void LoadWorldMap() {}
public override ISceneAgent AddNewAgent(IClientAPI client, PresenceType type)
{
client.OnObjectName += RecordObjectNameCall;
public ThreadSafeRandom() : base() {}
// FIXME
return null;
public ThreadSafeRandom(int seed): base (seed) {}
public override int Next()
{
lock (this)
return base.Next();
}
public override bool CloseAgent(UUID agentID, bool force) { return true; }
public override bool CheckClient(UUID clientId, IPEndPoint endPoint) { return true; }
public override void OtherRegionUp(GridRegion otherRegion) { }
public override bool TryGetScenePresence(UUID uuid, out ScenePresence sp) { sp = null; return false; }
/// <summary>
/// Doesn't really matter what the call is - we're using this to test that a packet has actually been received
/// </summary>
protected void RecordObjectNameCall(IClientAPI remoteClient, uint localID, string message)
public override int Next(int maxValue)
{
m_objectNameCallsReceived++;
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

@@ -80,6 +80,7 @@ namespace OpenSim.Framework
public string User = string.Empty;
public string SimName = string.Empty;
public string GlobalPos = "<0,0,0>";
public string Gatekeeper = string.Empty;
public int SortOrder = 0;
public bool Enabled = false;
}

View File

@@ -138,7 +138,7 @@ namespace OpenSim.Framework
}
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)
private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
@@ -509,6 +509,19 @@ namespace OpenSim.Framework
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>
/// Is the platform Windows?
/// </summary>
@@ -1307,46 +1320,6 @@ namespace OpenSim.Framework
return ret;
}
public static string Compress(string text)
{
byte[] buffer = Util.UTF8.GetBytes(text);
MemoryStream memory = new MemoryStream();
using (GZipStream compressor = new GZipStream(memory, CompressionMode.Compress, true))
{
compressor.Write(buffer, 0, buffer.Length);
}
memory.Position = 0;
byte[] compressed = new byte[memory.Length];
memory.Read(compressed, 0, compressed.Length);
byte[] compressedBuffer = new byte[compressed.Length + 4];
Buffer.BlockCopy(compressed, 0, compressedBuffer, 4, compressed.Length);
Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, compressedBuffer, 0, 4);
return Convert.ToBase64String(compressedBuffer);
}
public static string Decompress(string compressedText)
{
byte[] compressedBuffer = Convert.FromBase64String(compressedText);
using (MemoryStream memory = new MemoryStream())
{
int msgLength = BitConverter.ToInt32(compressedBuffer, 0);
memory.Write(compressedBuffer, 4, compressedBuffer.Length - 4);
byte[] buffer = new byte[msgLength];
memory.Position = 0;
using (GZipStream decompressor = new GZipStream(memory, CompressionMode.Decompress))
{
decompressor.Read(buffer, 0, buffer.Length);
}
return Util.UTF8.GetString(buffer);
}
}
/// <summary>
/// Copy data from one stream to another, leaving the read position of both streams at the beginning.
/// </summary>
@@ -2027,7 +2000,7 @@ namespace OpenSim.Framework
{
ThreadFuncNum = threadFuncNum;
this.context = context;
LogThread = true;
LogThread = false;
Thread = null;
Running = false;
Aborted = false;
@@ -2208,6 +2181,12 @@ namespace OpenSim.Framework
(LogThreadPool >= 2) ? full : partial);
}
}
else
{
// Since we didn't log "Queue threadfunc", don't log "Run threadfunc" or "End threadfunc" either.
// Those log lines aren't useful when we don't know which function is running in the thread.
threadInfo.LogThread = false;
}
switch (FireAndForgetMethod)
{
@@ -2420,36 +2399,6 @@ namespace OpenSim.Framework
#endregion FireAndForget Threading Pattern
/// <summary>
/// Run the callback on a different thread, outside the thread pool. This is used for tasks
/// that may take a long time.
/// </summary>
public static void RunThreadNoTimeout(WaitCallback callback, string name, object obj)
{
if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
{
Culture.SetCurrentCulture();
callback(obj);
return;
}
Thread t = new Thread(delegate()
{
try
{
Culture.SetCurrentCulture();
callback(obj);
}
catch (Exception e)
{
m_log.Error("Exception in thread " + name, e);
}
});
t.Name = name;
t.Start();
}
/// <summary>
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
/// and negative every 24.9 days. This trims down TickCount so it doesn't wrap
@@ -2626,7 +2575,7 @@ namespace OpenSim.Framework
}
#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.
reader.ReadStartElement();
@@ -2637,7 +2586,7 @@ namespace OpenSim.Framework
return result;
}
public static UUID ReadUUID(XmlTextReader reader, string name)
public static UUID ReadUUID(XmlReader reader, string name)
{
UUID id;
string idStr;
@@ -2656,7 +2605,7 @@ namespace OpenSim.Framework
return id;
}
public static Vector3 ReadVector(XmlTextReader reader, string name)
public static Vector3 ReadVector(XmlReader reader, string name)
{
Vector3 vec;
@@ -2669,7 +2618,7 @@ namespace OpenSim.Framework
return vec;
}
public static Quaternion ReadQuaternion(XmlTextReader reader, string name)
public static Quaternion ReadQuaternion(XmlReader reader, string name)
{
Quaternion quat = new Quaternion();
@@ -2698,7 +2647,7 @@ namespace OpenSim.Framework
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);
// !!!!! to deal with flags without commas

View File

@@ -69,7 +69,7 @@ namespace OpenSim.Framework
/// <summary>
/// Request number for diagnostic purposes.
/// </summary>
public static int RequestNumber { get; internal set; }
public static int RequestNumber { get; set; }
/// <summary>
/// Control where OSD requests should be serialized per endpoint.
@@ -176,7 +176,8 @@ namespace OpenSim.Framework
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;
@@ -262,12 +263,12 @@ namespace OpenSim.Framework
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);
// We need to close the gzip stream before we write it anywhere
// 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();
request.ContentLength = buf.Length; //Count bytes to send

View File

@@ -213,6 +213,8 @@ namespace OpenSim
// Make sure command line options take precedence
m_config.Source.Merge(argvSource);
m_config.Source.ReplaceKeyValues();
ReadConfigSettings();
return m_config;

View File

@@ -115,7 +115,7 @@ namespace OpenSim
Util.FireAndForgetMethod = asyncCallMethod;
stpMinThreads = startupConfig.GetInt("MinPoolThreads", 15);
stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 15);
stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 300);
m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) ");
}
@@ -155,7 +155,7 @@ namespace OpenSim
((RemoteConsole)m_console).ReadConfig(Config);
break;
default:
m_console = new LocalConsole("Region");
m_console = new LocalConsole("Region", Config.Configs["Startup"]);
break;
}
}
@@ -268,23 +268,24 @@ namespace OpenSim
m_console.Commands.AddCommand("Archiving", false, "load oar",
"load oar [--merge] [--skip-assets]"
+ " [--default-user \"User Name\"]"
+ " [--force-terrain] [--force-parcels]"
+ " [--no-objects]"
+ " [--rotation degrees] [--rotation-center \"<x,y,z>\"]"
+ " [--displacement \"<x,y,z>\"]"
+ " [--default-user \"User Name\"]"
+ " [--displacement \"<x,y,z>\"]"
+ " [<OAR path>]",
"Load a region's data from an OAR archive.",
"--merge will merge the OAR with the existing scene (suppresses terrain and parcel info loading)." + Environment.NewLine
+ "--skip-assets will load the OAR but ignore the assets it contains." + Environment.NewLine
+ "--displacement will add this value to the position of every object loaded" + Environment.NewLine
+ "--force-terrain forces the loading of terrain from the oar (undoes suppression done by --merge)" + Environment.NewLine
+ "--force-parcels forces the loading of parcels from the oar (undoes suppression done by --merge)" + Environment.NewLine
+ "--rotation specified rotation to be applied to the oar. Specified in degrees." + Environment.NewLine
+ "--rotation-center Location (relative to original OAR) to apply rotation. Default is <128,128,0>" + Environment.NewLine
+ "--no-objects suppresses the addition of any objects (good for loading only the terrain)" + Environment.NewLine
+ "The path can be either a filesystem location or a URI."
+ " If this is not given then the command looks for an OAR named region.oar in the current directory.",
"--merge will merge the OAR with the existing scene (suppresses terrain and parcel info loading).\n"
+ "--default-user will use this user for any objects with an owner whose UUID is not found in the grid.\n"
+ "--displacement will add this value to the position of every object loaded.\n"
+ "--force-terrain forces the loading of terrain from the oar (undoes suppression done by --merge).\n"
+ "--force-parcels forces the loading of parcels from the oar (undoes suppression done by --merge).\n"
+ "--no-objects suppresses the addition of any objects (good for loading only the terrain).\n"
+ "--rotation specified rotation to be applied to the oar. Specified in degrees.\n"
+ "--rotation-center Location (relative to original OAR) to apply rotation. Default is <128,128,0>.\n"
+ "--skip-assets will load the OAR but ignore the assets it contains.\n\n"
+ "The path can be either a filesystem location or a URI.\n"
+ " If this is not given then the command looks for an OAR named region.oar in the current directory.",
LoadOar);
m_console.Commands.AddCommand("Archiving", false, "save oar",
@@ -921,7 +922,7 @@ namespace OpenSim
foreach (IRegionModuleBase module in scene.RegionModules.Values)
{
if (module.GetType().GetInterface("ISharedRegionModule") != null)
if (module.GetType().GetInterface("ISharedRegionModule") == null)
nonSharedModules.Add(module);
else
sharedModules.Add(module);

View File

@@ -730,8 +730,6 @@ namespace OpenSim
clientServer = clientNetworkServers;
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.SetTerrain(scene.Heightmap.GetFloatsSerialised());
scene.PhysicsScene.SetWaterLevel((float) regionInfo.RegionSettings.WaterHeight);
@@ -747,10 +745,13 @@ namespace OpenSim
protected override Scene CreateScene(RegionInfo regionInfo, ISimulationDataService simDataService,
IEstateDataService estateDataService, AgentCircuitManager circuitManager)
{
Vector3 regionExtent = new Vector3(regionInfo.RegionSizeX, regionInfo.RegionSizeY, regionInfo.RegionSizeZ);
PhysicsScene physicsScene = GetPhysicsScene(regionInfo.RegionName, regionExtent);
SceneCommunicationService sceneGridService = new SceneCommunicationService();
return new Scene(
regionInfo, circuitManager, sceneGridService,
regionInfo, circuitManager, physicsScene, sceneGridService,
simDataService, estateDataService,
Config, m_version);
}

View File

@@ -268,8 +268,8 @@ namespace OpenSim.Region.ClientStack.Linden
public string SeedCapRequest(string request, string path, string param,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
m_log.DebugFormat(
"[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID);
// m_log.DebugFormat(
// "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID);
if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
{
@@ -546,7 +546,6 @@ namespace OpenSim.Region.ClientStack.Linden
if (texture_list.Count > 0)
{
ScenePresence avatar = null;
IClientAPI client = null;
m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
if (avatar != null)

View File

@@ -101,7 +101,7 @@ namespace OpenSim.Region.ClientStack.Linden
"debug eq [0|1|2]",
"Turn on event queue debugging\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",
HandleDebugEq);
@@ -188,9 +188,11 @@ namespace OpenSim.Region.ClientStack.Linden
{
if (!queues.ContainsKey(agentId))
{
m_log.DebugFormat(
"[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
agentId, m_scene.RegionInfo.RegionName);
if (DebugLevel > 0)
m_log.DebugFormat(
"[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
agentId, m_scene.RegionInfo.RegionName);
queues[agentId] = new Queue<OSD>();
}
@@ -302,9 +304,10 @@ namespace OpenSim.Region.ClientStack.Linden
{
// Register an event queue for the client
m_log.DebugFormat(
"[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
agentID, caps, m_scene.RegionInfo.RegionName);
if (DebugLevel > 0)
m_log.DebugFormat(
"[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
agentID, caps, m_scene.RegionInfo.RegionName);
// Let's instantiate a Queue for this agent right now
TryGetQueue(agentID);
@@ -720,8 +723,9 @@ namespace OpenSim.Region.ClientStack.Linden
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}>",
LogHeader, handle, avatarID, regionSizeX, regionSizeY);
if (DebugLevel > 0)
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);
Enqueue(item, avatarID);
@@ -730,8 +734,10 @@ namespace OpenSim.Region.ClientStack.Linden
public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath,
ulong regionHandle, int regionSizeX, int regionSizeY)
{
m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, avatarID={2}, regionSize={3},{4}>",
LogHeader, regionHandle, avatarID, regionSizeX, regionSizeY);
if (DebugLevel > 0)
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);
Enqueue(item, avatarID);
}
@@ -741,8 +747,9 @@ namespace OpenSim.Region.ClientStack.Linden
uint locationID, uint flags, string capsURL,
UUID avatarID, int regionSizeX, int regionSizeY)
{
m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, avatarID={2}, regionSize=<{3},{4}>",
LogHeader, regionHandle, avatarID, regionSizeX, regionSizeY);
if (DebugLevel > 0)
m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, endPoint={2}, avatarID={3}",
LogHeader, regionHandle, regionExternalEndPoint, avatarID, regionSizeX, regionSizeY);
OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint,
locationID, flags, capsURL, avatarID, regionSizeX, regionSizeY);
@@ -753,8 +760,9 @@ namespace OpenSim.Region.ClientStack.Linden
IPEndPoint newRegionExternalEndPoint,
string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY)
{
m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
LogHeader, handle, avatarID, regionSizeX, regionSizeY);
if (DebugLevel > 0)
m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
LogHeader, handle, avatarID, regionSizeX, regionSizeY);
OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint,
capsURL, avatarID, sessionID, regionSizeX, regionSizeY);
@@ -819,4 +827,4 @@ namespace OpenSim.Region.ClientStack.Linden
Enqueue(item, avatarID);
}
}
}
}

View File

@@ -43,7 +43,6 @@ using OpenSim.Region.CoreModules.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.OptionalModules.World.NPC;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.ClientStack.Linden.Tests
{

View File

@@ -27,6 +27,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using log4net;
using Nini.Config;
@@ -37,7 +38,7 @@ using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
// using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
namespace OpenSim.Region.ClientStack.Linden
@@ -56,8 +57,8 @@ namespace OpenSim.Region.ClientStack.Linden
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimulatorFeaturesModule")]
public class SimulatorFeaturesModule : ISharedRegionModule, ISimulatorFeaturesModule
{
// private static readonly ILog m_log =
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public event SimulatorFeaturesRequestDelegate OnSimulatorFeaturesRequest;
@@ -69,18 +70,31 @@ namespace OpenSim.Region.ClientStack.Linden
private OSDMap m_features = new OSDMap();
private string m_SearchURL = string.Empty;
private string m_DestinationGuideURL = string.Empty;
private bool m_ExportSupported = false;
private string m_GridName = string.Empty;
private string m_GridURL = string.Empty;
#region ISharedRegionModule Members
public void Initialise(IConfigSource source)
{
IConfig config = source.Configs["SimulatorFeatures"];
if (config != null)
{
m_SearchURL = config.GetString("SearchServerURI", string.Empty);
if (config != null)
{
// These are normaly set in their respective modules
m_SearchURL = config.GetString("SearchServerURI", m_SearchURL);
m_DestinationGuideURL = config.GetString ("DestinationGuideURI", m_DestinationGuideURL);
if (m_DestinationGuideURL == string.Empty) // Make this consistent with the variable in the LoginService config
m_DestinationGuideURL = config.GetString("DestinationGuide", m_DestinationGuideURL);
m_ExportSupported = config.GetBoolean("ExportSupported", m_ExportSupported);
m_GridURL = Util.GetConfigVarFromSections<string>(source, "GatekeeperURI",
new string[] { "Startup", "Hypergrid", "SimulatorFeatures" }, String.Empty);
m_GridName = config.GetString("GridName", string.Empty);
if (m_GridName == string.Empty)
m_GridName = Util.GetConfigVarFromSections<string>(source, "gridname",
new string[] { "GridInfo", "SimulatorFeatures" }, String.Empty);
}
AddDefaultFeatures();
@@ -101,6 +115,7 @@ namespace OpenSim.Region.ClientStack.Linden
public void RegionLoaded(Scene s)
{
GetGridExtraFeatures(s);
}
public void PostInitialise()
@@ -126,6 +141,7 @@ namespace OpenSim.Region.ClientStack.Linden
/// </remarks>
private void AddDefaultFeatures()
{
lock (m_features)
{
m_features["MeshRezEnabled"] = true;
@@ -141,15 +157,27 @@ namespace OpenSim.Region.ClientStack.Linden
// Extra information for viewers that want to use it
// TODO: Take these out of here into their respective modules, like map-server-url
OSDMap extrasMap = new OSDMap();
OSDMap extrasMap;
if(m_features.ContainsKey("OpenSimExtras"))
{
extrasMap = (OSDMap)m_features["OpenSimExtras"];
}
else
extrasMap = new OSDMap();
if (m_SearchURL != string.Empty)
extrasMap["search-server-url"] = m_SearchURL;
if (!string.IsNullOrEmpty(m_DestinationGuideURL))
extrasMap["destination-guide-url"] = m_DestinationGuideURL;
if (m_ExportSupported)
extrasMap["ExportSupported"] = true;
if (m_GridURL != string.Empty)
extrasMap["GridURL"] = m_GridURL;
if (m_GridName != string.Empty)
extrasMap["GridName"] = m_GridName;
if (extrasMap.Count > 0)
m_features["OpenSimExtras"] = extrasMap;
}
}
@@ -199,11 +227,16 @@ namespace OpenSim.Region.ClientStack.Linden
private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod, UUID agentID)
{
// m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
OSDMap copy = DeepCopy();
// Let's add the agentID to the destination guide, if it is expecting that.
if (copy.ContainsKey("OpenSimExtras") && ((OSDMap)(copy["OpenSimExtras"])).ContainsKey("destination-guide-url"))
((OSDMap)copy["OpenSimExtras"])["destination-guide-url"] = Replace(((OSDMap)copy["OpenSimExtras"])["destination-guide-url"], "[USERID]", agentID.ToString());
SimulatorFeaturesRequestDelegate handlerOnSimulatorFeaturesRequest = OnSimulatorFeaturesRequest;
if (handlerOnSimulatorFeaturesRequest != null)
handlerOnSimulatorFeaturesRequest(agentID, ref copy);
@@ -217,5 +250,46 @@ namespace OpenSim.Region.ClientStack.Linden
return responsedata;
}
/// <summary>
/// Gets the grid extra features.
/// </summary>
/// <param name='featuresURI'>
/// The URI Robust uses to handle the get_extra_features request
/// </param>
private void GetGridExtraFeatures(Scene scene)
{
Dictionary<string, object> extraFeatures = scene.GridService.GetExtraFeatures();
if (extraFeatures.ContainsKey("Result") && extraFeatures["Result"] != null && extraFeatures["Result"].ToString() == "Failure")
{
m_log.WarnFormat("[SIMULATOR FEATURES MODULE]: Unable to retrieve grid-wide features");
return;
}
lock (m_features)
{
OSDMap extrasMap = new OSDMap();
foreach(string key in extraFeatures.Keys)
{
extrasMap[key] = (string)extraFeatures[key];
if (key == "ExportSupported")
{
bool.TryParse(extraFeatures[key].ToString(), out m_ExportSupported);
}
}
m_features["OpenSimExtras"] = extrasMap;
}
}
private string Replace(string url, string substring, string replacement)
{
if (!String.IsNullOrEmpty(url) && url.Contains(substring))
return url.Replace(substring, replacement);
return url;
}
}
}

View File

@@ -47,7 +47,6 @@ using OpenSim.Region.CoreModules.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;

View File

@@ -4201,6 +4201,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
}
@@ -11848,7 +11852,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <returns></returns>
protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
{
//m_log.Debug("texture cached: " + packet.ToString());
AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
@@ -11864,24 +11867,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
cachedresp.WearableData =
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;
if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
// Find the cached baked textures for this user, if they're available
IAssetService cache = m_scene.AssetService;
IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
WearableCacheItem[] cacheItems = null;
if (bakedTextureModule != null && cache != null)
{
// 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
WearableCacheItem[] cacheItems = null;
ScenePresence p = m_scene.GetScenePresence(AgentId);
if (p.Appearance != null)
{
if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
{
try
@@ -11890,22 +11891,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
p.Appearance.WearableCacheItems = cacheItems;
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)
{
cacheItems = null;
@@ -11916,87 +11901,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
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;
cache.Store(item.TextureAsset);
}
item.TextureAsset.Temporary = true;
item.TextureAsset.Local = true;
cache.Store(item.TextureAsset);
}
}
if (cacheItems != null)
// Return the cached textures
for (int i = 0; i < maxWearablesLoop; i++)
{
WearableCacheItem item =
WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex, cacheItems);
for (int i = 0; i < maxWearablesLoop; i++)
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
cachedresp.WearableData[i].HostName = new byte[0];
if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
{
WearableCacheItem item =
WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
cachedresp.WearableData[i].HostName = new byte[0];
if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
{
cachedresp.WearableData[i].TextureID = item.TextureID;
}
else
{
cachedresp.WearableData[i].TextureID = UUID.Zero;
}
cachedresp.WearableData[i].TextureID = item.TextureID;
}
}
else
{
for (int i = 0; i < maxWearablesLoop; i++)
else
{
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
{
if (cache == null)
// 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].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.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
cachedresp.WearableData[i].TextureID = UUID.Zero;
cachedresp.WearableData[i].HostName = new byte[0];
}
}
cachedresp.Header.Zerocoded = true;
OutPacket(cachedresp, ThrottleOutPacketType.Task);
@@ -12389,6 +12341,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// provide your own method.</param>
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)
{
bool logPacket = true;
@@ -12447,6 +12403,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name="Pack">OpenMetaverse.packet</param>
public void ProcessInPacket(Packet packet)
{
if (m_inPacketsToDrop != null)
if (m_inPacketsToDrop.Contains(packet.Type.ToString()))
return;
if (DebugPacketLevel > 0)
{
bool logPacket = true;
@@ -13171,5 +13131,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP
eq.Enqueue(BuildEvent("BulkUpdateInventory",
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

@@ -76,6 +76,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// or removed, this number must also change</summary>
const int THROTTLE_CATEGORY_COUNT = 8;
/// <summary>
/// Controls whether information is logged about each outbound packet immediately before it is sent. For debug purposes.
/// </summary>
/// <remarks>Any level above 0 will turn on logging.</remarks>
public int DebugDataOutLevel { get; set; }
/// <summary>
/// Controls whether information is logged about each outbound packet immediately before it is sent. For debug purposes.
/// </summary>
/// <remarks>Any level above 0 will turn on logging.</remarks>
public int ThrottleDebugLevel
{
get
{
return m_throttleDebugLevel;
}
set
{
m_throttleDebugLevel = value;
m_throttleClient.DebugLevel = m_throttleDebugLevel;
m_throttleCategory.DebugLevel = m_throttleDebugLevel;
foreach (TokenBucket tb in m_throttleCategories)
tb.DebugLevel = m_throttleDebugLevel;
}
}
private int m_throttleDebugLevel;
/// <summary>Fired when updated networking stats are produced for this client</summary>
public event PacketStats OnPacketStats;
/// <summary>Fired when the queue for a packet category is empty. This event can be
@@ -201,9 +229,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_maxRTO = maxRTO;
// 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);
// Create a token bucket throttle for the total categary with the client bucket as a throttle
m_throttleCategory = new TokenBucket(m_throttleClient, 0);
m_throttleClient
= new AdaptiveTokenBucket(
string.Format("adaptive throttle for {0} in {1}", AgentID, server.Scene.Name),
parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled);
// Create a token bucket throttle for the total category with the client bucket as a throttle
m_throttleCategory
= new TokenBucket(
string.Format("total throttle for {0} in {1}", AgentID, server.Scene.Name),
m_throttleClient, 0);
// Create an array of token buckets for this clients different throttle categories
m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
@@ -215,8 +251,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Initialize the packet outboxes, where packets sit while they are waiting for tokens
m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
// Initialize the token buckets that control the throttling for each category
m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type));
m_throttleCategories[i]
= new TokenBucket(
string.Format("{0} throttle for {1} in {2}", type, AgentID, server.Scene.Name),
m_throttleCategory, rates.GetRate(type));
}
// Default the retransmission timeout to one second
@@ -262,6 +302,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate;
m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate;
m_info.totalThrottle = (int)m_throttleCategory.DripRate;
m_info.maxThrottle = (int)m_throttleClient.MaxDripRate;
return m_info;
}
@@ -278,6 +319,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
throw new NotImplementedException();
}
/// <summary>
/// Get the total number of pakcets queued for this client.
/// </summary>
/// <returns></returns>
public int GetTotalPacketsQueuedCount()
{
int total = 0;
for (int i = 0; i <= (int)ThrottleOutPacketType.Asset; i++)
total += m_packetOutboxes[i].Count;
return total;
}
/// <summary>
/// Get the number of packets queued for the given throttle type.
/// </summary>
/// <returns></returns>
/// <param name="throttleType"></param>
public int GetPacketsQueuedCount(ThrottleOutPacketType throttleType)
{
if ((int)throttleType > 0)
return m_packetOutboxes[(int)throttleType].Count;
else
return 0;
}
/// <summary>
/// Return statistics information about client packet queues.
/// </summary>
@@ -347,6 +415,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
if (ThrottleDebugLevel > 0)
{
long total = resend + land + wind + cloud + task + texture + asset;
m_log.DebugFormat(
"[LLUDPCLIENT]: {0} is setting throttles in {1} to Resend={2}, Land={3}, Wind={4}, Cloud={5}, Task={6}, Texture={7}, Asset={8}, TOTAL = {9}",
AgentID, m_udpServer.Scene.Name, resend, land, wind, cloud, task, texture, asset, total);
}
// Make sure none of the throttles are set below our packet MTU,
// otherwise a throttle could become permanently clogged
resend = Math.Max(resend, LLUDPServer.MTU);
@@ -364,8 +440,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
texture = (int)((1 - m_cannibalrate) * texture);
//int total = resend + land + wind + cloud + task + texture + asset;
//m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, Total={8}",
// AgentID, resend, land, wind, cloud, task, texture, asset, total);
if (ThrottleDebugLevel > 0)
{
long total = resend + land + wind + cloud + task + texture + asset;
m_log.DebugFormat(
"[LLUDPCLIENT]: {0} is setting throttles in {1} to Resend={2}, Land={3}, Wind={4}, Cloud={5}, Task={6}, Texture={7}, Asset={8}, TOTAL = {9}",
AgentID, m_udpServer.Scene.Name, resend, land, wind, cloud, task, texture, asset, total);
}
// Update the token buckets with new throttle values
TokenBucket bucket;
@@ -649,8 +731,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (HasUpdates(m_categories))
{
// Asynchronously run the callback
Util.FireAndForget(FireQueueEmpty, categories);
if (!m_udpServer.OqrEngine.IsRunning)
{
// Asynchronously run the callback
Util.FireAndForget(FireQueueEmpty, categories);
}
else
{
m_udpServer.OqrEngine.QueueRequest(this, categories);
}
}
else
{
@@ -669,8 +758,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name="o">Throttle categories to fire the callback for,
/// stored as an object to match the WaitCallback delegate
/// 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;
// const int MIN_CALLBACK_MS = 30;

View File

@@ -34,7 +34,6 @@ using System.Net.Sockets;
using System.Reflection;
using System.Threading;
using log4net;
using NDesk.Options;
using Nini.Config;
using OpenMetaverse.Packets;
using OpenSim.Framework;
@@ -222,6 +221,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary>
public int DefaultClientPacketDebugLevel { get; set; }
/// <summary>
/// If set then all inbound agent updates are discarded. For debugging purposes.
/// discard agent update.
/// </summary>
public bool DiscardInboundAgentUpdates { get; set; }
/// <summary>The measured resolution of Environment.TickCount</summary>
public readonly float TickCountResolution;
@@ -238,19 +243,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Incoming packets that are awaiting handling</summary>
private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
/// <summary></summary>
//private UDPClientCollection m_clients = new UDPClientCollection();
/// <summary>Bandwidth throttle for this UDP server</summary>
protected TokenBucket m_throttle;
public TokenBucket Throttle { get; private set; }
/// <summary>
/// Gets the maximum total drip rate allowed to all clients.
/// </summary>
public long MaxTotalDripRate { get { return Throttle.RequestedDripRate; } }
/// <summary>Bandwidth throttle rates for this UDP server</summary>
/// <summary>Per client throttle rates enforced by this server</summary>
/// <remarks>
/// If the total rate is non-zero, then this is the maximum total throttle setting that any client can ever have.
/// The other rates (resend, asset, etc.) are the defaults for a new client and can be changed (and usually
/// do get changed immediately). They do not need to sum to the total.
/// </remarks>
public ThrottleRates ThrottleRates { get; private set; }
/// <summary>Manages authentication for agent circuits</summary>
private AgentCircuitManager m_circuitManager;
/// <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>
private Location m_location;
@@ -355,6 +368,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary>
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(
IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port,
IConfigSource configSource, AgentCircuitManager circuitManager)
@@ -427,22 +447,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
#endregion BinaryStats
m_throttle = new TokenBucket(null, sceneThrottleBps);
// FIXME: Can't add info here because don't know scene yet.
// m_throttle
// = new TokenBucket(
// string.Format("server throttle bucket for {0}", Scene.Name), null, sceneThrottleBps);
Throttle = new TokenBucket("server throttle bucket", null, sceneThrottleBps);
ThrottleRates = new ThrottleRates(configSource);
if (usePools)
EnablePools();
OqrEngine = new OutgoingQueueRefillEngine(this);
}
public void Start()
{
StartInbound();
StartOutbound();
OqrEngine.Start();
m_elapsedMSSinceLastStatReport = Environment.TickCount;
}
private void StartInbound()
public void StartInbound()
{
m_log.InfoFormat(
"[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}",
@@ -453,7 +482,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// This thread will process the packets received that are placed on the packetInbox
Watchdog.StartThread(
IncomingPacketHandler,
string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName),
string.Format("Incoming Packets ({0})", Scene.Name),
ThreadPriority.Normal,
false,
true,
@@ -461,7 +490,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
}
private new void StartOutbound()
public override void StartOutbound()
{
m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server");
@@ -469,7 +498,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Watchdog.StartThread(
OutgoingPacketHandler,
string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName),
string.Format("Outgoing Packets ({0})", Scene.Name),
ThreadPriority.Normal,
false,
true,
@@ -479,12 +508,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
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.StopInbound();
OqrEngine.Stop();
}
protected override bool EnablePools()
public override bool EnablePools()
{
if (!UsePools)
{
@@ -498,7 +528,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return false;
}
protected override bool DisablePools()
public override bool DisablePools()
{
if (UsePools)
{
@@ -518,7 +548,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene
/// stats.
/// </summary>
private void EnablePoolStats()
protected internal void EnablePoolStats()
{
m_poolCountStat
= new Stat(
@@ -527,7 +557,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"The number of objects currently stored within the UDPPacketBuffer pool",
"",
"clientstack",
m_scene.Name,
Scene.Name,
StatType.Pull,
stat => stat.Value = Pool.Count,
StatVerbosity.Debug);
@@ -541,7 +571,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"The number of objects currently stored within the incoming packet pool",
"",
"clientstack",
m_scene.Name,
Scene.Name,
StatType.Pull,
stat => stat.Value = m_incomingPacketPool.Count,
StatVerbosity.Debug);
@@ -552,7 +582,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>
/// Disables pool stats.
/// </summary>
private void DisablePoolStats()
protected internal void DisablePoolStats()
{
StatsManager.DeregisterStat(m_poolCountStat);
m_poolCountStat = null;
@@ -585,7 +615,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
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");
return;
@@ -597,8 +627,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return;
}
m_scene = (Scene)scene;
m_location = new Location(m_scene.RegionInfo.RegionHandle);
Scene = (Scene)scene;
m_location = new Location(Scene.RegionInfo.RegionHandle);
StatsManager.RegisterStat(
new Stat(
@@ -621,7 +651,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"Packets reused",
"Number of packets reused out of all requests to the packet pool",
"clientstack",
m_scene.Name,
Scene.Name,
StatType.Pull,
stat =>
{ PercentageStat pstat = (PercentageStat)stat;
@@ -635,7 +665,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"Packet data blocks reused",
"Number of data blocks reused out of all requests to the packet pool",
"clientstack",
m_scene.Name,
Scene.Name,
StatType.Pull,
stat =>
{ PercentageStat pstat = (PercentageStat)stat;
@@ -650,7 +680,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"The number of objects currently stored within the packet pool",
"",
"clientstack",
m_scene.Name,
Scene.Name,
StatType.Pull,
stat => stat.Value = PacketPool.Instance.PacketsPooled,
StatVerbosity.Debug));
@@ -662,240 +692,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"The number of objects currently stored within the packet data block pool",
"",
"clientstack",
m_scene.Name,
Scene.Name,
StatType.Pull,
stat => stat.Value = PacketPool.Instance.BlocksPooled,
StatVerbosity.Debug));
StatsManager.RegisterStat(
new Stat(
"OutgoingPacketsQueuedCount",
"Packets queued for outgoing send",
"Number of queued outgoing packets across all connections",
"",
"clientstack",
Scene.Name,
StatType.Pull,
MeasuresOfInterest.AverageChangeOverTime,
stat => stat.Value = GetTotalQueuedOutgoingPackets(),
StatVerbosity.Info));
// We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by
// scene name
if (UsePools)
EnablePoolStats();
MainConsole.Instance.Commands.AddCommand(
"Debug", false, "debug lludp packet",
"debug lludp packet [--default] <level> [<avatar-first-name> <avatar-last-name>]",
"Turn on packet debugging",
"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 <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
+ "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation 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 --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 an avatar name is given then only packets from that avatar are logged.",
HandlePacketCommand);
MainConsole.Instance.Commands.AddCommand(
"Debug",
false,
"debug lludp start",
"debug lludp start <in|out|all>",
"Control LLUDP packet processing.",
"No effect if packet processing has already started.\n"
+ "in - start inbound processing.\n"
+ "out - start outbound processing.\n"
+ "all - start in and outbound processing.\n",
HandleStartCommand);
MainConsole.Instance.Commands.AddCommand(
"Debug",
false,
"debug lludp stop",
"debug lludp stop <in|out|all>",
"Stop LLUDP packet processing.",
"No effect if packet processing has already stopped.\n"
+ "in - stop inbound processing.\n"
+ "out - stop outbound processing.\n"
+ "all - stop in and outbound processing.\n",
HandleStopCommand);
MainConsole.Instance.Commands.AddCommand(
"Debug",
false,
"debug lludp pool",
"debug lludp pool <on|off>",
"Turn object pooling within the lludp component on or off.",
HandlePoolCommand);
MainConsole.Instance.Commands.AddCommand(
"Debug",
false,
"debug lludp status",
"debug lludp status",
"Return status of LLUDP packet processing.",
HandleStatusCommand);
MainConsole.Instance.Commands.AddCommand(
"Debug",
false,
"debug lludp toggle agentupdate",
"debug lludp toggle agentupdate",
"Toggle whether agentupdate packets are processed or simply discarded.",
HandleAgentUpdateCommand);
}
private void HandlePacketCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
return;
bool setAsDefaultLevel = false;
OptionSet optionSet = new OptionSet().Add("default", o => setAsDefaultLevel = o != null);
List<string> filteredArgs = optionSet.Parse(args);
string name = null;
if (filteredArgs.Count == 6)
{
if (!setAsDefaultLevel)
{
name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]);
}
else
{
MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default logging level");
return;
}
}
if (filteredArgs.Count > 3)
{
int newDebug;
if (int.TryParse(filteredArgs[3], out newDebug))
{
if (setAsDefaultLevel)
{
DefaultClientPacketDebugLevel = newDebug;
MainConsole.Instance.OutputFormat(
"Debug packet debug for new clients set to {0} in {1}", DefaultClientPacketDebugLevel, m_scene.Name);
}
else
{
m_scene.ForEachScenePresence(sp =>
{
if (name == null || sp.Name == name)
{
MainConsole.Instance.OutputFormat(
"Packet debug for {0} ({1}) set to {2} in {3}",
sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_scene.Name);
sp.ControllingClient.DebugPacketLevel = newDebug;
}
});
}
}
else
{
MainConsole.Instance.Output("Usage: debug lludp packet [--default] 0..255 [<first-name> <last-name>]");
}
}
}
private void HandleStartCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
return;
if (args.Length != 4)
{
MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>");
return;
}
string subCommand = args[3];
if (subCommand == "in" || subCommand == "all")
StartInbound();
if (subCommand == "out" || subCommand == "all")
StartOutbound();
}
private void HandleStopCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
return;
if (args.Length != 4)
{
MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>");
return;
}
string subCommand = args[3];
if (subCommand == "in" || subCommand == "all")
StopInbound();
if (subCommand == "out" || subCommand == "all")
StopOutbound();
}
private void HandlePoolCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
return;
if (args.Length != 4)
{
MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
return;
}
string enabled = args[3];
if (enabled == "on")
{
if (EnablePools())
{
EnablePoolStats();
MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name);
}
}
else if (enabled == "off")
{
if (DisablePools())
{
DisablePoolStats();
MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name);
}
}
else
{
MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
}
}
bool m_discardAgentUpdates;
private void HandleAgentUpdateCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
return;
m_discardAgentUpdates = !m_discardAgentUpdates;
MainConsole.Instance.OutputFormat(
"Discard AgentUpdates now {0} for {1}", m_discardAgentUpdates, m_scene.Name);
}
private void HandleStatusCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
return;
MainConsole.Instance.OutputFormat(
"IN LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningInbound ? "enabled" : "disabled");
MainConsole.Instance.OutputFormat(
"OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled");
MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_scene.Name, UsePools ? "on" : "off");
MainConsole.Instance.OutputFormat(
"Packet debug level for new clients is {0}", DefaultClientPacketDebugLevel);
LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this);
commands.Register();
}
public bool HandlesRegion(Location x)
@@ -903,6 +724,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return x == m_location;
}
public int GetTotalQueuedOutgoingPackets()
{
int total = 0;
foreach (ScenePresence sp in Scene.GetScenePresences())
{
LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
total += udpClient.GetTotalPacketsQueuedCount();
}
return total;
}
// public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting)
// {
// // CoarseLocationUpdate and AvatarGroupsReply packets cannot be split in an automated way
@@ -973,7 +807,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
for (int i = 0; i < packetCount; i++)
{
byte[] data = datas[i];
if (!SendPacketData(udpClient, data, packet.Type, category, method))
packetQueued = true;
}
@@ -981,7 +814,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
else
{
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);
@@ -1059,14 +893,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Queue or Send
OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
// If we were not provided a method for handling unacked, use the UDPServer default method
outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
if ((outgoingPacket.Buffer.Data[0] & Helpers.MSG_RELIABLE) != 0)
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
// 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.
bool requestQueue = type == PacketType.KillObject;
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue))
bool forceQueue = (type == PacketType.KillObject);
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forceQueue))
{
SendPacketFinal(outgoingPacket);
return true;
@@ -1270,6 +1107,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// is 100% correct
PacketsSentCount++;
if (udpClient.DebugDataOutLevel > 0)
m_log.DebugFormat(
"[LLUDPSERVER]: Sending packet #{0} (rel: {1}, res: {2}) to {3} from {4}",
outgoingPacket.SequenceNumber, isReliable, isResend, udpClient.AgentID, Scene.Name);
// Put the UDP payload on the wire
AsyncBeginSend(buffer);
@@ -1399,7 +1241,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Determine which agent this packet came from
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);
@@ -1514,7 +1356,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (packet.Type == PacketType.AgentUpdate)
{
if (m_discardAgentUpdates)
if (DiscardInboundAgentUpdates)
return;
((LLClientView)client).TotalAgentUpdates++;
@@ -1694,7 +1536,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.DebugFormat(
"[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;
if (IsClientAuthorized(uccp, out sessionInfo))
@@ -1716,11 +1558,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.
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);
// Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from
if (!tp)
client.SceneAgent.SendInitialDataToMe();
if (!tp && !client.SceneAgent.SentInitialDataToClient)
client.SceneAgent.SendInitialDataToClient();
}
}
else
@@ -1728,7 +1570,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Don't create clients for unauthorized requesters.
m_log.WarnFormat(
"[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(
@@ -1760,7 +1602,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1];
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
// We need to wait here because in when using the OpenSimulator V2 teleport protocol to travel to a destination
@@ -1771,7 +1613,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int count = 40;
while (count-- > 0)
{
if (m_scene.TryGetClient(endPoint, out client))
if (Scene.TryGetClient(endPoint, out client))
{
if (!client.IsActive)
{
@@ -1780,7 +1622,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// not yet been established).
m_log.DebugFormat(
"[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)
{
@@ -1792,7 +1634,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// the client manager
m_log.DebugFormat(
"[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
{
@@ -1803,7 +1645,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
m_log.DebugFormat(
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} in {1} but no client exists yet. Waiting.",
endPoint, m_scene.Name);
endPoint, Scene.Name);
}
Thread.Sleep(200);
@@ -1813,7 +1655,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
m_log.DebugFormat(
"[LLUDPSERVER]: No client found for CompleteAgentMovement from {0} in {1} after wait. Dropping.",
endPoint, m_scene.Name);
endPoint, Scene.Name);
return;
}
@@ -1825,7 +1667,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// purposes.
m_log.DebugFormat(
"[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;
}
@@ -1920,11 +1762,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// consistently, this lock could probably be removed.
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, 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.DebugPacketLevel = DefaultClientPacketDebugLevel;
@@ -1954,17 +1796,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.WarnFormat(
"[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)
client.Kick("Simulator logged you out due to connection timeout.");
}
m_scene.CloseAgent(client.AgentId, true);
Scene.CloseAgent(client.AgentId, true);
}
private void IncomingPacketHandler()
{
Thread.CurrentThread.Priority = ThreadPriority.Highest;
// Set this culture for the thread that incoming packets are received
// on to en-US to avoid number parsing issues
Culture.SetCurrentCulture();
@@ -2010,6 +1854,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private void OutgoingPacketHandler()
{
Thread.CurrentThread.Priority = ThreadPriority.Highest;
// Set this culture for the thread that outgoing packets are sent
// on to en-US to avoid number parsing issues
Culture.SetCurrentCulture();
@@ -2072,7 +1918,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Handle outgoing packets, resends, acknowledgements, and pings for each
// client. m_packetSent will be set to true if a packet is sent
m_scene.ForEachClient(clientPacketHandler);
Scene.ForEachClient(clientPacketHandler);
m_currentOutgoingClient = null;
@@ -2239,7 +2085,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
watch1.Reset();
// 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})",
avgProcessingTicks, avgResendUnackedTicks, avgSendAcksTicks, avgSendPingTicks, avgDequeueTicks, TickCountResolution, npacksSent, npackNotSent);
@@ -2288,7 +2134,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
m_log.DebugFormat(
"[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++;
@@ -2301,8 +2147,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (!client.IsLoggingOut)
{
client.IsLoggingOut = true;
m_scene.CloseAgent(client.AgentId, false);
Scene.CloseAgent(client.AgentId, false);
}
}
}
}
}

View File

@@ -0,0 +1,694 @@
/*
* 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.Text;
using NDesk.Options;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.ClientStack.LindenUDP
{
public class LLUDPServerCommands
{
private ICommandConsole m_console;
private LLUDPServer m_udpServer;
public LLUDPServerCommands(ICommandConsole console, LLUDPServer udpServer)
{
m_console = console;
m_udpServer = udpServer;
}
public void Register()
{
m_console.Commands.AddCommand(
"Comms", false, "show server throttles",
"show server throttles",
"Show information about server throttles",
HandleShowServerThrottlesCommand);
m_console.Commands.AddCommand(
"Debug", false, "debug lludp packet",
"debug lludp packet [--default | --all] <level> [<avatar-first-name> <avatar-last-name>]",
"Turn on packet debugging. This logs information when the client stack hands a processed packet off to downstream code or when upstream code first requests that a certain packet be sent.",
"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 <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
+ "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation 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 --default is specified then the level becomes the default logging level for all subsequent agents.\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.",
HandlePacketCommand);
m_console.Commands.AddCommand(
"Debug", false, "debug lludp data out",
"debug lludp data out <level> <avatar-first-name> <avatar-last-name>\"",
"Turn on debugging for final outgoing data to the given user's client.",
"This operates at a much lower level than the packet command and prints out available details when the data is actually sent.\n"
+ "If level > 0 then information about all outgoing UDP data for this avatar is logged.\n"
+ "If level <= 0 then no information about outgoing UDP data for this avatar is logged.",
HandleDataCommand);
m_console.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);
m_console.Commands.AddCommand(
"Debug",
false,
"debug lludp start",
"debug lludp start <in|out|all>",
"Control LLUDP packet processing.",
"No effect if packet processing has already started.\n"
+ "in - start inbound processing.\n"
+ "out - start outbound processing.\n"
+ "all - start in and outbound processing.\n",
HandleStartCommand);
m_console.Commands.AddCommand(
"Debug",
false,
"debug lludp stop",
"debug lludp stop <in|out|all>",
"Stop LLUDP packet processing.",
"No effect if packet processing has already stopped.\n"
+ "in - stop inbound processing.\n"
+ "out - stop outbound processing.\n"
+ "all - stop in and outbound processing.\n",
HandleStopCommand);
m_console.Commands.AddCommand(
"Debug",
false,
"debug lludp pool",
"debug lludp pool <on|off>",
"Turn object pooling within the lludp component on or off.",
HandlePoolCommand);
m_console.Commands.AddCommand(
"Debug",
false,
"debug lludp status",
"debug lludp status",
"Return status of LLUDP packet processing.",
HandleStatusCommand);
m_console.Commands.AddCommand(
"Debug",
false,
"debug lludp throttles log",
"debug lludp throttles log <level> [<avatar-first-name> <avatar-last-name>]",
"Change debug logging level for throttles.",
"If level >= 0 then throttle debug logging is performed.\n"
+ "If level <= 0 then no throttle debug logging is performed.",
HandleThrottleCommand);
m_console.Commands.AddCommand(
"Debug",
false,
"debug lludp throttles get",
"debug lludp throttles get [<avatar-first-name> <avatar-last-name>]",
"Return debug settings for throttles.",
HandleThrottleGetCommand);
m_console.Commands.AddCommand(
"Debug",
false,
"debug lludp throttles set",
"debug lludp throttles set <param> <value> [<avatar-first-name> <avatar-last-name>]",
"Set a throttle parameter for the given client.",
"Avaiable parameters are:\n"
+ "adaptive - true/false, control adaptive throttle setting\n"
+ "throttle-max - kbps, control maximum throttle setting for current and future clients\n",
HandleThrottleSetCommand);
m_console.Commands.AddCommand(
"Debug",
false,
"debug lludp set",
"debug lludp set <param> <value>",
"Set a parameter for the server.",
"Only current setting is 'scene-throttle-max' which sets the current max cumulative kbps provided for this scene to clients",
HandleSetCommand);
m_console.Commands.AddCommand(
"Debug",
false,
"debug lludp toggle agentupdate",
"debug lludp toggle agentupdate",
"Toggle whether agentupdate packets are processed or simply discarded.",
HandleAgentUpdateCommand);
}
private void HandleShowServerThrottlesCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
return;
m_console.OutputFormat("Throttles for {0}", m_udpServer.Scene.Name);
ConsoleDisplayList cdl = new ConsoleDisplayList();
cdl.AddRow("Adaptive throttles", m_udpServer.ThrottleRates.AdaptiveThrottlesEnabled);
long maxSceneDripRate = m_udpServer.MaxTotalDripRate;
cdl.AddRow(
"Max scene throttle",
maxSceneDripRate != 0 ? string.Format("{0} kbps", maxSceneDripRate * 8 / 1000) : "unset");
int maxClientDripRate = m_udpServer.ThrottleRates.Total;
cdl.AddRow(
"Max new client throttle",
maxClientDripRate != 0 ? string.Format("{0} kbps", maxClientDripRate * 8 / 1000) : "unset");
m_console.Output(cdl.ToString());
m_console.OutputFormat("{0}\n", GetServerThrottlesReport(m_udpServer));
}
private string GetServerThrottlesReport(LLUDPServer udpServer)
{
StringBuilder report = new StringBuilder();
report.AppendFormat(
"{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}\n",
"Total",
"Resend",
"Land",
"Wind",
"Cloud",
"Task",
"Texture",
"Asset");
report.AppendFormat(
"{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}\n",
"kb/s",
"kb/s",
"kb/s",
"kb/s",
"kb/s",
"kb/s",
"kb/s",
"kb/s");
ThrottleRates throttleRates = udpServer.ThrottleRates;
report.AppendFormat(
"{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}",
(throttleRates.Total * 8) / 1000,
(throttleRates.Resend * 8) / 1000,
(throttleRates.Land * 8) / 1000,
(throttleRates.Wind * 8) / 1000,
(throttleRates.Cloud * 8) / 1000,
(throttleRates.Task * 8) / 1000,
(throttleRates.Texture * 8) / 1000,
(throttleRates.Asset * 8) / 1000);
return report.ToString();
}
protected string GetColumnEntry(string entry, int maxLength, int columnPadding)
{
return string.Format(
"{0,-" + maxLength + "}{1,-" + columnPadding + "}",
entry.Length > maxLength ? entry.Substring(0, maxLength) : entry,
"");
}
private void HandleDataCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
return;
if (args.Length != 7)
{
MainConsole.Instance.OutputFormat("Usage: debug lludp data out <true|false> <avatar-first-name> <avatar-last-name>");
return;
}
int level;
if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level))
return;
string firstName = args[5];
string lastName = args[6];
m_udpServer.Scene.ForEachScenePresence(sp =>
{
if (sp.Firstname == firstName && sp.Lastname == lastName)
{
MainConsole.Instance.OutputFormat(
"Data debug for {0} ({1}) set to {2} in {3}",
sp.Name, sp.IsChildAgent ? "child" : "root", level, m_udpServer.Scene.Name);
((LLClientView)sp.ControllingClient).UDPClient.DebugDataOutLevel = level;
}
});
}
private void HandleThrottleCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
return;
bool all = args.Length == 5;
bool one = args.Length == 7;
if (!all && !one)
{
MainConsole.Instance.OutputFormat(
"Usage: debug lludp throttles log <level> [<avatar-first-name> <avatar-last-name>]");
return;
}
int level;
if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level))
return;
string firstName = null;
string lastName = null;
if (one)
{
firstName = args[5];
lastName = args[6];
}
m_udpServer.Scene.ForEachScenePresence(sp =>
{
if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
{
MainConsole.Instance.OutputFormat(
"Throttle log level for {0} ({1}) set to {2} in {3}",
sp.Name, sp.IsChildAgent ? "child" : "root", level, m_udpServer.Scene.Name);
((LLClientView)sp.ControllingClient).UDPClient.ThrottleDebugLevel = level;
}
});
}
private void HandleThrottleSetCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
return;
bool all = args.Length == 6;
bool one = args.Length == 8;
if (!all && !one)
{
MainConsole.Instance.OutputFormat(
"Usage: debug lludp throttles set <param> <value> [<avatar-first-name> <avatar-last-name>]");
return;
}
string param = args[4];
string rawValue = args[5];
string firstName = null;
string lastName = null;
if (one)
{
firstName = args[6];
lastName = args[7];
}
if (param == "adaptive")
{
bool newValue;
if (!ConsoleUtil.TryParseConsoleBool(MainConsole.Instance, rawValue, out newValue))
return;
m_udpServer.Scene.ForEachScenePresence(sp =>
{
if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
{
MainConsole.Instance.OutputFormat(
"Setting param {0} to {1} for {2} ({3}) in {4}",
param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
udpClient.FlowThrottle.Enabled = newValue;
// udpClient.FlowThrottle.MaxDripRate = 0;
// udpClient.FlowThrottle.AdjustedDripRate = 0;
}
});
}
else if (param == "throttle-max")
{
int newValue;
if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue))
return;
int newThrottleMaxKbps = newValue * 1000 / 8;
m_udpServer.ThrottleRates.Total = newThrottleMaxKbps;
m_udpServer.Scene.ForEachScenePresence(sp =>
{
if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
{
MainConsole.Instance.OutputFormat(
"Setting param {0} to {1} for {2} ({3}) in {4}",
param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
udpClient.FlowThrottle.RequestedDripRate = newThrottleMaxKbps;
udpClient.FlowThrottle.MaxDripRate = newThrottleMaxKbps;
}
});
}
}
private void HandleThrottleGetCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
return;
bool all = args.Length == 4;
bool one = args.Length == 6;
if (!all && !one)
{
MainConsole.Instance.OutputFormat(
"Usage: debug lludp throttles get [<avatar-first-name> <avatar-last-name>]");
return;
}
string firstName = null;
string lastName = null;
if (one)
{
firstName = args[4];
lastName = args[5];
}
m_udpServer.Scene.ForEachScenePresence(sp =>
{
if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
{
m_console.OutputFormat(
"Status for {0} ({1}) in {2}",
sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
ConsoleDisplayList cdl = new ConsoleDisplayList();
cdl.AddRow("Adaptive throttle", udpClient.FlowThrottle.Enabled);
cdl.AddRow("Max throttle", string.Format("{0} kbps", udpClient.FlowThrottle.RequestedDripRate * 8 / 1000));
m_console.Output(cdl.ToString());
}
});
}
private void HandleSetCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
return;
if (args.Length != 5)
{
MainConsole.Instance.OutputFormat("Usage: debug lludp set <param> <value>");
return;
}
string param = args[3];
string rawValue = args[4];
int newValue;
if (param == "scene-throttle-max")
{
if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue))
return;
m_udpServer.Throttle.RequestedDripRate = newValue * 1000 / 8;
}
m_console.OutputFormat("{0} set to {1} in {2}", param, rawValue, m_udpServer.Scene.Name);
}
private void HandlePacketCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
return;
bool setAsDefaultLevel = false;
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);
string name = null;
if (filteredArgs.Count == 6)
{
if (!(setAsDefaultLevel || setAll))
{
name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]);
}
else
{
MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default/all logging level");
return;
}
}
if (filteredArgs.Count > 3)
{
int newDebug;
if (int.TryParse(filteredArgs[3], out newDebug))
{
if (setAsDefaultLevel || setAll)
{
m_udpServer.DefaultClientPacketDebugLevel = newDebug;
MainConsole.Instance.OutputFormat(
"Packet debug for {0} clients set to {1} in {2}",
(setAll ? "all" : "future"), m_udpServer.DefaultClientPacketDebugLevel, m_udpServer.Scene.Name);
if (setAll)
{
m_udpServer.Scene.ForEachScenePresence(sp =>
{
MainConsole.Instance.OutputFormat(
"Packet debug for {0} ({1}) set to {2} in {3}",
sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_udpServer.Scene.Name);
sp.ControllingClient.DebugPacketLevel = newDebug;
});
}
}
else
{
m_udpServer.Scene.ForEachScenePresence(sp =>
{
if (name == null || sp.Name == name)
{
MainConsole.Instance.OutputFormat(
"Packet debug for {0} ({1}) set to {2} in {3}",
sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_udpServer.Scene.Name);
sp.ControllingClient.DebugPacketLevel = newDebug;
}
});
}
}
else
{
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 != m_udpServer.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, m_udpServer.Scene.Name);
m_udpServer.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, m_udpServer.Scene.Name);
m_udpServer.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)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
return;
if (args.Length != 4)
{
MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>");
return;
}
string subCommand = args[3];
if (subCommand == "in" || subCommand == "all")
m_udpServer.StartInbound();
if (subCommand == "out" || subCommand == "all")
m_udpServer.StartOutbound();
}
private void HandleStopCommand(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 stop <in|out|all>");
return;
}
string subCommand = args[3];
if (subCommand == "in" || subCommand == "all")
m_udpServer.StopInbound();
if (subCommand == "out" || subCommand == "all")
m_udpServer.StopOutbound();
}
private void HandlePoolCommand(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 pool <on|off>");
return;
}
string enabled = args[3];
if (enabled == "on")
{
if (m_udpServer.EnablePools())
{
m_udpServer.EnablePoolStats();
MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_udpServer.Scene.Name);
}
}
else if (enabled == "off")
{
if (m_udpServer.DisablePools())
{
m_udpServer.DisablePoolStats();
MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_udpServer.Scene.Name);
}
}
else
{
MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
}
}
private void HandleAgentUpdateCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
return;
m_udpServer.DiscardInboundAgentUpdates = !m_udpServer.DiscardInboundAgentUpdates;
MainConsole.Instance.OutputFormat(
"Discard AgentUpdates now {0} for {1}", m_udpServer.DiscardInboundAgentUpdates, m_udpServer.Scene.Name);
}
private void HandleStatusCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
return;
MainConsole.Instance.OutputFormat(
"IN LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningInbound ? "enabled" : "disabled");
MainConsole.Instance.OutputFormat(
"OUT LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningOutbound ? "enabled" : "disabled");
MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_udpServer.Scene.Name, m_udpServer.UsePools ? "on" : "off");
MainConsole.Instance.OutputFormat(
"Packet debug level for new clients is {0}", m_udpServer.DefaultClientPacketDebugLevel);
}
}
}

View File

@@ -135,7 +135,7 @@ namespace OpenMetaverse
/// manner (not throwing an exception when the remote side resets the
/// connection). This call is ignored on Mono where the flag is not
/// necessary</remarks>
public void StartInbound(int recvBufferSize, bool asyncPacketHandling)
public virtual void StartInbound(int recvBufferSize, bool asyncPacketHandling)
{
m_asyncPacketHandling = asyncPacketHandling;
@@ -185,14 +185,14 @@ namespace OpenMetaverse
/// <summary>
/// Start outbound UDP packet handling.
/// </summary>
public void StartOutbound()
public virtual void StartOutbound()
{
m_log.DebugFormat("[UDPBASE]: Starting outbound UDP loop");
IsRunningOutbound = true;
}
public void StopInbound()
public virtual void StopInbound()
{
if (IsRunningInbound)
{
@@ -203,14 +203,14 @@ namespace OpenMetaverse
}
}
public void StopOutbound()
public virtual void StopOutbound()
{
m_log.DebugFormat("[UDPBASE]: Stopping outbound UDP loop");
IsRunningOutbound = false;
}
protected virtual bool EnablePools()
public virtual bool EnablePools()
{
if (!UsePools)
{
@@ -224,7 +224,7 @@ namespace OpenMetaverse
return false;
}
protected virtual bool DisablePools()
public virtual bool DisablePools()
{
if (UsePools)
{

View File

@@ -0,0 +1,288 @@
/*
* 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()
{
Thread.CurrentThread.Priority = ThreadPriority.Highest;
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

@@ -36,7 +36,6 @@ using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
{
@@ -47,7 +46,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
public class BasicCircuitTests : OpenSimTestCase
{
private Scene m_scene;
private TestLLUDPServer m_udpServer;
[TestFixtureSetUp]
public void FixtureInit()
@@ -73,72 +71,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
StatsManager.SimExtraStats = new SimExtraStatsCollector();
}
/// <summary>
/// Build an object name packet for test purposes
/// </summary>
/// <param name="objectLocalId"></param>
/// <param name="objectName"></param>
private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName)
{
ObjectNamePacket onp = new ObjectNamePacket();
ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock();
odb.LocalID = objectLocalId;
odb.Name = Utils.StringToBytes(objectName);
onp.ObjectData = new ObjectNamePacket.ObjectDataBlock[] { odb };
onp.Header.Zerocoded = false;
return onp;
}
private void AddUdpServer()
{
AddUdpServer(new IniConfigSource());
}
private void AddUdpServer(IniConfigSource configSource)
{
uint port = 0;
AgentCircuitManager acm = m_scene.AuthenticateHandler;
m_udpServer = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, configSource, acm);
m_udpServer.AddScene(m_scene);
}
/// <summary>
/// Used by tests that aren't testing this stage.
/// </summary>
private ScenePresence AddClient()
{
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
uint myCircuitCode = 123456;
IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
= new UseCircuitCodePacket.CircuitCodeBlock();
uccpCcBlock.Code = myCircuitCode;
uccpCcBlock.ID = myAgentUuid;
uccpCcBlock.SessionID = mySessionUuid;
uccp.CircuitCode = uccpCcBlock;
byte[] uccpBytes = uccp.ToBytes();
UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length);
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
AgentCircuitData acd = new AgentCircuitData();
acd.AgentID = myAgentUuid;
acd.SessionID = mySessionUuid;
m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);
m_udpServer.PacketReceived(upb);
return m_scene.GetScenePresence(myAgentUuid);
}
// /// <summary>
// /// Build an object name packet for test purposes
// /// </summary>
// /// <param name="objectLocalId"></param>
// /// <param name="objectName"></param>
// private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName)
// {
// ObjectNamePacket onp = new ObjectNamePacket();
// ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock();
// odb.LocalID = objectLocalId;
// odb.Name = Utils.StringToBytes(objectName);
// onp.ObjectData = new ObjectNamePacket.ObjectDataBlock[] { odb };
// onp.Header.Zerocoded = false;
//
// return onp;
// }
//
/// <summary>
/// Test adding a client to the stack
/// </summary>
@@ -148,7 +97,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
AddUdpServer();
TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(m_scene);
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
@@ -169,7 +118,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
m_udpServer.PacketReceived(upb);
udpServer.PacketReceived(upb);
// Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet
Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null);
@@ -180,15 +129,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);
m_udpServer.PacketReceived(upb);
udpServer.PacketReceived(upb);
// Should succeed now
ScenePresence sp = m_scene.GetScenePresence(myAgentUuid);
Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));
Assert.That(m_udpServer.PacketsSent.Count, Is.EqualTo(1));
Assert.That(udpServer.PacketsSent.Count, Is.EqualTo(1));
Packet packet = m_udpServer.PacketsSent[0];
Packet packet = udpServer.PacketsSent[0];
Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));
PacketAckPacket ackPacket = packet as PacketAckPacket;
@@ -200,15 +149,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
public void TestLogoutClientDueToAck()
{
TestHelpers.InMethod();
TestHelpers.EnableLogging();
// TestHelpers.EnableLogging();
IniConfigSource ics = new IniConfigSource();
IConfig config = ics.AddConfig("ClientStack.LindenUDP");
config.Set("AckTimeout", -1);
AddUdpServer(ics);
TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(m_scene, ics);
ScenePresence sp = AddClient();
m_udpServer.ClientOutgoingPacketHandler(sp.ControllingClient, true, false, false);
ScenePresence sp
= ClientStackHelpers.AddChildClient(
m_scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456);
udpServer.ClientOutgoingPacketHandler(sp.ControllingClient, true, false, false);
ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID);
Assert.That(spAfterAckTimeout, Is.Null);
@@ -233,7 +185,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
// testLLUDPServer.RemoveClientCircuit(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);
// Assert.IsFalse(testLLUDPServer.HasCircuit(101));
// }

View File

@@ -39,7 +39,6 @@ using OpenSim.Framework;
using OpenSim.Region.CoreModules.Agent.TextureSender;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
{

View File

@@ -30,7 +30,6 @@ using NUnit.Framework;
using OpenMetaverse;
using OpenMetaverse.Packets;
using OpenSim.Framework;
using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common;
namespace OpenSim.Region.ClientStack.LindenUDP.Tests

View File

@@ -0,0 +1,257 @@
/*
* 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 NUnit.Framework;
using OpenMetaverse.Packets;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
{
[TestFixture]
public class ThrottleTests : OpenSimTestCase
{
[TestFixtureSetUp]
public void FixtureInit()
{
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
}
[TestFixtureTearDown]
public void TearDown()
{
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
// threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
// tests really shouldn't).
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
}
[Test]
public void TestClientThrottleSetNoLimit()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
Scene scene = new SceneHelpers().SetupScene();
TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene);
ScenePresence sp
= ClientStackHelpers.AddChildClient(
scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456);
LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
// udpClient.ThrottleDebugLevel = 1;
int resendBytes = 1000;
int landBytes = 2000;
int windBytes = 3000;
int cloudBytes = 4000;
int taskBytes = 5000;
int textureBytes = 6000;
int assetBytes = 7000;
SetThrottles(
udpClient, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
ClientInfo ci = udpClient.GetClientInfo();
// We expect this to be lower because of the minimum bound set by MTU
float totalBytes = LLUDPServer.MTU + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes;
Assert.AreEqual(LLUDPServer.MTU, ci.resendThrottle);
Assert.AreEqual(landBytes, ci.landThrottle);
Assert.AreEqual(windBytes, ci.windThrottle);
Assert.AreEqual(cloudBytes, ci.cloudThrottle);
Assert.AreEqual(taskBytes, ci.taskThrottle);
Assert.AreEqual(textureBytes, ci.textureThrottle);
Assert.AreEqual(assetBytes, ci.assetThrottle);
Assert.AreEqual(totalBytes, ci.totalThrottle);
}
/// <summary>
/// Test throttle setttings where max client throttle has been limited server side.
/// </summary>
[Test]
public void TestSingleClientThrottleRegionLimited()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
int resendBytes = 6000;
int landBytes = 8000;
int windBytes = 10000;
int cloudBytes = 12000;
int taskBytes = 14000;
int textureBytes = 16000;
int assetBytes = 18000;
int totalBytes
= (int)((resendBytes + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes) / 2);
Scene scene = new SceneHelpers().SetupScene();
TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene);
udpServer.Throttle.RequestedDripRate = totalBytes;
ScenePresence sp1
= ClientStackHelpers.AddChildClient(
scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456);
LLUDPClient udpClient1 = ((LLClientView)sp1.ControllingClient).UDPClient;
SetThrottles(
udpClient1, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
{
ClientInfo ci = udpClient1.GetClientInfo();
// Console.WriteLine(
// "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}",
// ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle);
Assert.AreEqual(resendBytes / 2, ci.resendThrottle);
Assert.AreEqual(landBytes / 2, ci.landThrottle);
Assert.AreEqual(windBytes / 2, ci.windThrottle);
Assert.AreEqual(cloudBytes / 2, ci.cloudThrottle);
Assert.AreEqual(taskBytes / 2, ci.taskThrottle);
Assert.AreEqual(textureBytes / 2, ci.textureThrottle);
Assert.AreEqual(assetBytes / 2, ci.assetThrottle);
Assert.AreEqual(totalBytes, ci.totalThrottle);
}
// Now add another client
ScenePresence sp2
= ClientStackHelpers.AddChildClient(
scene, udpServer, TestHelpers.ParseTail(0x10), TestHelpers.ParseTail(0x20), 123457);
LLUDPClient udpClient2 = ((LLClientView)sp2.ControllingClient).UDPClient;
// udpClient.ThrottleDebugLevel = 1;
SetThrottles(
udpClient2, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
{
ClientInfo ci = udpClient1.GetClientInfo();
// Console.WriteLine(
// "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}",
// ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle);
Assert.AreEqual(resendBytes / 4, ci.resendThrottle);
Assert.AreEqual(landBytes / 4, ci.landThrottle);
Assert.AreEqual(windBytes / 4, ci.windThrottle);
Assert.AreEqual(cloudBytes / 4, ci.cloudThrottle);
Assert.AreEqual(taskBytes / 4, ci.taskThrottle);
Assert.AreEqual(textureBytes / 4, ci.textureThrottle);
Assert.AreEqual(assetBytes / 4, ci.assetThrottle);
Assert.AreEqual(totalBytes / 2, ci.totalThrottle);
}
{
ClientInfo ci = udpClient2.GetClientInfo();
// Console.WriteLine(
// "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}",
// ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle);
Assert.AreEqual(resendBytes / 4, ci.resendThrottle);
Assert.AreEqual(landBytes / 4, ci.landThrottle);
Assert.AreEqual(windBytes / 4, ci.windThrottle);
Assert.AreEqual(cloudBytes / 4, ci.cloudThrottle);
Assert.AreEqual(taskBytes / 4, ci.taskThrottle);
Assert.AreEqual(textureBytes / 4, ci.textureThrottle);
Assert.AreEqual(assetBytes / 4, ci.assetThrottle);
Assert.AreEqual(totalBytes / 2, ci.totalThrottle);
}
}
/// <summary>
/// Test throttle setttings where max client throttle has been limited server side.
/// </summary>
[Test]
public void TestClientThrottlePerClientLimited()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
int resendBytes = 4000;
int landBytes = 6000;
int windBytes = 8000;
int cloudBytes = 10000;
int taskBytes = 12000;
int textureBytes = 14000;
int assetBytes = 16000;
int totalBytes
= (int)((resendBytes + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes) / 2);
Scene scene = new SceneHelpers().SetupScene();
TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene);
udpServer.ThrottleRates.Total = totalBytes;
ScenePresence sp
= ClientStackHelpers.AddChildClient(
scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456);
LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
// udpClient.ThrottleDebugLevel = 1;
SetThrottles(
udpClient, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
ClientInfo ci = udpClient.GetClientInfo();
// Console.WriteLine(
// "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}",
// ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle);
Assert.AreEqual(resendBytes / 2, ci.resendThrottle);
Assert.AreEqual(landBytes / 2, ci.landThrottle);
Assert.AreEqual(windBytes / 2, ci.windThrottle);
Assert.AreEqual(cloudBytes / 2, ci.cloudThrottle);
Assert.AreEqual(taskBytes / 2, ci.taskThrottle);
Assert.AreEqual(textureBytes / 2, ci.textureThrottle);
Assert.AreEqual(assetBytes / 2, ci.assetThrottle);
Assert.AreEqual(totalBytes, ci.totalThrottle);
}
private void SetThrottles(
LLUDPClient udpClient, int resendBytes, int landBytes, int windBytes, int cloudBytes, int taskBytes, int textureBytes, int assetBytes)
{
byte[] throttles = new byte[28];
Array.Copy(BitConverter.GetBytes((float)resendBytes * 8), 0, throttles, 0, 4);
Array.Copy(BitConverter.GetBytes((float)landBytes * 8), 0, throttles, 4, 4);
Array.Copy(BitConverter.GetBytes((float)windBytes * 8), 0, throttles, 8, 4);
Array.Copy(BitConverter.GetBytes((float)cloudBytes * 8), 0, throttles, 12, 4);
Array.Copy(BitConverter.GetBytes((float)taskBytes * 8), 0, throttles, 16, 4);
Array.Copy(BitConverter.GetBytes((float)textureBytes * 8), 0, throttles, 20, 4);
Array.Copy(BitConverter.GetBytes((float)assetBytes * 8), 0, throttles, 24, 4);
udpClient.SetThrottles(throttles);
}
}
}

View File

@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -42,9 +42,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public class TokenBucket
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static Int32 m_counter = 0;
// private Int32 m_identifier;
public string Identifier { get; private set; }
public int DebugLevel { get; set; }
/// <summary>
/// Number of ticks (ms) per quantum, drip rate and max burst
@@ -165,16 +166,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>
/// Default constructor
/// </summary>
/// <param name="identifier">Identifier for this token bucket</param>
/// <param name="parent">Parent bucket if this is a child bucket, or
/// null if this is a root bucket</param>
/// <param name="maxBurst">Maximum size of the bucket in bytes, or
/// zero if this bucket has no maximum capacity</param>
/// <param name="dripRate">Rate that the bucket fills, in bytes per
/// second. If zero, the bucket always remains full</param>
public TokenBucket(TokenBucket parent, Int64 dripRate)
public TokenBucket(string identifier, TokenBucket parent, Int64 dripRate)
{
// m_identifier = m_counter++;
m_counter++;
Identifier = identifier;
Parent = parent;
RequestedDripRate = dripRate;
@@ -301,7 +300,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// with no drip rate...
if (DripRate == 0)
{
m_log.WarnFormat("[TOKENBUCKET] something odd is happening and drip rate is 0");
m_log.WarnFormat("[TOKENBUCKET] something odd is happening and drip rate is 0 for {0}", Identifier);
return;
}
@@ -321,7 +320,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public class AdaptiveTokenBucket : TokenBucket
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// The minimum rate for flow control. Minimum drip rate is one
@@ -335,13 +334,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// greater than this.
// </summary>
protected Int64 m_maxDripRate = 0;
protected Int64 MaxDripRate
public Int64 MaxDripRate
{
get { return (m_maxDripRate == 0 ? m_totalDripRequest : m_maxDripRate); }
set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value,m_minimumFlow)); }
}
private bool m_enabled = false;
public bool Enabled { get; set; }
// <summary>
//
@@ -360,13 +359,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// <summary>
//
// </summary>
public AdaptiveTokenBucket(TokenBucket parent, Int64 maxDripRate, bool enabled) : base(parent,maxDripRate)
public AdaptiveTokenBucket(string identifier, TokenBucket parent, Int64 maxDripRate, bool enabled)
: base(identifier, 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;
AdjustedDripRate = m_minimumFlow;
}
@@ -377,9 +377,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// </summary>
public void ExpirePackets(Int32 count)
{
// m_log.WarnFormat("[ADAPTIVEBUCKET] drop {0} by {1} expired packets",AdjustedDripRate,count);
if (m_enabled)
if (Enabled)
{
if (DebugLevel > 0)
m_log.WarnFormat(
"[ADAPTIVEBUCKET] drop {0} by {1} expired packets for {2}",
AdjustedDripRate, count, Identifier);
AdjustedDripRate = (Int64) (AdjustedDripRate / Math.Pow(2,count));
}
}
// <summary>
@@ -387,7 +393,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// </summary>
public void AcknowledgePackets(Int32 count)
{
if (m_enabled)
if (Enabled)
AdjustedDripRate = AdjustedDripRate + count;
}
}

View File

@@ -231,7 +231,11 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
{
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)
{

View File

@@ -43,6 +43,7 @@ using Mono.Addins;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
@@ -963,7 +964,8 @@ namespace OpenSim.Region.CoreModules.Asset
case "assets":
con.Output("Ensuring assets are cached for all scenes.");
Util.RunThreadNoTimeout(delegate {
Watchdog.RunInThread(delegate
{
int assetReferenceTotal = TouchAllSceneAssets(true);
con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal);
}, "TouchAllSceneAssets", null);

View File

@@ -39,7 +39,6 @@ using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Asset.Tests
{

View File

@@ -145,7 +145,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
{
DebugLevel = debugLevel;
MainConsole.Instance.OutputFormat(
"Set event queue debug level to {0} in {1}", DebugLevel, m_scene.Name);
"Set attachments debug level to {0} in {1}", DebugLevel, m_scene.Name);
}
}
@@ -387,7 +387,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
if (!Enabled)
return false;
return AttachObjectInternal(sp, group, attachmentPt, silent, addToInventory, false, append);
group.DetachFromBackup();
bool success = AttachObjectInternal(sp, group, attachmentPt, silent, addToInventory, false, append);
if (!success)
group.AttachToBackup();
return success;
}
/// <summary>
@@ -815,8 +822,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
"[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
so.DetachFromBackup();
// Remove from database and parcel prim count
m_scene.DeleteFromStorage(so.UUID);
m_scene.EventManager.TriggerParcelPrimCountTainted();

View File

@@ -53,7 +53,6 @@ using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.XEngine;
using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
{
@@ -199,6 +198,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
string attName = "att";
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
Assert.That(so.Backup, Is.True);
m_numberOfAttachEventsFired = 0;
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false);
@@ -213,6 +213,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
Assert.That(attSo.IsAttachment);
Assert.That(attSo.UsesPhysics, Is.False);
Assert.That(attSo.IsTemporary, Is.False);
Assert.That(attSo.Backup, Is.False);
// Check item status
Assert.That(
@@ -385,7 +386,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
public void TestRezAttachmentFromInventory()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
// TestHelpers.EnableLogging();
Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
@@ -407,6 +408,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
Assert.That(attSo.IsAttachment);
Assert.That(attSo.UsesPhysics, Is.False);
Assert.That(attSo.IsTemporary, Is.False);
Assert.IsFalse(attSo.Backup);
// Check appearance status
Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
@@ -601,7 +603,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItem.ID)), Is.Null);
// Check object in scene
Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null);
SceneObjectGroup soInScene = scene.GetSceneObjectGroup("att");
Assert.That(soInScene, Is.Not.Null);
Assert.IsTrue(soInScene.Backup);
// Check events
Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
@@ -755,6 +759,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
Assert.That(attSo.IsAttachment);
Assert.That(attSo.UsesPhysics, Is.False);
Assert.That(attSo.IsTemporary, Is.False);
Assert.IsFalse(attSo.Backup);
// Check appearance status
List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments();
@@ -884,6 +889,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0];
Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name));
Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest));
Assert.IsFalse(actualSceneBAtt.Backup);
Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1));
@@ -994,6 +1000,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0];
Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name));
Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest));
Assert.IsFalse(actualSceneBAtt.Backup);
Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1));

View File

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

View File

@@ -34,7 +34,6 @@ using OpenSim.Framework;
using OpenSim.Region.CoreModules.Asset;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
{

View File

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

View File

@@ -41,7 +41,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests
{

View File

@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -289,18 +289,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
rootElement.AppendChild(result);
return 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();
return Util.DocToBytes(doc);
}
#endregion

View File

@@ -35,7 +35,6 @@ using OpenSim.Framework;
using OpenSim.Region.CoreModules.Avatar.Friends;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
{

View File

@@ -61,6 +61,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
private UserAccount m_userInfo;
private string m_invPath;
/// <value>
/// ID of this request
/// </value>
protected UUID m_id;
/// <summary>
/// Do we want to merge this load with existing inventory?
@@ -71,6 +76,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
protected IAssetService m_AssetService;
protected IUserAccountService m_UserAccountService;
private InventoryArchiverModule m_module;
/// <value>
/// The stream from which the inventory archive will be loaded.
/// </value>
@@ -114,11 +121,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// Record the creator id that should be associated with an asset. This is used to adjust asset creator ids
/// after OSP resolution (since OSP creators are only stored in the item
/// </summary>
protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>();
protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>();
public InventoryArchiveReadRequest(
IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge)
: this(UUID.Zero, null,
inv,
assets,
uacc,
userInfo,
invPath,
loadPath,
merge)
{
}
public InventoryArchiveReadRequest(
UUID id, InventoryArchiverModule module, IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge)
: this(
id,
module,
inv,
assets,
uacc,
@@ -130,8 +152,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
}
public InventoryArchiveReadRequest(
IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, Stream loadStream, bool merge)
UUID id, InventoryArchiverModule module, IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, Stream loadStream, bool merge)
{
m_id = id;
m_InventoryService = inv;
m_AssetService = assets;
m_UserAccountService = uacc;
@@ -139,6 +162,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_userInfo = userInfo;
m_invPath = invPath;
m_loadStream = loadStream;
m_module = module;
// FIXME: Do not perform this check since older versions of OpenSim do save the control file after other things
// (I thought they weren't). We will need to bump the version number and perform this check on all
@@ -161,6 +185,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{
try
{
Exception reportedException = null;
string filePath = "ERROR";
List<InventoryFolderBase> folderCandidates
@@ -197,14 +223,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
}
archive.Close();
m_log.DebugFormat(
"[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures",
m_successfulAssetRestores, m_failedAssetRestores);
m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", m_successfulItemRestores);
//Alicia: When this is called by LibraryModule or Tests, m_module will be null as event is not required
if(m_module != null)
m_module.TriggerInventoryArchiveLoaded(m_id, true, m_userInfo, m_invPath, m_loadStream, reportedException, m_successfulItemRestores);
return m_loadedNodes;
}
catch(Exception Ex)
{
// Trigger saved event with failed result and exception data
if (m_module != null)
m_module.TriggerInventoryArchiveLoaded(m_id, false, m_userInfo, m_invPath, m_loadStream, Ex, 0);
return m_loadedNodes;
}
finally
{
m_loadStream.Close();

View File

@@ -34,6 +34,7 @@ using System.Xml;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Serialization;
using OpenSim.Framework.Serialization.External;
using OpenSim.Region.CoreModules.World.Archiver;
@@ -42,6 +43,7 @@ using OpenSim.Services.Interfaces;
using Ionic.Zlib;
using GZipStream = Ionic.Zlib.GZipStream;
using CompressionMode = Ionic.Zlib.CompressionMode;
using PermissionMask = OpenSim.Framework.PermissionMask;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{
@@ -54,6 +56,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// </summary>
public bool SaveAssets { get; set; }
/// <summary>
/// Determines which items will be included in the archive, according to their permissions.
/// Default is null, meaning no permission checks.
/// </summary>
public string FilterContent { get; set; }
/// <summary>
/// Counter for inventory items saved to archive for passing to compltion event
/// </summary>
public int CountItems { get; set; }
/// <summary>
/// Counter for inventory items skipped due to permission filter option for passing to compltion event
/// </summary>
public int CountFiltered { get; set; }
/// <value>
/// Used to select all inventory nodes in a folder but not the folder itself
/// </value>
@@ -73,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// <value>
/// ID of this request
/// </value>
protected Guid m_id;
protected UUID m_id;
/// <value>
/// Used to collect the uuids of the assets that we need to save into the archive
@@ -94,7 +112,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// Constructor
/// </summary>
public InventoryArchiveWriteRequest(
Guid id, InventoryArchiverModule module, Scene scene,
UUID id, InventoryArchiverModule module, Scene scene,
UserAccount userInfo, string invPath, string savePath)
: this(
id,
@@ -110,7 +128,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// Constructor
/// </summary>
public InventoryArchiveWriteRequest(
Guid id, InventoryArchiverModule module, Scene scene,
UUID id, InventoryArchiverModule module, Scene scene,
UserAccount userInfo, string invPath, Stream saveStream)
{
m_id = id;
@@ -122,6 +140,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_assetGatherer = new UuidGatherer(m_scene.AssetService);
SaveAssets = true;
FilterContent = null;
}
protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids, bool timedOut)
@@ -150,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
}
m_module.TriggerInventoryArchiveSaved(
m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException);
m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException, CountItems, CountFiltered);
}
protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService)
@@ -166,10 +185,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
"[INVENTORY ARCHIVER]: Skipping inventory item {0} {1} at {2}",
inventoryItem.Name, inventoryItem.ID, path);
}
CountFiltered++;
return;
}
}
// Check For Permissions Filter Flags
if (!CanUserArchiveObject(m_userInfo.PrincipalID, inventoryItem))
{
m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Insufficient permissions, skipping inventory item {0} {1} at {2}",
inventoryItem.Name, inventoryItem.ID, path);
// Count Items Excluded
CountFiltered++;
return;
}
if (options.ContainsKey("verbose"))
m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Saving item {0} {1} (asset UUID {2})",
@@ -185,6 +220,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
AssetType itemAssetType = (AssetType)inventoryItem.AssetType;
// Count inventory items (different to asset count)
CountItems++;
// Don't chase down link asset items as they actually point to their target item IDs rather than an asset
if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder)
m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (sbyte)inventoryItem.AssetType, m_assetUuids);
@@ -242,6 +280,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
}
}
/// <summary>
/// Checks whether the user has permission to export an inventory item to an IAR.
/// </summary>
/// <param name="UserID">The user</param>
/// <param name="InvItem">The inventory item</param>
/// <returns>Whether the user is allowed to export the object to an IAR</returns>
private bool CanUserArchiveObject(UUID UserID, InventoryItemBase InvItem)
{
if (FilterContent == null)
return true;// Default To Allow Export
bool permitted = true;
bool canCopy = (InvItem.CurrentPermissions & (uint)PermissionMask.Copy) != 0;
bool canTransfer = (InvItem.CurrentPermissions & (uint)PermissionMask.Transfer) != 0;
bool canMod = (InvItem.CurrentPermissions & (uint)PermissionMask.Modify) != 0;
if (FilterContent.Contains("C") && !canCopy)
permitted = false;
if (FilterContent.Contains("T") && !canTransfer)
permitted = false;
if (FilterContent.Contains("M") && !canMod)
permitted = false;
return permitted;
}
/// <summary>
/// Execute the inventory write request
/// </summary>
@@ -250,6 +317,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (options.ContainsKey("noassets") && (bool)options["noassets"])
SaveAssets = false;
// Set Permission filter if flag is set
if (options.ContainsKey("checkPermissions"))
{
Object temp;
if (options.TryGetValue("checkPermissions", out temp))
FilterContent = temp.ToString().ToUpper();
}
try
{
InventoryFolderBase inventoryFolder = null;
@@ -309,7 +384,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
// We couldn't find the path indicated
string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath);
Exception e = new InventoryArchiverException(errorMessage);
m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e);
m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e, 0, 0);
throw e;
}
@@ -356,7 +431,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
options, ReceivedAllAssets);
Util.RunThreadNoTimeout(o => ar.Execute(), "AssetsRequest", null);
Watchdog.RunInThread(o => ar.Execute(), string.Format("AssetsRequest ({0})", m_scene.Name), null);
}
else
{

View File

@@ -57,6 +57,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
// public bool DisablePresenceChecks { get; set; }
public event InventoryArchiveSaved OnInventoryArchiveSaved;
public event InventoryArchiveLoaded OnInventoryArchiveLoaded;
/// <summary>
/// The file to load and save inventory if no filename has been specified
@@ -64,9 +65,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
protected const string DEFAULT_INV_BACKUP_FILENAME = "user-inventory.iar";
/// <value>
/// Pending save completions initiated from the console
/// Pending save and load completions initiated from the console
/// </value>
protected List<Guid> m_pendingConsoleSaves = new List<Guid>();
protected List<UUID> m_pendingConsoleTasks = new List<UUID>();
/// <value>
/// All scenes that this module knows about
@@ -111,6 +112,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{
scene.RegisterModuleInterface<IInventoryArchiverModule>(this);
OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted;
OnInventoryArchiveLoaded += LoadInvConsoleCommandCompleted;
scene.AddCommand(
"Archiving", this, "load iar",
@@ -139,7 +141,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
+ "-e|--exclude=<name/uuid> don't save the inventory item in archive" + Environment.NewLine
+ "-f|--excludefolder=<folder/uuid> don't save contents of the folder in archive" + Environment.NewLine
+ "-v|--verbose extra debug messages.\n"
+ "--noassets stops assets being saved to the IAR.",
+ "--noassets stops assets being saved to the IAR."
+ "--perm=<permissions> stops items with insufficient permissions from being saved to the IAR.\n"
+ " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer, \"M\" = Modify.\n",
HandleSaveInvConsoleCommand);
m_aScene = scene;
@@ -175,22 +179,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// Trigger the inventory archive saved event.
/// </summary>
protected internal void TriggerInventoryArchiveSaved(
Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
Exception reportedException)
UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
Exception reportedException, int SaveCount, int FilterCount)
{
InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved;
if (handlerInventoryArchiveSaved != null)
handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException);
handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException, SaveCount , FilterCount);
}
/// <summary>
/// Trigger the inventory archive loaded event.
/// </summary>
protected internal void TriggerInventoryArchiveLoaded(
UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream loadStream,
Exception reportedException, int LoadCount)
{
InventoryArchiveLoaded handlerInventoryArchiveLoaded = OnInventoryArchiveLoaded;
if (handlerInventoryArchiveLoaded != null)
handlerInventoryArchiveLoaded(id, succeeded, userInfo, invPath, loadStream, reportedException, LoadCount);
}
public bool ArchiveInventory(
Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream)
UUID id, string firstName, string lastName, string invPath, string pass, Stream saveStream)
{
return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary<string, object>());
}
public bool ArchiveInventory(
Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream,
UUID id, string firstName, string lastName, string invPath, string pass, Stream saveStream,
Dictionary<string, object> options)
{
if (m_scenes.Count > 0)
@@ -230,7 +246,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
}
public bool ArchiveInventory(
Guid id, string firstName, string lastName, string invPath, string pass, string savePath,
UUID id, string firstName, string lastName, string invPath, string pass, string savePath,
Dictionary<string, object> options)
{
// if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, savePath))
@@ -272,13 +288,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
return false;
}
public bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, Stream loadStream)
public bool DearchiveInventory(UUID id, string firstName, string lastName, string invPath, string pass, Stream loadStream)
{
return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>());
return DearchiveInventory(id, firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>());
}
public bool DearchiveInventory(
string firstName, string lastName, string invPath, string pass, Stream loadStream,
UUID id, string firstName, string lastName, string invPath, string pass, Stream loadStream,
Dictionary<string, object> options)
{
if (m_scenes.Count > 0)
@@ -294,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
try
{
request = new InventoryArchiveReadRequest(m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadStream, merge);
request = new InventoryArchiveReadRequest(id, this, m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadStream, merge);
}
catch (EntryPointNotFoundException e)
{
@@ -326,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
}
public bool DearchiveInventory(
string firstName, string lastName, string invPath, string pass, string loadPath,
UUID id, string firstName, string lastName, string invPath, string pass, string loadPath,
Dictionary<string, object> options)
{
if (m_scenes.Count > 0)
@@ -342,7 +358,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
try
{
request = new InventoryArchiveReadRequest(m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadPath, merge);
request = new InventoryArchiveReadRequest(id, this, m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadPath, merge);
}
catch (EntryPointNotFoundException e)
{
@@ -378,6 +394,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{
try
{
UUID id = UUID.Random();
Dictionary<string, object> options = new Dictionary<string, object>();
OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; });
@@ -400,10 +418,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
"[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}",
loadPath, invPath, firstName, lastName);
if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options))
m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}",
loadPath, firstName, lastName);
lock (m_pendingConsoleTasks)
m_pendingConsoleTasks.Add(id);
DearchiveInventory(id, firstName, lastName, invPath, pass, loadPath, options);
}
catch (InventoryArchiverException e)
{
@@ -417,7 +435,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// <param name="cmdparams"></param>
protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams)
{
Guid id = Guid.NewGuid();
UUID id = UUID.Random();
Dictionary<string, object> options = new Dictionary<string, object>();
@@ -439,6 +457,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
options["excludefolders"] = new List<String>();
((List<String>)options["excludefolders"]).Add(v);
});
ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; });
List<string> mainParams = ops.Parse(cmdparams);
@@ -464,8 +483,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
"[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
savePath, invPath, firstName, lastName);
lock (m_pendingConsoleSaves)
m_pendingConsoleSaves.Add(id);
lock (m_pendingConsoleTasks)
m_pendingConsoleTasks.Add(id);
ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options);
}
@@ -476,20 +495,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
}
private void SaveInvConsoleCommandCompleted(
Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
Exception reportedException)
UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
Exception reportedException, int SaveCount, int FilterCount)
{
lock (m_pendingConsoleSaves)
lock (m_pendingConsoleTasks)
{
if (m_pendingConsoleSaves.Contains(id))
m_pendingConsoleSaves.Remove(id);
if (m_pendingConsoleTasks.Contains(id))
m_pendingConsoleTasks.Remove(id);
else
return;
}
if (succeeded)
{
m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive for {0} {1}", userInfo.FirstName, userInfo.LastName);
// Report success and include item count and filter count (Skipped items due to --perm or --exclude switches)
if(FilterCount == 0)
m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive with {0} items for {1} {2}", SaveCount, userInfo.FirstName, userInfo.LastName);
else
m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive with {0} items for {1} {2}. Skipped {3} items due to exclude and/or perm switches", SaveCount, userInfo.FirstName, userInfo.LastName, FilterCount);
}
else
{
@@ -499,6 +522,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
}
}
private void LoadInvConsoleCommandCompleted(
UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream loadStream,
Exception reportedException, int LoadCount)
{
lock (m_pendingConsoleTasks)
{
if (m_pendingConsoleTasks.Contains(id))
m_pendingConsoleTasks.Remove(id);
else
return;
}
if (succeeded)
{
m_log.InfoFormat("[INVENTORY ARCHIVER]: Loaded {0} items from archive {1} for {2} {3}", LoadCount, invPath, userInfo.FirstName, userInfo.LastName);
}
else
{
m_log.ErrorFormat(
"[INVENTORY ARCHIVER]: Archive load for {0} {1} failed - {2}",
userInfo.FirstName, userInfo.LastName, reportedException.Message);
}
}
/// <summary>
/// Get user information for the given name.
/// </summary>

View File

@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{
@@ -69,8 +68,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood");
UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
InventoryItemBase foundItem1
= InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
@@ -79,7 +78,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
// Now try loading to a root child folder
UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA", false);
MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray());
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream);
archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream);
InventoryItemBase foundItem2
= InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xA/" + m_item1Name);
@@ -88,7 +87,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
// Now try loading to a more deeply nested folder
UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC", false);
archiveReadStream = new MemoryStream(archiveReadStream.ToArray());
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream);
archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream);
InventoryItemBase foundItem3
= InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC/" + m_item1Name);
@@ -110,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password");
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream);
archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream);
InventoryItemBase foundItem1
= InventoryArchiveUtils.FindItemByPath(
@@ -180,13 +179,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
mre.Reset();
archiverModule.ArchiveInventory(
Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream);
UUID.Random(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream);
mre.WaitOne(60000, false);
// LOAD ITEM
MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream);
archiverModule.DearchiveInventory(UUID.Random(), userFirstName, userLastName, "Scripts", userPassword, archiveReadStream);
InventoryItemBase foundItem1
= InventoryArchiveUtils.FindItemByPath(
@@ -229,7 +228,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{
// Test replication of path1
new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory(
iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
foldersCreated, nodesLoaded);
@@ -246,7 +245,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{
// Test replication of path2
new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory(
iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
foldersCreated, nodesLoaded);
@@ -292,7 +291,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory(
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
@@ -343,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, folder1ExistingName, (Stream)null, true)
new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, folder1ExistingName, (Stream)null, true)
.ReplicateArchivePathToUserInventory(
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());

View File

@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{
@@ -72,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
// TestHelpers.EnableLogging();
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password");
m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream);
m_archiverModule.DearchiveInventory(UUID.Random(), m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream);
InventoryItemBase coaItem
= InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_coaItemName);
@@ -106,8 +105,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
// log4net.Config.XmlConfigurator.Configure();
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood");
m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream);
m_archiverModule.DearchiveInventory(UUID.Random(), m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream);
InventoryItemBase foundItem1
= InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_item1Name);
@@ -171,7 +170,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
// log4net.Config.XmlConfigurator.Configure();
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password");
m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream);
m_archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream);
InventoryItemBase foundItem1
= InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);

View File

@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{
@@ -85,8 +84,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
InventoryArchiveReadRequest iarr
= new InventoryArchiveReadRequest(null, null, null, null, null, (Stream)null, false);
InventoryArchiveReadRequest iarr
= new InventoryArchiveReadRequest(UUID.Random(), null, null, null, null, null, null, (Stream)null, false);
iarr.LoadControlFile(filePath, data);
Assert.That(iarr.ControlFileLoaded, Is.True);
@@ -110,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
mre.Reset();
m_archiverModule.ArchiveInventory(
Guid.NewGuid(), userFirstName, userLastName, "/", userPassword, archiveWriteStream);
UUID.Random(), userFirstName, userLastName, "/", userPassword, archiveWriteStream);
mre.WaitOne(60000, false);
// Test created iar
@@ -179,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
mre.Reset();
m_archiverModule.ArchiveInventory(
Guid.NewGuid(), userFirstName, userLastName, "f1", userPassword, archiveWriteStream);
UUID.Random(), userFirstName, userLastName, "f1", userPassword, archiveWriteStream);
mre.WaitOne(60000, false);
// Test created iar
@@ -267,7 +266,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
mre.Reset();
m_archiverModule.ArchiveInventory(
Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream);
UUID.Random(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream);
mre.WaitOne(60000, false);
byte[] archive = archiveWriteStream.ToArray();
@@ -364,7 +363,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
// When we're not saving assets, archiving is being done synchronously.
m_archiverModule.ArchiveInventory(
Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options);
UUID.Random(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options);
byte[] archive = archiveWriteStream.ToArray();
MemoryStream archiveReadStream = new MemoryStream(archive);

View File

@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{
@@ -163,14 +162,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
scene.AddInventoryItem(coaItem);
archiverModule.ArchiveInventory(
Guid.NewGuid(), m_uaLL1.FirstName, m_uaLL1.LastName, "/*", "hampshire", archiveWriteStream);
UUID.Random(), m_uaLL1.FirstName, m_uaLL1.LastName, "/*", "hampshire", archiveWriteStream);
m_iarStreamBytes = archiveWriteStream.ToArray();
}
protected void SaveCompleted(
Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
Exception reportedException)
UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
Exception reportedException, int SaveCount, int FilterCount)
{
mre.Set();
}

View File

@@ -39,7 +39,6 @@ using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.Tests
{

View File

@@ -48,6 +48,8 @@ using Mono.Addins;
using OpenSim.Services.Connectors.Hypergrid;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Services.UserProfilesService;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using Microsoft.CSharp;
namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
{
@@ -78,7 +80,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
/// <value>
/// The configuration
/// </value>
public IConfigSource Config {
public IConfigSource Config
{
get;
set;
}
@@ -89,7 +92,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
/// <value>
/// The profile server URI.
/// </value>
public string ProfileServerUri {
public string ProfileServerUri
{
get;
set;
}
@@ -111,11 +115,17 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
/// <value>
/// <c>true</c> if enabled; otherwise, <c>false</c>.
/// </value>
public bool Enabled {
public bool Enabled
{
get;
set;
}
public string MyGatekeeper
{
get; private set;
}
#region IRegionModuleBase implementation
/// <summary>
@@ -152,6 +162,9 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
m_log.Debug("[PROFILES]: Full Profiles Enabled");
ReplaceableInterface = null;
Enabled = true;
MyGatekeeper = Util.GetConfigVarFromSections<string>(source, "GatekeeperURI",
new string[] { "Startup", "Hypergrid", "UserProfiles" }, String.Empty);
}
/// <summary>
@@ -599,30 +612,64 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
return;
UUID targetID;
UUID.TryParse(args[0], out targetID);
UUID.TryParse (args [0], out targetID);
string serverURI = string.Empty;
GetUserProfileServerURI(targetID, out serverURI);
GetUserProfileServerURI (targetID, out serverURI);
string theirGatekeeperURI;
GetUserGatekeeperURI (targetID, out theirGatekeeperURI);
IClientAPI remoteClient = (IClientAPI)sender;
UserProfilePick pick = new UserProfilePick();
UUID.TryParse(args[0], out pick.CreatorId);
UUID.TryParse(args[1], out pick.PickId);
UserProfilePick pick = new UserProfilePick ();
UUID.TryParse (args [0], out pick.CreatorId);
UUID.TryParse (args [1], out pick.PickId);
object Pick = (object)pick;
if(!rpc.JsonRpcRequest(ref Pick, "pickinforequest", serverURI, UUID.Random().ToString()))
{
remoteClient.SendAgentAlertMessage(
if (!rpc.JsonRpcRequest (ref Pick, "pickinforequest", serverURI, UUID.Random ().ToString ())) {
remoteClient.SendAgentAlertMessage (
"Error selecting pick", false);
return;
}
pick = (UserProfilePick) Pick;
Vector3 globalPos;
Vector3.TryParse(pick.GlobalPos,out globalPos);
pick = (UserProfilePick)Pick;
Vector3 globalPos = new Vector3(Vector3.Zero);
// Smoke and mirrors
if (pick.Gatekeeper == MyGatekeeper)
{
Vector3.TryParse(pick.GlobalPos,out globalPos);
}
else
{
// Setup the illusion
string region = string.Format("{0} {1}",pick.Gatekeeper,pick.SimName);
GridRegion target = Scene.GridService.GetRegionByName(Scene.RegionInfo.ScopeID, region);
if(target == null)
{
// This is a dead or unreachable region
}
else
{
// Work our slight of hand
int x = target.RegionLocX;
int y = target.RegionLocY;
dynamic synthX = globalPos.X - (globalPos.X/Constants.RegionSize) * Constants.RegionSize;
synthX += x;
globalPos.X = synthX;
dynamic synthY = globalPos.Y - (globalPos.Y/Constants.RegionSize) * Constants.RegionSize;
synthY += y;
globalPos.Y = synthY;
}
}
m_log.DebugFormat("[PROFILES]: PickInfoRequest: {0} : {1}", pick.Name.ToString(), pick.SnapshotId.ToString());
// Pull the rabbit out of the hat
remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name,
pick.Desc,pick.SnapshotId,pick.User,pick.OriginalName,pick.SimName,
globalPos,pick.SortOrder,pick.Enabled);
@@ -659,7 +706,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
/// Enabled.
/// </param>
public void PickInfoUpdate(IClientAPI remoteClient, UUID pickID, UUID creatorID, bool topPick, string name, string desc, UUID snapshotID, int sortOrder, bool enabled)
{
{
//TODO: See how this works with NPC, May need to test
m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString());
UserProfilePick pick = new UserProfilePick();
@@ -699,6 +747,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
avaPos.X, avaPos.Y, p.Scene.Name);
}
pick.PickId = pickID;
pick.CreatorId = creatorID;
pick.TopPick = topPick;
@@ -708,6 +757,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
pick.SnapshotId = snapshotID;
pick.User = landOwnerName;
pick.SimName = remoteClient.Scene.RegionInfo.RegionName;
pick.Gatekeeper = MyGatekeeper;
pick.GlobalPos = posGlobal.ToString();
pick.SortOrder = sortOrder;
pick.Enabled = enabled;
@@ -1259,6 +1309,37 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
}
}
/// <summary>
/// Gets the user gatekeeper server URI.
/// </summary>
/// <returns>
/// The user gatekeeper server URI.
/// </returns>
/// <param name='userID'>
/// If set to <c>true</c> user URI.
/// </param>
/// <param name='serverURI'>
/// If set to <c>true</c> server URI.
/// </param>
bool GetUserGatekeeperURI(UUID userID, out string serverURI)
{
bool local;
local = UserManagementModule.IsLocalGridUser(userID);
if (!local)
{
serverURI = UserManagementModule.GetUserServerURL(userID, "GatekeeperURI");
// Is Foreign
return true;
}
else
{
serverURI = MyGatekeeper;
// Is local
return false;
}
}
/// <summary>
/// Gets the user profile server UR.
/// </summary>

View File

@@ -1529,7 +1529,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
else
{
// The destination region just doesn't exist
failureReason = "Cannot cross into non-existant region";
failureReason = "Cannot cross into non-existent region";
}
if (neighbourRegion == null)
@@ -1786,8 +1786,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
// now we have a child agent in this region. Request all interesting data about other (root) agents
agent.SendOtherAgentsAvatarDataToMe();
agent.SendOtherAgentsAppearanceToMe();
agent.SendOtherAgentsAvatarDataToClient();
agent.SendOtherAgentsAppearanceToClient();
// Backwards compatibility. Best effort
if (version == "Unknown" || version == string.Empty)

View File

@@ -294,7 +294,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
logout = success; // flag for later logout from this grid; this is an HG TP
if (success)
sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
return success;
}
@@ -516,13 +516,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Local region?
if (info != null)
{
((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
Scene.RequestTeleportLocation(
remoteClient, info.RegionHandle, lm.Position,
Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
}
else
{
// Foreign region
Scene scene = (Scene)(remoteClient.Scene);
GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
GridRegion gatekeeper = new GridRegion();
gatekeeper.ServerURI = lm.Gatekeeper;
@@ -533,15 +533,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (finalDestination != null)
{
ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId);
IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
ScenePresence sp = Scene.GetScenePresence(remoteClient.AgentId);
if (transferMod != null && sp != null)
if (sp != null)
{
if (message != null)
sp.ControllingClient.SendAgentAlertMessage(message, true);
transferMod.DoTeleport(
// Validate assorted conditions
string reason = string.Empty;
if (!ValidateGenericConditions(sp, gatekeeper, finalDestination, 0, out reason))
{
sp.ControllingClient.SendTeleportFailed(reason);
return;
}
DoTeleport(
sp, gatekeeper, finalDestination, lm.Position, Vector3.UnitX,
(uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
}
@@ -625,4 +632,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return region;
}
}
}
}

View File

@@ -798,7 +798,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
{
AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString());
AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString());
if (rezAsset == null)
{
@@ -829,7 +829,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
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)
{
@@ -910,7 +912,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
// one full update during the attachment
// process causes some clients to fail to display the
// attachment properly.
m_Scene.AddNewSceneObject(group, true, false);
m_Scene.AddNewSceneObject(group, !attachment, false);
// if attachment we set it's asset id so object updates
// can reflect that, if not, we set it's position in world.

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