Compare commits

..

183 Commits

Author SHA1 Message Date
BlueWall
5eb2526e88 0006270: Warp3D leaks memory on mono based systems
Thanks Hiro Lecker for a patch to reduce memory useage with Warp3D map module
2012-09-06 05:18:08 -04:00
Mic Bowman
641b08aa78 Enables cast from int to float for MOD* functions;
Thanks SignpostMarv!
2012-09-05 09:13:16 -07:00
Justin Clark-Casey (justincc)
15d5f3d09d Bump master code up to 0.7.5 now that 0.7.4 is out. 2012-09-04 00:11:14 +01:00
SignpostMarv
07dbe46ba3 wrapping attachment functions in a region 2012-09-04 00:03:44 +01:00
SignpostMarv
ff867b59cf Implementing functing to send messages directly to attachments 2012-09-04 00:03:44 +01:00
SignpostMarv
d4b8a13a1d refactoring the grunt work of MessageObject into a private method with a UUID argument 2012-09-04 00:03:44 +01:00
SignpostMarv
a858c5daee implementing a function to get the number of attachments worn 2012-09-04 00:03:43 +01:00
SignpostMarv
8d431c6359 formatting 2012-09-04 00:03:43 +01:00
SignpostMarv
663bfbb372 although the attachmentPoint argument is a uint, zero is not a valid attachment point 2012-09-04 00:03:43 +01:00
Melanie
d297eb39e5 Revert "made setting rotation match Second Life"
Second Life seems to have introduced a bug, as we have confirmation that SL
behavior changed recently and changed in contradiction to their stated intention
This appears to be another of the bugs SL is notorious for. Signpost and I have
decided to back this out until SL's intention becomes clear.

This reverts commit f7b88d1c40.
2012-09-03 21:52:12 +01:00
Melanie
29218cdb31 Revert "no need to assign rotation to a variable now"
This reverts commit a3d140b57c.
2012-09-03 21:52:03 +01:00
Melanie
359f9efc76 Revert "formatting"
This reverts commit fb211c64fd.
2012-09-03 21:51:54 +01:00
SignpostMarv
fb211c64fd formatting 2012-09-03 13:55:41 +01:00
SignpostMarv
a3d140b57c no need to assign rotation to a variable now 2012-09-03 13:55:40 +01:00
SignpostMarv
f7b88d1c40 made setting rotation match Second Life 2012-09-03 13:55:40 +01:00
Robert Adams
32b534f324 BulletSim: update the SOs and DLLs 2012-08-31 11:41:39 -07:00
Robert Adams
ffdc798720 BulletSim: Update BulletSimAPI to match the DLL interface.
Major rework of terrain management which finally makes mega-regions work.
Update heightmap of terrain by rebuilding the terrain's body and shape.
    There is a problem with just replacing the shape so this workaround
    will do for the moment but it will need to be resolved for
    mesh and hull switching.
2012-08-31 11:41:33 -07:00
Robert Adams
ae852bb873 BulletSim: clean up some variable naming for consistancy.
Update DLL API for new terrain and shape/body pattern methods.
Terrain creation and modification uses new shape/body pattern.
Move debug logging callback set to initialization call so logging
   is per physics engine.
2012-08-31 11:41:28 -07:00
Robert Adams
d3adf9b2b3 BulletSim: fix line endings. 2012-08-31 11:41:23 -07:00
Robert Adams
7c140570db BulletSim: Changes to terrain storage and management so mega-regions work.
Moved all terrain code out of BSScene and into new BSTerrainManager.
Added logic to manage multiple terrains for mega-regions.
Added new functions to BulletSimAPI to match the library.
Moved all of the terrain creation and setup logic from C++ code to C# code.
    The unused code has not yet been removed from either place. Soon.
Moved checks for avatar above ground and in bounds into BSCharacter.
2012-08-31 11:41:18 -07:00
Robert Adams
7b6987ce83 BulletSim: unify physical objects under BSPhysObjects. Now BSScene and BSLinkset only know of BSPhysObject's and there is only one list to search in BSScene. 2012-08-31 11:41:12 -07:00
Robert Adams
0376b8ddbc BulletSim: add new interface for mesh, hull and terrain creation that will move nearly all of the logic into the C# code. 2012-08-31 11:41:07 -07:00
Mic Bowman
2d2495cc45 Remove the unused Newtonsoft.Json dlls
Also remove the license files
2012-08-31 11:33:53 -07:00
BlueWall
a0eda6eb16 Fix Windows build
Add reference to fix Windows build: no windows here to test, please report any issues back to IRC #opensim-dev ASAP
2012-08-31 13:09:54 -04:00
SignpostMarv
dac31303b7 Type.Type is RuntimeType 2012-08-31 15:33:15 +01:00
Melanie
edd3577b66 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-08-31 14:34:44 +01:00
SignpostMarv
054db94d5d formatting 2012-08-31 14:32:33 +01:00
SignpostMarv
794c5f5a6d adding support for static method script invocations 2012-08-31 14:32:33 +01:00
SignpostMarv
b625579780 moving assignment to new line to make next commit easier to read in diffs 2012-08-31 14:32:33 +01:00
SignpostMarv
7e41559917 using specific type instead of var 2012-08-31 14:32:33 +01:00
SignpostMarv
8cd415c2b0 formatting 2012-08-31 14:32:32 +01:00
SignpostMarv
4c58c1b116 formatting 2012-08-31 14:32:32 +01:00
SignpostMarv
e6f43023b6 adding support for finding static methods 2012-08-31 14:32:32 +01:00
SignpostMarv
bcf944db48 assign binding flags to variable 2012-08-31 14:32:32 +01:00
SignpostMarv
7a9eee8538 no need to assign result to GetMethodInfoFromType 2012-08-31 14:32:32 +01:00
SignpostMarv
05648c2c4a changing to use Type argument instead of object 2012-08-31 14:32:31 +01:00
SignpostMarv
dff746df7b moving code that will be common into private static method 2012-08-31 14:32:31 +01:00
SignpostMarv
973f2e8be5 adding documentation to script invokation methods 2012-08-31 14:32:31 +01:00
SignpostMarv
3c019bea8c Implementing a vastly simpler means of allowing region modules to access GetLinkParts than mantis 6236 2012-08-31 01:19:17 +01:00
Melanie
68814f904e Replace SendBannedUserList with Avination's version. Untested in core. Not even test compiled. 2012-08-31 00:37:27 +01:00
Justin Clark-Casey (justincc)
3bd3f448a2 Also do other MySQL region settings related calls under m_dbLock, in common with other calls. 2012-08-31 00:33:06 +01:00
Justin Clark-Casey (justincc)
7c6e8fab15 Do Windlight storage and removal calls in MySQL under m_dbLock, as is done with all the other database calls. 2012-08-31 00:29:57 +01:00
Justin Clark-Casey (justincc)
3ed0d79b00 Make ReuseDynamicTextures an experimental config setting in [Textures]. Default is false, as before.
If true, this setting reuses dynamically generated textures (i.e. created through osSetDynamicTextureData() and similar OSSL functions) where possible rather than always regenerating them.
This results in much quicker updates viewer-side but may bloat the asset cache (though this is fixable).
Also, sometimes issue have been seen where dynamic textures do not transfer to the viewer properly (permanently blurry).
If this happens and that flag is set then they are not regenerated, the viewer has to clear cache or wait for 24 hours before all cached uuids are invalidated.
CUrrently experimental.  Default is false, as before.
2012-08-30 22:57:40 +01:00
Justin Clark-Casey (justincc)
d89b974680 If the compile-time DynamicTextureModule.ReuseTextures flag is set, check metadata still exists for any reused asset in case some other process has removed it from the cache. 2012-08-30 22:28:45 +01:00
SignpostMarv
c76c63725b fixing bug where last element in list is ignored 2012-08-30 00:10:28 +01:00
SignpostMarv
6b277394c0 refactoring as the list funcs either skip invalid values or recall ToDoubleList 2012-08-30 00:10:28 +01:00
Justin Clark-Casey (justincc)
adce58b33a Renaming existing 'torture' tests to 'performance' tests instead, since this better matches what they really do.
nant target name changes to test-perf instead of torture, to match test-stress
still not run by default
2012-08-29 23:19:21 +01:00
Justin Clark-Casey (justincc)
1f88179a65 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-29 23:16:16 +01:00
Justin Clark-Casey (justincc)
ec726413dd Add VectorRenderModuleStressTests that contains a long running test that generates thousands of vector textures concurrently.
Intended for use if there are future issues with mono crashes whilst generate dynamic textures.
This test is triggered via a new test-stress nant target.
Not run by default.
2012-08-29 23:04:00 +01:00
Mic Bowman
3d736d575f This partially implements the LSL function to set the response
type for an HTTP request. Since the "official" LSL function limits
the use of the response type, it is implemented as osSetContentType
with a string for the content mime type and a threat level of high.
With this function you should be able to implement rather functional
media-on-a-prim application with much less difficulty.
2012-08-29 14:56:51 -07:00
SignpostMarv
0c3061f973 implementing rule tracking 2012-08-29 02:10:04 +01:00
SignpostMarv
3bf7bd6359 track originating IScriptApi method for SL-like error messages. Will add rule number tracking in next commit. 2012-08-29 02:10:04 +01:00
Justin Clark-Casey (justincc)
7ea832d47c Fix regression introduced in a0d178b2 (Sat Aug 25 02:00:17 2012) where folders with asset type of 'Folder' and 'Unknown' were accidentally treated as system folders.
This prevented more than one additional ordinary folder from being created in the base "My Inventory" user folder.
Added regression test for this case.
Switched tests to use XInventoryService with mostly implemented TestXInventoryDataPlugin rather than InventoryService
Disabled TestLoadIarV0_1SameNameCreator() since this has not been working for a very long time (ever since XInventoryService) started being used
since it doesnt' preserve creator data in the same way as InventoryService did and so effectively lost the OSPAs.
However, nobody noticed/complained about this issue and OSPAs have been superseded by HG like creator information via the --home save oar/iar switch.
2012-08-29 02:01:43 +01:00
Justin Clark-Casey (justincc)
c1cece4b82 Add experimental DynamicTextureModule.ReuseTextures flag, currently only configurable on compile.
Disabled (status quo) by default.
This flag makes the dynamic texture module reuse cache previously dynamically generated textures given the same input commands and extra params for 24 hours.
This occurs as long as those commands would always generate the same texture (e.g. they do not contain commands to fetch data from the web).
This makes texture changing faster as a viewer-cached texture uuid is sent and may reduce simulator load in regions with generation of lots of dynamic textures.
A downside is that this stops expiry of old temporary dynamic textures from the cache,
Another downside is that a jpeg2000 generation that partially failed is currently not regenerated until restart or after 24 hours.
2012-08-28 23:06:53 +01:00
Justin Clark-Casey (justincc)
aa44df9c04 Add IDynamicTextureManager.ConvertData() to match AsyncConvertData(). Remove mismatching ConvertStream() where there is no AsyncConvertStream and neither IDynamicTextureManager implementer implements this method. 2012-08-28 20:35:17 +01:00
SignpostMarv
1e18f0f26a copying documentation from http://opensimulator.org/wiki/Threat_level 2012-08-28 00:12:35 +01:00
SignpostMarv
8a7fbfb06a adding some files to .gitignore that get generated when debugging in c# express with OpenSim.32BitLaunch as the startup project 2012-08-27 23:48:29 +01:00
SignpostMarv
e916b1399f formatting 2012-08-27 23:39:18 +01:00
SignpostMarv
72c2d13ac6 refactoring to load from self (fixes ChanneDigger being absent) 2012-08-27 23:39:18 +01:00
SignpostMarv
a6d689c529 refactoring to assign the first argument to a variable 2012-08-27 23:39:18 +01:00
Justin Clark-Casey (justincc)
ab9bfe5156 minor: Simplify return of vector render module name and some very minor removal of unncessary syntax clutter 2012-08-27 23:06:37 +01:00
Justin Clark-Casey (justincc)
4e26d039d6 Add VectorRenderModule.TestRepeatSameDrawDifferentExtraParams() 2012-08-27 23:03:21 +01:00
Justin Clark-Casey (justincc)
3082fdd0f6 Add VectorRenderModuleTests.TestRepeatDrawContainingImage() 2012-08-27 22:58:20 +01:00
Justin Clark-Casey (justincc)
e90168c738 Add VectorRenderModuleTests.TestRepeatDraw() 2012-08-27 22:42:40 +01:00
Melanie
a5c6cb2fc9 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-08-25 17:34:08 +01:00
Melanie
6ea95a3294 Fix and refactor region registration. Reorder checks to short-curcuit expensive and destructive ones. Properly fix region reservation and authentication.
Make region moves and flags preservation work again as intended. Prevent
failes reservation take-over from damging reservation data.
2012-08-25 17:32:00 +01:00
SignpostMarv
6e86b23012 implementing PRIM_LINK_TARGET on GetPrimParams ala SetPrimParams 2012-08-25 02:30:23 +01:00
SignpostMarv
58714b0aca minor formatting 2012-08-25 02:30:23 +01:00
SignpostMarv
5203665bb2 refactoring to local variable for cleaner code 2012-08-25 02:30:23 +01:00
SignpostMarv
2a2e120470 since we will be making the Get return type the remaining ruleset as with the Set return type, we need to move the original return type to a ref param 2012-08-25 02:30:23 +01:00
SignpostMarv
a8044999fb use SceneObjectPart instead of var 2012-08-25 02:30:23 +01:00
SignpostMarv
3d504261b0 renaming to be similar to equivalent Set command 2012-08-25 02:30:23 +01:00
Justin Clark-Casey (justincc)
a0d178b284 Following on from f8a89a79, do not allow more than one 'type' folder (e.g. calling cards) to be created in the base "My Inventory" user folder.
This is to accomodate situations where viewers will create more than one 'type' subfolder (e.g. calling cards)
But at the same time to prevent multiple such 'system' folders (those in the base "My Inventory" user folder).
This also makes GetFolderForType() only return a folder in the base "My Inventory" folder, if such a type folder exists
2012-08-25 02:00:17 +01:00
Justin Clark-Casey (justincc)
f8a89a79eb Allow multiple calling card type inventory folders to be created.
Modern viewers want to create Friends and All folders of this type inside the root Calling Cards folder.
2012-08-25 01:09:12 +01:00
Justin Clark-Casey (justincc)
e04047152f minor: Fix bad log message for failure to create an inventory folder 2012-08-25 00:49:38 +01:00
Justin Clark-Casey (justincc)
f3a5e3a02b Log initial script startup info notice when xengine actually starts to do this for debugging purposes, rather than before it actually starts to do this. 2012-08-25 00:42:32 +01:00
Justin Clark-Casey (justincc)
ba58331b29 Extend "Restarting scripts in attachments" debug log message to show actual name of user and the region they are in 2012-08-24 22:56:05 +01:00
Justin Clark-Casey (justincc)
476996bee8 If a connecting scene presence is replacing an existing scene presence then bypass close checks. 2012-08-24 22:38:07 +01:00
Justin Clark-Casey (justincc)
01771aca40 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-24 21:38:46 +01:00
Justin Clark-Casey (justincc)
cd325fdf02 Pass the "attachToBackup" bool given to SceneGraph.AddNewSceneObject() down into the 3-parameter AddNewSceneObject() method instead of always hardcoding true.
This doesn't affect any core OpenSimulator code since all callers were passing true anyway
But it allows region modules to create objects that are never persisted.
2012-08-24 21:36:20 +01:00
SignpostMarv
67477290ad stripping superfluous whitespace
Signed-off-by: Melanie <melanie@t-data.com>
2012-08-24 17:44:35 +01:00
SignpostMarv
582a256646 immediately returning the string.Join operation instead of checking if the list has members 2012-08-24 17:44:14 +01:00
SignpostMarv
d188272462 refactoring using List.ConvertAll<string> 2012-08-24 17:44:14 +01:00
SignpostMarv
632908db9e adding sqlite journal files to .gitignore 2012-08-24 01:26:11 +01:00
Justin Clark-Casey (justincc)
82b23f7cc1 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-24 01:20:23 +01:00
Justin Clark-Casey (justincc)
a08687aef3 Revert "implementing function to allow scripts to self-replicate as if the owner duplicated them, using the same script delay as llRezObject()"
This reverts commit 2ad9d656b3.

Reverted pending consideration of associated issues.
2012-08-24 01:18:35 +01:00
SignpostMarv
2ad9d656b3 implementing function to allow scripts to self-replicate as if the owner duplicated them, using the same script delay as llRezObject() 2012-08-24 00:21:42 +01:00
Melanie
1747030d19 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-08-24 00:16:58 +01:00
Melanie
c557684666 Fix bad child prim permissions that can make objects change perms after rezzing
Port from Avination
2012-08-24 00:15:30 +01:00
TBG Renfold
a3cbda0d74 Removed land checking as suggested by SignpostMarv.
Now whatever remaining health the avatar has is displayed (float).
This will be 100% (100.000000) if no damage has occurred (as what the viewer should really be seeing anyway).

Returns -1.000000 if the avatar is not found.
2012-08-24 00:13:27 +01:00
TBG Renfold
4f3fabae5b Adds osGetHealth.
Returns the amount of health (in an integer) that an avatar has left in the scene.
If an avatar is not found or safe is enabled on a region, -1 is returned.

Example usage:

default
{
    touch_end(integer _t)
    {
        key agentID = llDetectedKey(0);
        osCauseDamage(agentID, 50);
        llSay(0, llKey2Name(agentID) + " has " + (string)osGetHealth(agentID) + "% health left.");
    }
}
2012-08-24 00:13:14 +01:00
Justin Clark-Casey (justincc)
aede42b875 If a script state save fails for some reason on shutdown/region removal, get xengine to spit out some useful information and continue to save other script states 2012-08-23 23:13:53 +01:00
Justin Clark-Casey (justincc)
a533db7e27 Add an [HGAssetService] section to SQLiteStandalone.ini with the same connection string as [AssetService].
This is necessary because commit 8131a24 (Tue Mar 27 10:08:13 2012) started passing the config section name rather than hardcoding "AssetService"
This meant that the HG external-facing asset service tried to read ConnectionString from [HGAssetService] rather than [AssetService].
On SQLite, not finding this meant that it fell back to [DatabaseService], which is set for OpenSim.db rather than Asset.db.
Therefore, all external asset requests returned null.
Solution taken here is to create an [HGAssetService] section with the same ConnectionString as [AssetService].
This bug does not affect normal MySQL/MSSQL config since they use the [DatabaseService] connection string anyway.
Addresses http://opensimulator.org/mantis/view.php?id=6200, many thanks to DanBanner for identifying the exact problem commit which was very helpful.
This was a regression from OpenSimulator 0.7.3.1 which did not contain this bug.
2012-08-23 22:30:14 +01:00
SignpostMarv
4820dfd733 this should be an if-else block in case the non-phys min/max are smaller than the physical min/max 2012-08-22 23:55:01 +01:00
Justin Clark-Casey (justincc)
1369058280 Lock disposal of separate gdi+ objects under different threads since this prevents malloc heap corruption seen under Ubuntu 10.04.1 and 11.04 - probably a libcairo issue
In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
the native malloc heap can become corrupted, possibly due to a double free().  This may be due to
bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX.  These problems were
seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1.  They go away if disposal is perfomed
under lock.
2012-08-22 23:04:17 +01:00
Robert Adams
568de9313a BulletSim: update DLLs and SOs to eliminate terrain update crash which manifested itself on Linux. 2012-08-21 20:55:48 -07:00
Justin Clark-Casey (justincc)
219326dd8e Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-21 22:29:27 +01:00
Justin Clark-Casey (justincc)
9925317239 Fix bug in SoundModule.PlayAttachedSound() where every sound update to an avatar would base its gain calculation on the previous avatar's gain, instead of the original input gain
This is similar to commit d89faa which fixed the same kind of bug in TriggerSound()
2012-08-21 22:21:35 +01:00
nebadon
150748392e testing github bot take 2 2012-08-20 15:57:28 -07:00
nebadon
555edc4ef7 testing github commit bot 2012-08-20 15:51:30 -07:00
SignpostMarv
481c00f50a refactoring out SetFaceColor 2012-08-20 23:10:25 +01:00
SignpostMarv
ede3b9ab07 making use of implicit operators and Util.Clip handling of Vector3 2012-08-20 23:10:25 +01:00
SignpostMarv
b863a15a82 single operation for PRIM_COLOR 2012-08-20 23:10:25 +01:00
SignpostMarv
aee4353e9c fix typo 2012-08-20 23:10:25 +01:00
Justin Clark-Casey (justincc)
e6fb458597 no-op change for cia.vc test 2012-08-20 22:18:29 +01:00
Justin Clark-Casey (justincc)
812c498ef4 When loading an OAR, validate any group UUIDs and properly reconstruct parcel access lists.
If a group UUID is present that is not on this simulator then the object or parcel is no longer group owned.
This is a change from previous behaviour where such invalid UUIDs were kept.
This is an adaptation of patch 0002 from http://opensimulator.org/mantis/view.php?id=6105 by Oren Hurvitz of Kitely.
My adaptations are formatting only, apart from the notices about parcel owner IDs not being saved since this has now been fixed.
Thanks Oren.
2012-08-20 22:01:02 +01:00
Justin Clark-Casey (justincc)
970727e57e Tighten up OpenSim.Framework.Cache locking to avoid race conditions.
This is to resolve a reported issue in http://opensimulator.org/mantis/view.php?id=6232
Here, the land management module is using OpenSim.Framework.Cache (the only code to currently do so apart from the non-default CoreAssetCache).
2012-08-20 20:55:58 +01:00
Justin Clark-Casey (justincc)
bcbd450fe4 Add --force flag to "kick user" console command to allow bypassing of recent race condition checks.
This is to allow a second attempt to remove an avatar even if "show connections" shows them as already inactive (i.e. close has already been attempted once).
You should only attempt --force if a normal kick fails.
This is partly for diagnostics as we have seen some connections occasionally remain on lbsa plaza even if they are registered as inactive.
This is not a permanent solution and may not work anyway - the ultimate solution is to stop this problem from happening in the first place.
2012-08-20 20:24:54 +01:00
Melanie
9aec62f0ac Fix scripted detach of temp attachments 2012-08-20 15:59:38 +01:00
Melanie
dd0556abc9 Fix llDialog responses so that they can be heard throughout the region. This now conforms to the behaviour in SL. 2012-08-19 22:05:38 +01:00
Melanie
8769e4ee73 Add a reference to OpenMetaverseType.dll to compiled script assemblies. 2012-08-18 19:08:38 +01:00
SignpostMarv
d72d599056 integrating redundant code into operator 2012-08-18 18:30:00 +01:00
SignpostMarv
ca33619e11 Rot2Quaternion is now redundant 2012-08-18 18:30:00 +01:00
SignpostMarv
ffdde05bb7 constructor means not having to manually refer to individual properties 2012-08-18 18:29:59 +01:00
SignpostMarv
fb84ff96a9 implicit operators mean one does not need to instantiate new objects manually 2012-08-18 18:29:59 +01:00
SignpostMarv
52d7af05bc adding missing refactor for LSL_Vector 2012-08-18 18:29:59 +01:00
SignpostMarv
2b0c8bc480 Implementing operators & constructors for Quaternion 2012-08-18 18:29:59 +01:00
Melanie
2a70afeca2 Fix the whitespace formatting error introduced by the last patch 2012-08-18 14:00:10 +01:00
SignpostMarv
5d7751da89 refactoring for Vector3 operator & constructor tweaks 2012-08-18 13:21:55 +01:00
Melanie
9d6fe1224a Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-08-18 12:57:49 +01:00
Justin Clark-Casey (justincc)
e4e5237086 When reporting a thread timeout, create a copy of the info rather than passing the original ThreadWatchdogInfo structure.
This is to avoid the possibility of misleading reporting if a watchdog update outraces an alarm.
Should address any remaining issues from http://opensimulator.org/mantis/view.php?id=6012
2012-08-18 00:46:34 +01:00
SignpostMarv
28d0aff2e3 adding null return to fix building 2012-08-17 23:23:03 +01:00
SignpostMarv
7068fddd2f fixing bug that get/set the wrong property for prim types other than sphere & box 2012-08-17 23:23:03 +01:00
SignpostMarv
466d684fbe implemented 2012-08-17 23:23:03 +01:00
SignpostMarv
74f5253a36 attempt to handle InvalidCastException in a manner similar to Second Life 2012-08-17 23:08:24 +01:00
Justin Clark-Casey (justincc)
3ad827174e Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-17 22:50:54 +01:00
Justin Clark-Casey (justincc)
56da788243 Add information to ThreadStackSize about possibly increasing if suffering StackOverflowExceptions during script conversion/compilation (e.g. on Windows 64-bit) 2012-08-17 22:50:11 +01:00
Robert Adams
7243d4f842 BulletSim: Properly regenerate hulls when objects made physical.
This fixes the problem of non-base shapes (cubes and spheres)
    falling through the terrain.
2012-08-17 14:45:18 -07:00
Justin Clark-Casey (justincc)
f57c1ac386 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-17 22:31:58 +01:00
Justin Clark-Casey (justincc)
0860a0d856 minor: Make xengine debug message on script load a scripting loading message instead.
This is more useful if compilation fails due to an uncatchable exception since we know what was being compiled.
2012-08-17 22:30:01 +01:00
Robert Adams
03d76e9403 BulletSim: restore most of the Detail logging statements. Will have
no effect on non-logging running.
Capture region name that is passed to the physics engine and use
    it for detail logging file name prefix.
Fix problem with avatars dropping when flying across region boundries.
2012-08-17 13:34:22 -07:00
Robert Adams
5c192b9bab Modify order of code so SOP doesn't set the physics actor flying
property multiple times every time Update is called.
This eliminates zillions of settings which is better for BulletSim.
The should be no functionality change.
2012-08-17 13:34:20 -07:00
Robert Adams
ccc69d66a1 BulletSim: add parameters and functionality to specify the mesh
level of detail for large meshes.
Remove parameter and code for DetailLog (conditional logging into
   regular log file).
2012-08-17 13:34:18 -07:00
Robert Adams
8eda290262 BulletSim: comments and parameter changes in dynamics engine. 2012-08-17 13:34:16 -07:00
Robert Adams
e31e23d68d BulletSim: in BSDynamics, merge 'flags' and 'hoverFlags' as they are defined for the same bits and it makes the code less complicated. 2012-08-17 13:34:14 -07:00
Justin Clark-Casey (justincc)
99e339dd40 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-17 18:48:35 +01:00
SignpostMarv
e9ea911563 adding a clip method to handle Vector3 objects to enable a minor amount of refactoring 2012-08-17 18:40:49 +01:00
Melanie
9995421df1 Do a proper null check to avoid the overloaded operator == trap 2012-08-16 02:35:03 +01:00
Robert Adams
57a9879669 Correct an exception report in SceneObjectPart so it outputs the stack. 2012-08-15 16:39:00 -07:00
Robert Adams
376441e550 BulletSim: make it so objects in a linkset do not generate collisions with each other. 2012-08-15 16:29:50 -07:00
Robert Adams
ae5db637f2 BulletSim: update DLLs and SOs to fix the problem with avatars jumping around at altitudes less than 25m. 2012-08-15 16:29:46 -07:00
SignpostMarv
ef4122213c enables configurable minimum sizes for physical & non-physical prims 2012-08-15 23:35:23 +01:00
Melanie
e286a95d76 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-08-15 22:59:31 +01:00
SignpostMarv
0aa1f1cc3f Implementing PRIM_LINK_TARGET in a non-recursive fashion 2012-08-15 22:58:33 +01:00
Justin Clark-Casey (justincc)
5a1b6fdf06 Don't enable the thread watchdog until all regions are ready.
This is to avoid false positives when the machine is under heavy load whilst starting up.
2012-08-15 22:43:32 +01:00
SignpostMarv
7679384829 adding ATTACH_*_PEC constants 2012-08-15 22:06:20 +01:00
Robert Adams
9f83f4bfa3 BulletSim: update DLLs and SOs 2012-08-15 12:08:29 -07:00
Robert Adams
2b982ab212 BulletSim: add physics logging parameters to OpenSimDefaults.ini. Remove trailing semis from some the of the value definitions. 2012-08-15 12:08:25 -07:00
Robert Adams
dd10cf01e7 BulletSim: add hinge constraint.
Update BulletSimAPI with new constraint related function calls.
Reorganize locking in BS6DofConstraint.
Update BS6DofConstraint to do constraint reset correctly.
Add new 'midpoint' construction of 6Dof constraint.
2012-08-15 12:08:21 -07:00
Robert Adams
9efe7bf7ba BulletSim: add locking to constraintCollection and rename some of the public method variables to reduce confusion between a physics scene and the real scene. 2012-08-15 12:08:17 -07:00
Robert Adams
68f112888b BulletSim: clean up detail logging by adding many more debug log statements and then commenting out most of the additions. 2012-08-15 12:08:13 -07:00
Robert Adams
b05a2fc4ed BulletSim: don't recreate mesh unless it needs it when rebuilding the hull. Make sure the collisionCollection is reallocated each tick to fix race condition of it being cleared while still in use. 2012-08-15 12:08:09 -07:00
Robert Adams
257446889b BulletSim: fix problem of a null reference exception on shutdown if there were linksets in the region. 2012-08-15 12:08:05 -07:00
Robert Adams
77a7758cf5 BulletSim: Refactor BSConstraintCollection to add a new RemoveAndDestroyConstraint(BSConstraint xx) 2012-08-15 12:08:01 -07:00
Robert Adams
c1c1d48af1 BulletSim: add BSConstraint.RecomputConstraintVariables for the recomputation after linksets changed, etc 2012-08-15 12:07:57 -07:00
Robert Adams
6f1f299619 BulletSim: Add the class BSCharacter to the DetailLog output 2012-08-15 12:07:53 -07:00
Robert Adams
11a4b9ec1d BulletSim: rework physics FPS calculation to make a more realistic number. 2012-08-15 12:07:49 -07:00
Melanie
ebbf349c6a Let the temp attachment module add a command to allow attaching without permissions and add support for this (incomplete!) to LSL 2012-08-15 19:37:16 +01:00
Melanie
c27ff70d5c Add support for the extra params to scene and the event manager 2012-08-15 18:58:39 +01:00
Melanie
c7f2debd38 Fix and finish the extra parameters storage system for MySQL 2012-08-15 18:58:32 +01:00
Melanie
dc82ad0f7a Add a skeleton for a name value storage associated with regions 2012-08-15 02:06:22 +01:00
Melanie
f6562e2269 Actually add the module 2012-08-14 22:22:25 +01:00
Melanie
faa710aee1 Allow the use of the region debug console found in recent viewers. This console
will be available to estate owners and managers. If the user using the console
had god privs, they can use "set console on" and "set console off" to switch on
the actual region console. This allows console access from within the viewer.
The region debug console can coexist with any other main console.
2012-08-14 22:22:20 +01:00
Justin Clark-Casey (justincc)
d8125fb1f7 minor: Add Gryc Ueusp to CREDITS for commit 884edac amongst others, by request. 2012-08-14 21:56:31 +01:00
Justin Clark-Casey (justincc)
c42fe6c159 Prevent race conditions when one thread removes an NPC SP before another thread has retreived it after checking whether the NPC exists. 2012-08-14 21:44:06 +01:00
Melanie
a5b6492223 Perform ownership transfer and permission propagation as well as needed
updates on the new temp attachment.
2012-08-14 13:40:13 +01:00
Melanie
1be072f19e Move inititalization to RegionLoaded to avoid a module loading order issue 2012-08-14 09:55:44 +01:00
Melanie
4bbdcfb5ee Implement the temp attachments. UNTESTED 2012-08-14 01:45:02 +01:00
Melanie
9bd2c1b88a As per lindn spec, disable detach and drop for temp attachments 2012-08-14 01:12:27 +01:00
Melanie
62acfabec4 Add the skeleton for the temp attachments module 2012-08-14 00:54:12 +01:00
Melanie
50db8649aa Exclude temp attachemnts from being sent to the avatar service 2012-08-14 00:29:39 +01:00
Melanie
fe4c3a37c0 Lay some groundwork for temp attachments. Decouple attachments from inventory. 2012-08-14 00:12:15 +01:00
SignpostMarv
58c630c18e attempt at replicating behaviour of llList2thing functions in SL
Committed with changes. Please don't sign comments with your name. Please
don't use your own coding style, use the OpenSim project style. Please
don't modify unrelated whitespace.

Signed-off-by: Melanie <melanie@t-data.com>
2012-08-13 19:17:19 +01:00
Robert Adams
3ecd39068c Merge branch 'bulletsim7' 2012-08-10 16:35:00 -07:00
Robert Adams
3a55d5b123 BulletSim: actually update the DLLs and SOs 2012-08-10 16:34:22 -07:00
Robert Adams
0c7ce4fc98 BulletSim: many, many detailed logging messages for physical linkset
debugging.
Linkset bugs fixed where accounting of children would get lost.
Moved scene based vehicle tracking logic from prim to the scene.
Added GetCollisionFlags2 method to BulletSimAPI.
Updated DLLs and SOs.
2012-08-10 16:22:44 -07:00
Robert Adams
3ca770cd2c BulletSim: Add module names to DetailLog output. Fix some problems with linksets that were caused by checking data structures that are changed regularly from taint time code -- resulted in linksets not being unlinked properly. 2012-08-10 08:33:09 -07:00
Robert Adams
320982cae3 BulletSim: add an identifier to the TaintObject call so exceptions that happen when the taint is invoked can be debugged 2012-08-09 15:17:19 -07:00
Robert Adams
38e79b80a8 BulletSim: separate out the constraints by type. The linksets use
6dof constraint but eventually others will be exposed so future
features can use all the Bullet capabilities.
Force children to generate a position update when unlinked.
2012-08-09 15:01:05 -07:00
Robert Adams
5ab151c2d6 BulletSim: add avatar code to keep avatars from ending up trapped under the terrain 2012-08-08 13:48:49 -07:00
Robert Adams
19417fca41 BulletSim: Added avatar capsule scaling for size of avatar.
This also fixes computation of avatar mass.
Added parameter MaxPersistantManifoldPoolSize.
Fixed a parameter setting bug which caused crashes of there were
  more than 400 or so physical objects. I tested up to 5000.
Updated BulletSim DLLs and SOs.
2012-08-07 17:15:06 -07:00
Melanie
926c0b90a1 Release http-in URLs when llResetScript is called 2012-08-07 20:48:22 +01:00
Robert Adams
4adb3471ac BulletSim: update SOs and DLLs to run on more Linux versions. Correct multiple buoyancy settings when character flying. Remove chatty log message on prim destruction. 2012-08-06 12:55:52 -07:00
277 changed files with 6033 additions and 25682 deletions

1
.gitignore vendored
View File

@@ -66,7 +66,6 @@ Examples/*.dll
OpenSim.build
OpenSim.sln
OpenSim.suo
OpenSim.userprefs
Prebuild/Prebuild.build
Prebuild/Prebuild.sln
TestResult.xml

View File

@@ -92,6 +92,7 @@ what it is today.
* Flyte Xevious
* Garmin Kawaguichi
* Gryc Ueusp
* Hiro Lecker
* Imaze Rhiano
* Intimidated
* Jeremy Bongio (IBM)

View File

@@ -572,7 +572,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
region.ExternalHostName = (string) requestData["external_address"];
bool persist = Convert.ToBoolean(requestData["persist"]);
bool persist = Convert.ToBoolean((string) requestData["persist"]);
if (persist)
{
// default place for region configuration files is in the
@@ -982,8 +982,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
string lastName = (string) requestData["user_lastname"];
string password = (string) requestData["user_password"];
uint regionXLocation = Convert.ToUInt32(requestData["start_region_x"]);
uint regionYLocation = Convert.ToUInt32(requestData["start_region_y"]);
uint regionXLocation = Convert.ToUInt32((Int32) requestData["start_region_x"]);
uint regionYLocation = Convert.ToUInt32((Int32) requestData["start_region_y"]);
string email = ""; // empty string for email
if (requestData.Contains("user_email"))
@@ -1180,9 +1180,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController
if (requestData.ContainsKey("user_password")) password = (string) requestData["user_password"];
if (requestData.ContainsKey("start_region_x"))
regionXLocation = Convert.ToUInt32(requestData["start_region_x"]);
regionXLocation = Convert.ToUInt32((Int32) requestData["start_region_x"]);
if (requestData.ContainsKey("start_region_y"))
regionYLocation = Convert.ToUInt32(requestData["start_region_y"]);
regionYLocation = Convert.ToUInt32((Int32) requestData["start_region_y"]);
// if (requestData.ContainsKey("start_lookat_x"))
// ulaX = Convert.ToUInt32((Int32) requestData["start_lookat_x"]);

View File

@@ -312,16 +312,14 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// Now that everything is setup we can proceed to
// add THIS agent to the HTTP server's handler list
// FIXME: If this code is ever to be re-enabled (most of it is disabled already) then this will
// have to be handled through the AddHttpHandler interface.
// if (!AddAgentHandler(Rest.Name,this))
// {
// Rest.Log.ErrorFormat("{0} Unable to activate handler interface", MsgId);
// foreach (IRest handler in handlers)
// {
// handler.Close();
// }
// }
if (!AddAgentHandler(Rest.Name,this))
{
Rest.Log.ErrorFormat("{0} Unable to activate handler interface", MsgId);
foreach (IRest handler in handlers)
{
handler.Close();
}
}
}
catch (Exception e)
@@ -344,13 +342,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
Rest.Log.InfoFormat("{0} Plugin is terminating", MsgId);
// FIXME: If this code is ever to be re-enabled (most of it is disabled already) then this will
// have to be handled through the AddHttpHandler interface.
// try
// {
// RemoveAgentHandler(Rest.Name, this);
// }
// catch (KeyNotFoundException){}
try
{
RemoveAgentHandler(Rest.Name, this);
}
catch (KeyNotFoundException){}
foreach (IRest handler in handlers)
{

View File

@@ -297,9 +297,7 @@ namespace OpenSim.ApplicationPlugins.Rest
{
if (!IsEnabled) return false;
_agents.Add(agentName, handler);
// return _httpd.AddAgentHandler(agentName, handler);
return false;
return _httpd.AddAgentHandler(agentName, handler);
}
/// <summary>
@@ -318,7 +316,7 @@ namespace OpenSim.ApplicationPlugins.Rest
if (_agents[agentName] == handler)
{
_agents.Remove(agentName);
// return _httpd.RemoveAgentHandler(agentName, handler);
return _httpd.RemoveAgentHandler(agentName, handler);
}
return false;
}
@@ -360,10 +358,10 @@ namespace OpenSim.ApplicationPlugins.Rest
_httpd.RemoveStreamHandler(h.HttpMethod, h.Path);
}
_handlers = null;
// foreach (KeyValuePair<string, IHttpAgentHandler> h in _agents)
// {
// _httpd.RemoveAgentHandler(h.Key, h.Value);
// }
foreach (KeyValuePair<string, IHttpAgentHandler> h in _agents)
{
_httpd.RemoveAgentHandler(h.Key, h.Value);
}
_agents = null;
}

View File

@@ -163,7 +163,7 @@ namespace OpenSim.Capabilities.Handlers
if (texture == null)
{
// m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
//m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
// Fetch locally or remotely. Misses return a 404
texture = m_assetService.Get(textureID.ToString());
@@ -197,7 +197,7 @@ namespace OpenSim.Capabilities.Handlers
}
else // it was on the cache
{
// m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
//m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
WriteTextureData(httpRequest, httpResponse, texture, format);
return true;
}
@@ -219,30 +219,12 @@ namespace OpenSim.Capabilities.Handlers
int start, end;
if (TryParseRange(range, out start, out end))
{
// Before clamping start make sure we can satisfy it in order to avoid
// sending back the last byte instead of an error status
if (start >= texture.Data.Length)
{
// m_log.DebugFormat(
// "[GETTEXTURE]: Client requested range for texture {0} starting at {1} but texture has end of {2}",
// texture.ID, start, texture.Data.Length);
// Stricly speaking, as per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, we should be sending back
// Requested Range Not Satisfiable (416) here. However, it appears that at least recent implementations
// of the Linden Lab viewer (3.2.1 and 3.3.4 and probably earlier), a viewer that has previously
// received a very small texture may attempt to fetch bytes from the server past the
// range of data that it received originally. Whether this happens appears to depend on whether
// the viewer's estimation of how large a request it needs to make for certain discard levels
// (http://wiki.secondlife.com/wiki/Image_System#Discard_Level_and_Mip_Mapping), chiefly discard
// level 2. If this estimate is greater than the total texture size, returning a RequestedRangeNotSatisfiable
// here will cause the viewer to treat the texture as bad and never display the full resolution
// However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length));
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
response.ContentType = texture.Metadata.ContentType;
response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
}
else
{
@@ -250,18 +232,12 @@ namespace OpenSim.Capabilities.Handlers
start = Utils.Clamp(start, 0, end);
int len = end - start + 1;
// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
// Always return PartialContent, even if the range covered the entire data length
// We were accidentally sending back 404 before in this situation
// https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
// entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
//
// We also do not want to send back OK even if the whole range was satisfiable since this causes
// HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality.
// if (end > maxEnd)
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
// else
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
response.ContentLength = len;

View File

@@ -116,22 +116,7 @@ namespace OpenSim.Data
/// <returns>true if the delete was successful, false if it was not</returns>
bool DeleteItems(string[] fields, string[] vals);
/// <summary>
/// Move an item to another folder.
/// </summary>
/// <returns>/returns>
/// <param name='id'>UUID of the item</param>
/// <param name='newParent'>UUID of the new parent folder.</param>
bool MoveItem(string id, string newParentFolderID);
/// <summary>
/// Move a folder to another folder.
/// </summary>
/// <returns>/returns>
/// <param name='id'>UUID of the item</param>
/// <param name='newParent'>UUID of the new parent folder.</param>
bool MoveFolder(string id, string newParentFolderID);
bool MoveItem(string id, string newParent);
XInventoryItem[] GetActiveGestures(UUID principalID);
int GetAssetPermissions(UUID principalID, UUID assetID);
}

View File

@@ -2202,5 +2202,18 @@ VALUES
}
}
}
public void SaveExtra(UUID regionID, string name, string value)
{
}
public void RemoveExtra(UUID regionID, string name)
{
}
public Dictionary<string, string> GetExtra(UUID regionID)
{
return null;
}
}
}

View File

@@ -43,12 +43,12 @@ namespace OpenSim.Data.MSSQL
// private static readonly ILog m_log = LogManager.GetLogger(
// MethodBase.GetCurrentMethod().DeclaringType);
private MSSQLFolderHandler m_Folders;
private MSSQLGenericTableHandler<XInventoryFolder> m_Folders;
private MSSQLItemHandler m_Items;
public MSSQLXInventoryData(string conn, string realm)
{
m_Folders = new MSSQLFolderHandler(
m_Folders = new MSSQLGenericTableHandler<XInventoryFolder>(
conn, "inventoryfolders", "InventoryStore");
m_Items = new MSSQLItemHandler(
conn, "inventoryitems", String.Empty);
@@ -85,7 +85,6 @@ namespace OpenSim.Data.MSSQL
{
return m_Folders.Delete(field, val);
}
public bool DeleteFolders(string[] fields, string[] vals)
{
return m_Folders.Delete(fields, vals);
@@ -95,22 +94,15 @@ namespace OpenSim.Data.MSSQL
{
return m_Items.Delete(field, val);
}
public bool DeleteItems(string[] fields, string[] vals)
{
return m_Items.Delete(fields, vals);
}
public bool MoveItem(string id, string newParent)
{
return m_Items.MoveItem(id, newParent);
}
public bool MoveFolder(string id, string newParent)
{
return m_Folders.MoveFolder(id, newParent);
}
public XInventoryItem[] GetActiveGestures(UUID principalID)
{
return m_Items.GetActiveGestures(principalID);
@@ -132,115 +124,79 @@ namespace OpenSim.Data.MSSQL
public bool MoveItem(string id, string newParent)
{
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
using (SqlCommand cmd = new SqlCommand())
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where inventoryID = @InventoryID", m_Realm);
cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParent));
cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id));
cmd.Connection = conn;
conn.Open();
return cmd.ExecuteNonQuery() == 0 ? false : true;
}
cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where inventoryID = @InventoryID", m_Realm);
cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParent));
cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id));
cmd.Connection = conn;
conn.Open();
return cmd.ExecuteNonQuery() == 0 ? false : true;
}
}
public XInventoryItem[] GetActiveGestures(UUID principalID)
{
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
using (SqlCommand cmd = new SqlCommand())
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm);
cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm);
cmd.Parameters.Add(m_database.CreateParameter("@uuid", principalID.ToString()));
cmd.Parameters.Add(m_database.CreateParameter("@type", (int)AssetType.Gesture));
cmd.Connection = conn;
conn.Open();
return DoQuery(cmd);
}
cmd.Parameters.Add(m_database.CreateParameter("@uuid", principalID.ToString()));
cmd.Parameters.Add(m_database.CreateParameter("@type", (int)AssetType.Gesture));
cmd.Connection = conn;
conn.Open();
return DoQuery(cmd);
}
}
public int GetAssetPermissions(UUID principalID, UUID assetID)
{
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
using (SqlCommand cmd = new SqlCommand())
{
using (SqlCommand cmd = new SqlCommand())
cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = @PrincipalID and assetID = @AssetID group by assetID", m_Realm);
cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
cmd.Parameters.Add(m_database.CreateParameter("@AssetID", assetID.ToString()));
cmd.Connection = conn;
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = @PrincipalID and assetID = @AssetID group by assetID", m_Realm);
cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
cmd.Parameters.Add(m_database.CreateParameter("@AssetID", assetID.ToString()));
cmd.Connection = conn;
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
int perms = 0;
if (reader.Read())
{
int perms = 0;
if (reader.Read())
{
perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]);
}
return perms;
perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]);
}
return perms;
}
}
}
public override bool Store(XInventoryItem item)
{
if (!base.Store(item))
return false;
string sql = "update inventoryfolders set version=version+1 where folderID = @folderID";
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
conn.Open();
conn.Open();
cmd.Parameters.AddWithValue("@folderID", item.parentFolderID.ToString());
try
{
cmd.ExecuteNonQuery();
}
catch (Exception)
{
return false;
}
}
return true;
cmd.Parameters.AddWithValue("@folderID", item.parentFolderID.ToString());
try
{
cmd.ExecuteNonQuery();
}
catch (Exception)
{
return false;
}
}
return true;
}
}
public class MSSQLFolderHandler : MSSQLGenericTableHandler<XInventoryFolder>
{
public MSSQLFolderHandler(string c, string t, string m) :
base(c, t, m)
{
}
public bool MoveFolder(string id, string newParentFolderID)
{
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where folderID = @folderID", m_Realm);
cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParentFolderID));
cmd.Parameters.Add(m_database.CreateParameter("@folderID", id));
cmd.Connection = conn;
conn.Open();
return cmd.ExecuteNonQuery() == 0 ? false : true;
}
}
}
}
}
}

View File

@@ -219,8 +219,6 @@ namespace OpenSim.Data.MySQL
public virtual bool Store(T row)
{
// m_log.DebugFormat("[MYSQL GENERIC TABLE HANDLER]: Store(T row) invoked");
using (MySqlCommand cmd = new MySqlCommand())
{
string query = "";
@@ -275,10 +273,6 @@ namespace OpenSim.Data.MySQL
public virtual bool Delete(string[] fields, string[] keys)
{
// m_log.DebugFormat(
// "[MYSQL GENERIC TABLE HANDLER]: Delete(string[] fields, string[] keys) invoked with {0}:{1}",
// string.Join(",", fields), string.Join(",", keys));
if (fields.Length != keys.Length)
return false;

View File

@@ -1985,5 +1985,74 @@ namespace OpenSim.Data.MySQL
}
}
}
public void SaveExtra(UUID regionID, string name, string val)
{
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
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();
}
}
}
}
public void RemoveExtra(UUID regionID, string name)
{
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
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();
}
}
}
}
public Dictionary<string, string> GetExtra(UUID regionID)
{
Dictionary<string, string> ret = new Dictionary<string, string>();
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "select * from regionextra where RegionID=?RegionID";
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
using (IDataReader r = cmd.ExecuteReader())
{
while (r.Read())
{
ret[r["Name"].ToString()] = r["value"].ToString();
}
}
}
}
}
return ret;
}
}
}

View File

@@ -26,10 +26,9 @@
*/
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using log4net;
using MySql.Data.MySqlClient;
using OpenMetaverse;
@@ -42,12 +41,12 @@ namespace OpenSim.Data.MySQL
/// </summary>
public class MySQLXInventoryData : IXInventoryData
{
private MySqlFolderHandler m_Folders;
private MySQLGenericTableHandler<XInventoryFolder> m_Folders;
private MySqlItemHandler m_Items;
public MySQLXInventoryData(string conn, string realm)
{
m_Folders = new MySqlFolderHandler(
m_Folders = new MySQLGenericTableHandler<XInventoryFolder>(
conn, "inventoryfolders", "InventoryStore");
m_Items = new MySqlItemHandler(
conn, "inventoryitems", String.Empty);
@@ -106,11 +105,6 @@ namespace OpenSim.Data.MySQL
return m_Items.MoveItem(id, newParent);
}
public bool MoveFolder(string id, string newParent)
{
return m_Folders.MoveFolder(id, newParent);
}
public XInventoryItem[] GetActiveGestures(UUID principalID)
{
return m_Items.GetActiveGestures(principalID);
@@ -124,69 +118,22 @@ namespace OpenSim.Data.MySQL
public class MySqlItemHandler : MySQLGenericTableHandler<XInventoryItem>
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public MySqlItemHandler(string c, string t, string m) :
base(c, t, m)
{
}
public override bool Delete(string field, string val)
{
XInventoryItem[] retrievedItems = Get(new string[] { field }, new string[] { val });
if (retrievedItems.Length == 0)
return false;
if (!base.Delete(field, val))
return false;
// Don't increment folder version here since Delete(string, string) calls Delete(string[], string[])
// IncrementFolderVersion(retrievedItems[0].parentFolderID);
return true;
}
public override bool Delete(string[] fields, string[] vals)
{
XInventoryItem[] retrievedItems = Get(fields, vals);
if (retrievedItems.Length == 0)
return false;
if (!base.Delete(fields, vals))
return false;
HashSet<UUID> deletedItemFolderUUIDs = new HashSet<UUID>();
Array.ForEach<XInventoryItem>(retrievedItems, i => deletedItemFolderUUIDs.Add(i.parentFolderID));
foreach (UUID deletedItemFolderUUID in deletedItemFolderUUIDs)
IncrementFolderVersion(deletedItemFolderUUID);
return true;
}
public bool MoveItem(string id, string newParent)
{
XInventoryItem[] retrievedItems = Get(new string[] { "inventoryID" }, new string[] { id });
if (retrievedItems.Length == 0)
return false;
UUID oldParent = retrievedItems[0].parentFolderID;
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("update {0} set parentFolderID = ?ParentFolderID where inventoryID = ?InventoryID", m_Realm);
cmd.Parameters.AddWithValue("?ParentFolderID", newParent);
cmd.Parameters.AddWithValue("?InventoryID", id);
if (ExecuteNonQuery(cmd) == 0)
return false;
return ExecuteNonQuery(cmd) == 0 ? false : true;
}
IncrementFolderVersion(oldParent);
IncrementFolderVersion(newParent);
return true;
}
public XInventoryItem[] GetActiveGestures(UUID principalID)
@@ -237,21 +184,6 @@ namespace OpenSim.Data.MySQL
if (!base.Store(item))
return false;
IncrementFolderVersion(item.parentFolderID);
return true;
}
private bool IncrementFolderVersion(UUID folderID)
{
return IncrementFolderVersion(folderID.ToString());
}
private bool IncrementFolderVersion(string folderID)
{
// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
// Util.PrintCallStack();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
@@ -261,7 +193,7 @@ namespace OpenSim.Data.MySQL
cmd.Connection = dbcon;
cmd.CommandText = String.Format("update inventoryfolders set version=version+1 where folderID = ?folderID");
cmd.Parameters.AddWithValue("?folderID", folderID);
cmd.Parameters.AddWithValue("?folderID", item.parentFolderID.ToString());
try
{
@@ -273,96 +205,9 @@ namespace OpenSim.Data.MySQL
}
cmd.Dispose();
}
dbcon.Close();
}
return true;
}
}
public class MySqlFolderHandler : MySQLGenericTableHandler<XInventoryFolder>
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public MySqlFolderHandler(string c, string t, string m) :
base(c, t, m)
{
}
public bool MoveFolder(string id, string newParentFolderID)
{
XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id });
if (folders.Length == 0)
return false;
UUID oldParentFolderUUID = folders[0].parentFolderID;
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText
= String.Format(
"update {0} set parentFolderID = ?ParentFolderID where folderID = ?folderID", m_Realm);
cmd.Parameters.AddWithValue("?ParentFolderID", newParentFolderID);
cmd.Parameters.AddWithValue("?folderID", id);
if (ExecuteNonQuery(cmd) == 0)
return false;
}
IncrementFolderVersion(oldParentFolderUUID);
IncrementFolderVersion(newParentFolderID);
return true;
}
public override bool Store(XInventoryFolder folder)
{
if (!base.Store(folder))
return false;
IncrementFolderVersion(folder.parentFolderID);
return true;
}
private bool IncrementFolderVersion(UUID folderID)
{
return IncrementFolderVersion(folderID.ToString());
}
private bool IncrementFolderVersion(string folderID)
{
// m_log.DebugFormat("[MYSQL FOLDER HANDLER]: Incrementing version on folder {0}", folderID);
// Util.PrintCallStack();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.Connection = dbcon;
cmd.CommandText = String.Format("update inventoryfolders set version=version+1 where folderID = ?folderID");
cmd.Parameters.AddWithValue("?folderID", folderID);
try
{
cmd.ExecuteNonQuery();
}
catch (Exception)
{
return false;
}
cmd.Dispose();
}
dbcon.Close();
}
return true;
}
}
}
}

View File

@@ -895,3 +895,10 @@ CREATE TABLE `regionenvironment` (
COMMIT;
:VERSION 45
BEGIN;
CREATE TABLE `regionextra` (`RegionID` char(36) not null, `Name` varchar(32) not null, `value` text, primary key(`RegionID`, `Name`));
COMMIT;

View File

@@ -151,5 +151,18 @@ namespace OpenSim.Data.Null
public void Shutdown()
{
}
public void SaveExtra(UUID regionID, string name, string value)
{
}
public void RemoveExtra(UUID regionID, string name)
{
}
public Dictionary<string, string> GetExtra(UUID regionID)
{
return null;
}
}
}

View File

@@ -202,8 +202,7 @@ namespace OpenSim.Data.SQLite
/// <returns>True if exist, or false.</returns>
override public bool ExistsAsset(UUID uuid)
{
lock (this)
{
lock (this) {
using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn))
{
cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
@@ -354,13 +353,12 @@ namespace OpenSim.Data.SQLite
{
lock (this)
{
using (SqliteCommand cmd = new SqliteCommand(DeleteAssetSQL, m_conn))
{
cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
cmd.ExecuteNonQuery();
}
using (SqliteCommand cmd = new SqliteCommand(DeleteAssetSQL, m_conn))
{
cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
cmd.ExecuteNonQuery();
}
}
return true;
}

View File

@@ -82,14 +82,11 @@ namespace OpenSim.Data.SQLite
{
AuthenticationData ret = new AuthenticationData();
ret.Data = new Dictionary<string, object>();
IDataReader result;
using (SqliteCommand cmd = new SqliteCommand("select * from `" + m_Realm + "` where UUID = :PrincipalID"))
{
cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString()));
SqliteCommand cmd = new SqliteCommand("select * from `" + m_Realm + "` where UUID = :PrincipalID");
cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString()));
result = ExecuteReader(cmd, m_Connection);
}
IDataReader result = ExecuteReader(cmd, m_Connection);
try
{
@@ -124,6 +121,10 @@ namespace OpenSim.Data.SQLite
catch
{
}
finally
{
//CloseCommand(cmd);
}
return null;
}
@@ -139,81 +140,84 @@ namespace OpenSim.Data.SQLite
foreach (object o in data.Data.Values)
values[i++] = o.ToString();
using (SqliteCommand cmd = new SqliteCommand())
SqliteCommand cmd = new SqliteCommand();
if (Get(data.PrincipalID) != null)
{
if (Get(data.PrincipalID) != null)
string update = "update `" + m_Realm + "` set ";
bool first = true;
foreach (string field in fields)
{
if (!first)
update += ", ";
update += "`" + field + "` = :" + field;
cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field]));
first = false;
}
string update = "update `" + m_Realm + "` set ";
bool first = true;
foreach (string field in fields)
update += " where UUID = :UUID";
cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString()));
cmd.CommandText = update;
try
{
if (ExecuteNonQuery(cmd, m_Connection) < 1)
{
if (!first)
update += ", ";
update += "`" + field + "` = :" + field;
cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field]));
first = false;
}
update += " where UUID = :UUID";
cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString()));
cmd.CommandText = update;
try
{
if (ExecuteNonQuery(cmd, m_Connection) < 1)
{
//CloseCommand(cmd);
return false;
}
}
catch (Exception e)
{
m_log.Error("[SQLITE]: Exception storing authentication data", e);
//CloseCommand(cmd);
return false;
}
}
else
catch (Exception e)
{
string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
String.Join("`, `", fields) +
"`) values (:UUID, :" + String.Join(", :", fields) + ")";
m_log.Error("[SQLITE]: Exception storing authentication data", e);
//CloseCommand(cmd);
return false;
}
}
cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString()));
foreach (string field in fields)
cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field]));
else
{
string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
String.Join("`, `", fields) +
"`) values (:UUID, :" + String.Join(", :", fields) + ")";
cmd.CommandText = insert;
cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString()));
foreach (string field in fields)
cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field]));
try
cmd.CommandText = insert;
try
{
if (ExecuteNonQuery(cmd, m_Connection) < 1)
{
if (ExecuteNonQuery(cmd, m_Connection) < 1)
{
return false;
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
//CloseCommand(cmd);
return false;
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
//CloseCommand(cmd);
return false;
}
}
//CloseCommand(cmd);
return true;
}
public bool SetDataItem(UUID principalID, string item, string value)
{
using (SqliteCommand cmd = new SqliteCommand("update `" + m_Realm +
"` set `" + item + "` = " + value + " where UUID = '" + principalID.ToString() + "'"))
{
if (ExecuteNonQuery(cmd, m_Connection) > 0)
return true;
}
SqliteCommand cmd = new SqliteCommand("update `" + m_Realm +
"` set `" + item + "` = " + value + " where UUID = '" + principalID.ToString() + "'");
if (ExecuteNonQuery(cmd, m_Connection) > 0)
return true;
return false;
}
@@ -223,13 +227,16 @@ namespace OpenSim.Data.SQLite
if (System.Environment.TickCount - m_LastExpire > 30000)
DoExpire();
using (SqliteCommand cmd = new SqliteCommand("insert into tokens (UUID, token, validity) values ('" + principalID.ToString() +
"', '" + token + "', datetime('now', 'localtime', '+" + lifetime.ToString() + " minutes'))"))
SqliteCommand cmd = new SqliteCommand("insert into tokens (UUID, token, validity) values ('" + principalID.ToString() +
"', '" + token + "', datetime('now', 'localtime', '+" + lifetime.ToString() + " minutes'))");
if (ExecuteNonQuery(cmd, m_Connection) > 0)
{
if (ExecuteNonQuery(cmd, m_Connection) > 0)
return true;
cmd.Dispose();
return true;
}
cmd.Dispose();
return false;
}
@@ -238,22 +245,28 @@ namespace OpenSim.Data.SQLite
if (System.Environment.TickCount - m_LastExpire > 30000)
DoExpire();
using (SqliteCommand cmd = new SqliteCommand("update tokens set validity = datetime('now', 'localtime', '+" + lifetime.ToString() +
" minutes') where UUID = '" + principalID.ToString() + "' and token = '" + token + "' and validity > datetime('now', 'localtime')"))
SqliteCommand cmd = new SqliteCommand("update tokens set validity = datetime('now', 'localtime', '+" + lifetime.ToString() +
" minutes') where UUID = '" + principalID.ToString() + "' and token = '" + token + "' and validity > datetime('now', 'localtime')");
if (ExecuteNonQuery(cmd, m_Connection) > 0)
{
if (ExecuteNonQuery(cmd, m_Connection) > 0)
return true;
cmd.Dispose();
return true;
}
cmd.Dispose();
return false;
}
private void DoExpire()
{
using (SqliteCommand cmd = new SqliteCommand("delete from tokens where validity < datetime('now', 'localtime')"))
ExecuteNonQuery(cmd, m_Connection);
SqliteCommand cmd = new SqliteCommand("delete from tokens where validity < datetime('now', 'localtime')");
ExecuteNonQuery(cmd, m_Connection);
cmd.Dispose();
m_LastExpire = System.Environment.TickCount;
}
}
}
}

View File

@@ -56,17 +56,23 @@ namespace OpenSim.Data.SQLite
public bool Delete(UUID principalID, string name)
{
using (SqliteCommand cmd = new SqliteCommand())
{
cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = :PrincipalID and `Name` = :Name", m_Realm);
cmd.Parameters.AddWithValue(":PrincipalID", principalID.ToString());
cmd.Parameters.AddWithValue(":Name", name);
SqliteCommand cmd = new SqliteCommand();
cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = :PrincipalID and `Name` = :Name", m_Realm);
cmd.Parameters.AddWithValue(":PrincipalID", principalID.ToString());
cmd.Parameters.AddWithValue(":Name", name);
try
{
if (ExecuteNonQuery(cmd, m_Connection) > 0)
return true;
}
return false;
return false;
}
finally
{
//CloseCommand(cmd);
}
}
}
}
}

View File

@@ -104,13 +104,12 @@ namespace OpenSim.Data.SQLite
{
string sql = "select estate_settings."+String.Join(",estate_settings.", FieldList)+" from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = :RegionID";
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
return DoLoad(cmd, regionID, create);
}
cmd.CommandText = sql;
cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
return DoLoad(cmd, regionID, create);
}
private EstateSettings DoLoad(SqliteCommand cmd, UUID regionID, bool create)
@@ -187,40 +186,38 @@ namespace OpenSim.Data.SQLite
{
List<string> names = new List<string>(FieldList);
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
IDataReader r = null;
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
names.Remove("EstateID");
names.Remove("EstateID");
string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")";
string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")";
cmd.CommandText = sql;
cmd.Parameters.Clear();
cmd.CommandText = sql;
cmd.Parameters.Clear();
foreach (string name in FieldList)
foreach (string name in FieldList)
{
if (m_FieldMap[name].GetValue(es) is bool)
{
if (m_FieldMap[name].GetValue(es) is bool)
{
if ((bool)m_FieldMap[name].GetValue(es))
cmd.Parameters.AddWithValue(":"+name, "1");
else
cmd.Parameters.AddWithValue(":"+name, "0");
}
if ((bool)m_FieldMap[name].GetValue(es))
cmd.Parameters.AddWithValue(":"+name, "1");
else
{
cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString());
}
cmd.Parameters.AddWithValue(":"+name, "0");
}
else
{
cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString());
}
cmd.ExecuteNonQuery();
cmd.CommandText = "select LAST_INSERT_ROWID() as id";
cmd.Parameters.Clear();
r = cmd.ExecuteReader();
}
cmd.ExecuteNonQuery();
cmd.CommandText = "select LAST_INSERT_ROWID() as id";
cmd.Parameters.Clear();
r = cmd.ExecuteReader();
r.Read();
es.EstateID = Convert.ToUInt32(r["id"]);
@@ -242,28 +239,27 @@ namespace OpenSim.Data.SQLite
string sql = "update estate_settings set "+String.Join(", ", terms.ToArray())+" where EstateID = :EstateID";
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
cmd.CommandText = sql;
foreach (string name in FieldList)
{
cmd.CommandText = sql;
foreach (string name in FieldList)
if (m_FieldMap[name].GetValue(es) is bool)
{
if (m_FieldMap[name].GetValue(es) is bool)
{
if ((bool)m_FieldMap[name].GetValue(es))
cmd.Parameters.AddWithValue(":"+name, "1");
else
cmd.Parameters.AddWithValue(":"+name, "0");
}
if ((bool)m_FieldMap[name].GetValue(es))
cmd.Parameters.AddWithValue(":"+name, "1");
else
{
cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString());
}
cmd.Parameters.AddWithValue(":"+name, "0");
}
else
{
cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString());
}
cmd.ExecuteNonQuery();
}
cmd.ExecuteNonQuery();
SaveBanList(es);
SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers);
SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess);
@@ -274,15 +270,12 @@ namespace OpenSim.Data.SQLite
{
es.ClearBans();
IDataReader r;
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = "select bannedUUID from estateban where EstateID = :EstateID";
cmd.Parameters.AddWithValue(":EstateID", es.EstateID);
cmd.CommandText = "select bannedUUID from estateban where EstateID = :EstateID";
cmd.Parameters.AddWithValue(":EstateID", es.EstateID);
r = cmd.ExecuteReader();
}
IDataReader r = cmd.ExecuteReader();
while (r.Read())
{
@@ -301,64 +294,60 @@ namespace OpenSim.Data.SQLite
private void SaveBanList(EstateSettings es)
{
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
cmd.CommandText = "delete from estateban where EstateID = :EstateID";
cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString());
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( :EstateID, :bannedUUID, '', '', '' )";
foreach (EstateBan b in es.EstateBans)
{
cmd.CommandText = "delete from estateban where EstateID = :EstateID";
cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString());
cmd.Parameters.AddWithValue(":bannedUUID", b.BannedUserID.ToString());
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( :EstateID, :bannedUUID, '', '', '' )";
foreach (EstateBan b in es.EstateBans)
{
cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString());
cmd.Parameters.AddWithValue(":bannedUUID", b.BannedUserID.ToString());
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
}
}
void SaveUUIDList(uint EstateID, string table, UUID[] data)
{
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
cmd.CommandText = "delete from "+table+" where EstateID = :EstateID";
cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString());
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
cmd.CommandText = "insert into "+table+" (EstateID, uuid) values ( :EstateID, :uuid )";
foreach (UUID uuid in data)
{
cmd.CommandText = "delete from "+table+" where EstateID = :EstateID";
cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString());
cmd.Parameters.AddWithValue(":uuid", uuid.ToString());
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
cmd.CommandText = "insert into "+table+" (EstateID, uuid) values ( :EstateID, :uuid )";
foreach (UUID uuid in data)
{
cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString());
cmd.Parameters.AddWithValue(":uuid", uuid.ToString());
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
}
}
UUID[] LoadUUIDList(uint EstateID, string table)
{
List<UUID> uuids = new List<UUID>();
IDataReader r;
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = "select uuid from "+table+" where EstateID = :EstateID";
cmd.Parameters.AddWithValue(":EstateID", EstateID);
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
r = cmd.ExecuteReader();
}
cmd.CommandText = "select uuid from "+table+" where EstateID = :EstateID";
cmd.Parameters.AddWithValue(":EstateID", EstateID);
IDataReader r = cmd.ExecuteReader();
while (r.Read())
{
@@ -378,13 +367,12 @@ namespace OpenSim.Data.SQLite
{
string sql = "select estate_settings."+String.Join(",estate_settings.", FieldList)+" from estate_settings where estate_settings.EstateID = :EstateID";
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddWithValue(":EstateID", estateID.ToString());
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
return DoLoad(cmd, UUID.Zero, false);
}
cmd.CommandText = sql;
cmd.Parameters.AddWithValue(":EstateID", estateID.ToString());
return DoLoad(cmd, UUID.Zero, false);
}
public List<EstateSettings> LoadEstateSettingsAll()
@@ -403,15 +391,13 @@ namespace OpenSim.Data.SQLite
List<int> result = new List<int>();
string sql = "select EstateID from estate_settings where estate_settings.EstateName = :EstateName";
IDataReader r;
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddWithValue(":EstateName", search);
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
r = cmd.ExecuteReader();
}
cmd.CommandText = sql;
cmd.Parameters.AddWithValue(":EstateName", search);
IDataReader r = cmd.ExecuteReader();
while (r.Read())
{
@@ -427,14 +413,12 @@ namespace OpenSim.Data.SQLite
List<int> result = new List<int>();
string sql = "select EstateID from estate_settings";
IDataReader r;
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = sql;
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
r = cmd.ExecuteReader();
}
cmd.CommandText = sql;
IDataReader r = cmd.ExecuteReader();
while (r.Read())
{
@@ -450,15 +434,13 @@ namespace OpenSim.Data.SQLite
List<int> result = new List<int>();
string sql = "select EstateID from estate_settings where estate_settings.EstateOwner = :EstateOwner";
IDataReader r;
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddWithValue(":EstateOwner", ownerID);
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
r = cmd.ExecuteReader();
}
cmd.CommandText = sql;
cmd.Parameters.AddWithValue(":EstateOwner", ownerID);
IDataReader r = cmd.ExecuteReader();
while (r.Read())
{

View File

@@ -90,5 +90,12 @@ namespace OpenSim.Data.SQLite
return cmd.ExecuteReader();
}
}
protected void CloseCommand(SqliteCommand cmd)
{
cmd.Connection.Close();
cmd.Connection.Dispose();
cmd.Dispose();
}
}
}
}

View File

@@ -53,13 +53,13 @@ namespace OpenSim.Data.SQLite
public FriendsData[] GetFriends(string userID)
{
using (SqliteCommand cmd = new SqliteCommand())
{
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = :PrincipalID", m_Realm);
cmd.Parameters.AddWithValue(":PrincipalID", userID.ToString());
SqliteCommand cmd = new SqliteCommand();
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = :PrincipalID", m_Realm);
cmd.Parameters.AddWithValue(":PrincipalID", userID.ToString());
return DoQuery(cmd);
return DoQuery(cmd);
}
}
public bool Delete(UUID principalID, string friend)
@@ -69,14 +69,13 @@ namespace OpenSim.Data.SQLite
public bool Delete(string principalID, string friend)
{
using (SqliteCommand cmd = new SqliteCommand())
{
cmd.CommandText = String.Format("delete from {0} where PrincipalID = :PrincipalID and Friend = :Friend", m_Realm);
cmd.Parameters.AddWithValue(":PrincipalID", principalID.ToString());
cmd.Parameters.AddWithValue(":Friend", friend);
SqliteCommand cmd = new SqliteCommand();
ExecuteNonQuery(cmd, m_Connection);
}
cmd.CommandText = String.Format("delete from {0} where PrincipalID = :PrincipalID and Friend = :Friend", m_Realm);
cmd.Parameters.AddWithValue(":PrincipalID", principalID.ToString());
cmd.Parameters.AddWithValue(":Friend", friend);
ExecuteNonQuery(cmd, m_Connection);
return true;
}

View File

@@ -132,23 +132,22 @@ namespace OpenSim.Data.SQLite
List<string> terms = new List<string>();
using (SqliteCommand cmd = new SqliteCommand())
SqliteCommand cmd = new SqliteCommand();
for (int i = 0 ; i < fields.Length ; i++)
{
for (int i = 0 ; i < fields.Length ; i++)
{
cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i]));
terms.Add("`" + fields[i] + "` = :" + fields[i]);
}
string where = String.Join(" and ", terms.ToArray());
string query = String.Format("select * from {0} where {1}",
m_Realm, where);
cmd.CommandText = query;
return DoQuery(cmd);
cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i]));
terms.Add("`" + fields[i] + "` = :" + fields[i]);
}
string where = String.Join(" and ", terms.ToArray());
string query = String.Format("select * from {0} where {1}",
m_Realm, where);
cmd.CommandText = query;
return DoQuery(cmd);
}
protected T[] DoQuery(SqliteCommand cmd)
@@ -215,53 +214,51 @@ namespace OpenSim.Data.SQLite
public T[] Get(string where)
{
using (SqliteCommand cmd = new SqliteCommand())
{
string query = String.Format("select * from {0} where {1}",
m_Realm, where);
SqliteCommand cmd = new SqliteCommand();
cmd.CommandText = query;
string query = String.Format("select * from {0} where {1}",
m_Realm, where);
return DoQuery(cmd);
}
cmd.CommandText = query;
return DoQuery(cmd);
}
public bool Store(T row)
{
using (SqliteCommand cmd = new SqliteCommand())
SqliteCommand cmd = new SqliteCommand();
string query = "";
List<String> names = new List<String>();
List<String> values = new List<String>();
foreach (FieldInfo fi in m_Fields.Values)
{
string query = "";
List<String> names = new List<String>();
List<String> values = new List<String>();
foreach (FieldInfo fi in m_Fields.Values)
{
names.Add(fi.Name);
values.Add(":" + fi.Name);
cmd.Parameters.Add(new SqliteParameter(":" + fi.Name, fi.GetValue(row).ToString()));
}
if (m_DataField != null)
{
Dictionary<string, string> data =
(Dictionary<string, string>)m_DataField.GetValue(row);
foreach (KeyValuePair<string, string> kvp in data)
{
names.Add(kvp.Key);
values.Add(":" + kvp.Key);
cmd.Parameters.Add(new SqliteParameter(":" + kvp.Key, kvp.Value));
}
}
query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values (" + String.Join(",", values.ToArray()) + ")";
cmd.CommandText = query;
if (ExecuteNonQuery(cmd, m_Connection) > 0)
return true;
names.Add(fi.Name);
values.Add(":" + fi.Name);
cmd.Parameters.Add(new SqliteParameter(":" + fi.Name, fi.GetValue(row).ToString()));
}
if (m_DataField != null)
{
Dictionary<string, string> data =
(Dictionary<string, string>)m_DataField.GetValue(row);
foreach (KeyValuePair<string, string> kvp in data)
{
names.Add(kvp.Key);
values.Add(":" + kvp.Key);
cmd.Parameters.Add(new SqliteParameter(":" + kvp.Key, kvp.Value));
}
}
query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values (" + String.Join(",", values.ToArray()) + ")";
cmd.CommandText = query;
if (ExecuteNonQuery(cmd, m_Connection) > 0)
return true;
return false;
}
@@ -277,22 +274,21 @@ namespace OpenSim.Data.SQLite
List<string> terms = new List<string>();
using (SqliteCommand cmd = new SqliteCommand())
SqliteCommand cmd = new SqliteCommand();
for (int i = 0 ; i < fields.Length ; i++)
{
for (int i = 0 ; i < fields.Length ; i++)
{
cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i]));
terms.Add("`" + fields[i] + "` = :" + fields[i]);
}
string where = String.Join(" and ", terms.ToArray());
string query = String.Format("delete from {0} where {1}", m_Realm, where);
cmd.CommandText = query;
return ExecuteNonQuery(cmd, m_Connection) > 0;
cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i]));
terms.Add("`" + fields[i] + "` = :" + fields[i]);
}
string where = String.Join(" and ", terms.ToArray());
string query = String.Format("delete from {0} where {1}", m_Realm, where);
cmd.CommandText = query;
return ExecuteNonQuery(cmd, m_Connection) > 0;
}
}
}

View File

@@ -1366,13 +1366,6 @@ namespace OpenSim.Data.SQLite
createCol(land, "UserLookAtZ", typeof(Double));
createCol(land, "AuthbuyerID", typeof(String));
createCol(land, "OtherCleanTime", typeof(Int32));
createCol(land, "Dwell", typeof(Int32));
createCol(land, "MediaType", typeof(String));
createCol(land, "MediaDescription", typeof(String));
createCol(land, "MediaSize", typeof(String));
createCol(land, "MediaLoop", typeof(Boolean));
createCol(land, "ObscureMedia", typeof(Boolean));
createCol(land, "ObscureMusic", typeof(Boolean));
land.PrimaryKey = new DataColumn[] { land.Columns["UUID"] };
@@ -1788,16 +1781,9 @@ namespace OpenSim.Data.SQLite
newData.PassHours = Convert.ToSingle(row["PassHours"]);
newData.PassPrice = Convert.ToInt32(row["PassPrice"]);
newData.SnapshotID = (UUID)(String)row["SnapshotUUID"];
newData.Dwell = Convert.ToInt32(row["Dwell"]);
newData.MediaType = (String)row["MediaType"];
newData.MediaDescription = (String)row["MediaDescription"];
newData.MediaWidth = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[0]);
newData.MediaHeight = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[1]);
newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]);
newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]);
newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]);
try
{
newData.UserLocation =
new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]),
Convert.ToSingle(row["UserLocationZ"]));
@@ -2209,13 +2195,12 @@ namespace OpenSim.Data.SQLite
row["UserLookAtZ"] = land.UserLookAt.Z;
row["AuthbuyerID"] = land.AuthBuyerID.ToString();
row["OtherCleanTime"] = land.OtherCleanTime;
row["Dwell"] = land.Dwell;
row["MediaType"] = land.MediaType;
row["MediaDescription"] = land.MediaDescription;
row["MediaSize"] = String.Format("{0},{1}", land.MediaWidth, land.MediaHeight);
row["MediaLoop"] = land.MediaLoop;
row["ObscureMusic"] = land.ObscureMusic;
row["ObscureMedia"] = land.ObscureMedia;
row["MediaSize"] = land.MediaWidth.ToString() + "," + land.MediaHeight.ToString();
row["MediaLoop"] = land.MediaLoop.ToString();
row["ObscureMusic"] = land.ObscureMusic.ToString();
row["ObscureMedia"] = land.ObscureMedia.ToString();
}
/// <summary>
@@ -2905,5 +2890,17 @@ namespace OpenSim.Data.SQLite
}
}
public void SaveExtra(UUID regionID, string name, string value)
{
}
public void RemoveExtra(UUID regionID, string name)
{
}
public Dictionary<string, string> GetExtra(UUID regionID)
{
return null;
}
}
}

View File

@@ -66,21 +66,20 @@ namespace OpenSim.Data.SQLite
if (words.Length > 2)
return new UserAccountData[0];
using (SqliteCommand cmd = new SqliteCommand())
{
if (words.Length == 1)
{
cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{2}%')",
m_Realm, scopeID.ToString(), words[0]);
}
else
{
cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{3}%')",
m_Realm, scopeID.ToString(), words[0], words[1]);
}
SqliteCommand cmd = new SqliteCommand();
return DoQuery(cmd);
if (words.Length == 1)
{
cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{2}%')",
m_Realm, scopeID.ToString(), words[0]);
}
else
{
cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{3}%')",
m_Realm, scopeID.ToString(), words[0], words[1]);
}
return DoQuery(cmd);
}
}
}

View File

@@ -47,7 +47,7 @@ namespace OpenSim.Data.SQLite
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private SqliteFolderHandler m_Folders;
private SQLiteGenericTableHandler<XInventoryFolder> m_Folders;
private SqliteItemHandler m_Items;
public SQLiteXInventoryData(string conn, string realm)
@@ -55,7 +55,7 @@ namespace OpenSim.Data.SQLite
if (Util.IsWindows())
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
m_Folders = new SqliteFolderHandler(
m_Folders = new SQLiteGenericTableHandler<XInventoryFolder>(
conn, "inventoryfolders", "XInventoryStore");
m_Items = new SqliteItemHandler(
conn, "inventoryitems", String.Empty);
@@ -114,11 +114,6 @@ namespace OpenSim.Data.SQLite
return m_Items.MoveItem(id, newParent);
}
public bool MoveFolder(string id, string newParent)
{
return m_Folders.MoveFolder(id, newParent);
}
public XInventoryItem[] GetActiveGestures(UUID principalID)
{
return m_Items.GetActiveGestures(principalID);
@@ -139,41 +134,35 @@ namespace OpenSim.Data.SQLite
public bool MoveItem(string id, string newParent)
{
using (SqliteCommand cmd = new SqliteCommand())
{
cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where inventoryID = :InventoryID", m_Realm);
cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent));
cmd.Parameters.Add(new SqliteParameter(":InventoryID", id));
SqliteCommand cmd = new SqliteCommand();
return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true;
}
cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where inventoryID = :InventoryID", m_Realm);
cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent));
cmd.Parameters.Add(new SqliteParameter(":InventoryID", id));
return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true;
}
public XInventoryItem[] GetActiveGestures(UUID principalID)
{
using (SqliteCommand cmd = new SqliteCommand())
{
cmd.CommandText = String.Format("select * from inventoryitems where avatarId = :uuid and assetType = :type and flags = 1", m_Realm);
SqliteCommand cmd = new SqliteCommand();
cmd.CommandText = String.Format("select * from inventoryitems where avatarId = :uuid and assetType = :type and flags = 1", m_Realm);
cmd.Parameters.Add(new SqliteParameter(":uuid", principalID.ToString()));
cmd.Parameters.Add(new SqliteParameter(":type", (int)AssetType.Gesture));
cmd.Parameters.Add(new SqliteParameter(":uuid", principalID.ToString()));
cmd.Parameters.Add(new SqliteParameter(":type", (int)AssetType.Gesture));
return DoQuery(cmd);
}
return DoQuery(cmd);
}
public int GetAssetPermissions(UUID principalID, UUID assetID)
{
IDataReader reader;
SqliteCommand cmd = new SqliteCommand();
using (SqliteCommand cmd = new SqliteCommand())
{
cmd.CommandText = String.Format("select inventoryCurrentPermissions from inventoryitems where avatarID = :PrincipalID and assetID = :AssetID", m_Realm);
cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString()));
cmd.Parameters.Add(new SqliteParameter(":AssetID", assetID.ToString()));
cmd.CommandText = String.Format("select inventoryCurrentPermissions from inventoryitems where avatarID = :PrincipalID and assetID = :AssetID", m_Realm);
cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString()));
cmd.Parameters.Add(new SqliteParameter(":AssetID", assetID.ToString()));
reader = ExecuteReader(cmd, m_Connection);
}
IDataReader reader = ExecuteReader(cmd, m_Connection);
int perms = 0;
@@ -188,24 +177,4 @@ namespace OpenSim.Data.SQLite
return perms;
}
}
public class SqliteFolderHandler : SQLiteGenericTableHandler<XInventoryFolder>
{
public SqliteFolderHandler(string c, string t, string m) :
base(c, t, m)
{
}
public bool MoveFolder(string id, string newParentFolderID)
{
using (SqliteCommand cmd = new SqliteCommand())
{
cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where folderID = :FolderID", m_Realm);
cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParentFolderID));
cmd.Parameters.Add(new SqliteParameter(":FolderID", id));
return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true;
}
}
}
}
}

View File

@@ -330,9 +330,6 @@ namespace OpenSim.Framework
SetVisualParams(visualParams);
}
/// <summary>
/// Set avatar height by a calculation based on their visual parameters.
/// </summary>
public virtual void SetHeight()
{
// Start with shortest possible female avatar height

View File

@@ -33,8 +33,7 @@ namespace OpenSim.Framework.Client
{
event ChatMessage OnChatFromClient;
void SendChatMessage(
string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, UUID ownerID, byte source,
byte audible);
void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, byte source,
byte audible);
}
}
}

View File

@@ -678,6 +678,8 @@ namespace OpenSim.Framework.Console
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public event OnOutputDelegate OnOutput;
public ICommands Commands { get; private set; }
public CommandConsole(string defaultPrompt) : base(defaultPrompt)
@@ -697,6 +699,13 @@ namespace OpenSim.Framework.Console
Output(s);
}
protected void FireOnOutput(string text)
{
OnOutputDelegate onOutput = OnOutput;
if (onOutput != null)
onOutput(text);
}
/// <summary>
/// Display a command prompt on the console and wait for user input
/// </summary>

View File

@@ -1,209 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using log4net;
using OpenMetaverse;
namespace OpenSim.Framework.Console
{
public class ConsoleUtil
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public const int LocalIdNotFound = 0;
/// <summary>
/// Used by modules to display stock co-ordinate help, though possibly this should be under some general section
/// rather than in each help summary.
/// </summary>
public const string CoordHelp
= @"Each component of the coord is comma separated. There must be no spaces between the commas.
If you don't care about the z component you can simply omit it.
If you don't care about the x or y components then you can leave them blank (though a comma is still required)
If you want to specify the maxmimum value of a component then you can use ~ instead of a number
If you want to specify the minimum value of a component then you can use -~ instead of a number
e.g.
delete object pos 20,20,20 to 40,40,40
delete object pos 20,20 to 40,40
delete object pos ,20,20 to ,40,40
delete object pos ,,30 to ,,~
delete object pos ,,-~ to ,,30";
public const string MinRawConsoleVectorValue = "-~";
public const string MaxRawConsoleVectorValue = "~";
public const string VectorSeparator = ",";
public static char[] VectorSeparatorChars = VectorSeparator.ToCharArray();
/// <summary>
/// Try to parse a console UUID from the console.
/// </summary>
/// <remarks>
/// Will complain to the console if parsing fails.
/// </remarks>
/// <returns></returns>
/// <param name='console'>If null then no complaint is printed.</param>
/// <param name='rawUuid'></param>
/// <param name='uuid'></param>
public static bool TryParseConsoleUuid(ICommandConsole console, string rawUuid, out UUID uuid)
{
if (!UUID.TryParse(rawUuid, out uuid))
{
if (console != null)
console.OutputFormat("{0} is not a valid uuid", rawUuid);
return false;
}
return true;
}
public static bool TryParseConsoleLocalId(ICommandConsole console, string rawLocalId, out uint localId)
{
if (!uint.TryParse(rawLocalId, out localId))
{
if (console != null)
console.OutputFormat("{0} is not a valid local id", localId);
return false;
}
if (localId == 0)
{
if (console != null)
console.OutputFormat("{0} is not a valid local id - it must be greater than 0", localId);
return false;
}
return true;
}
/// <summary>
/// Tries to parse the input as either a UUID or a local ID.
/// </summary>
/// <returns>true if parsing succeeded, false otherwise.</returns>
/// <param name='console'></param>
/// <param name='rawId'></param>
/// <param name='uuid'></param>
/// <param name='localId'>
/// Will be set to ConsoleUtil.LocalIdNotFound if parsing result was a UUID or no parse succeeded.
/// </param>
public static bool TryParseConsoleId(ICommandConsole console, string rawId, out UUID uuid, out uint localId)
{
if (TryParseConsoleUuid(null, rawId, out uuid))
{
localId = LocalIdNotFound;
return true;
}
if (TryParseConsoleLocalId(null, rawId, out localId))
{
return true;
}
if (console != null)
console.OutputFormat("{0} is not a valid UUID or local id", rawId);
return false;
}
/// <summary>
/// Convert a minimum vector input from the console to an OpenMetaverse.Vector3
/// </summary>
/// <param name='rawConsoleVector'>/param>
/// <param name='vector'></param>
/// <returns></returns>
public static bool TryParseConsoleMinVector(string rawConsoleVector, out Vector3 vector)
{
return TryParseConsoleVector(rawConsoleVector, c => float.MinValue.ToString(), out vector);
}
/// <summary>
/// Convert a maximum vector input from the console to an OpenMetaverse.Vector3
/// </summary>
/// <param name='rawConsoleVector'>/param>
/// <param name='vector'></param>
/// <returns></returns>
public static bool TryParseConsoleMaxVector(string rawConsoleVector, out Vector3 vector)
{
return TryParseConsoleVector(rawConsoleVector, c => float.MaxValue.ToString(), out vector);
}
/// <summary>
/// Convert a vector input from the console to an OpenMetaverse.Vector3
/// </summary>
/// <param name='rawConsoleVector'>
/// A string in the form <x>,<y>,<z> where there is no space between values.
/// Any component can be missing (e.g. ,,40). blankComponentFunc is invoked to replace the blank with a suitable value
/// Also, if the blank component is at the end, then the comma can be missed off entirely (e.g. 40,30 or 40)
/// The strings "~" and "-~" are valid in components. The first substitutes float.MaxValue whilst the second is float.MinValue
/// Other than that, component values must be numeric.
/// </param>
/// <param name='blankComponentFunc'></param>
/// <param name='vector'></param>
/// <returns></returns>
public static bool TryParseConsoleVector(
string rawConsoleVector, Func<string, string> blankComponentFunc, out Vector3 vector)
{
List<string> components = rawConsoleVector.Split(VectorSeparatorChars).ToList();
if (components.Count < 1 || components.Count > 3)
{
vector = Vector3.Zero;
return false;
}
for (int i = components.Count; i < 3; i++)
components.Add("");
List<string> semiDigestedComponents
= components.ConvertAll<string>(
c =>
{
if (c == "")
return blankComponentFunc.Invoke(c);
else if (c == MaxRawConsoleVectorValue)
return float.MaxValue.ToString();
else if (c == MinRawConsoleVectorValue)
return float.MinValue.ToString();
else
return c;
});
string semiDigestedConsoleVector = string.Join(VectorSeparator, semiDigestedComponents.ToArray());
// m_log.DebugFormat("[CONSOLE UTIL]: Parsing {0} into OpenMetaverse.Vector3", semiDigestedConsoleVector);
return Vector3.TryParse(semiDigestedConsoleVector, out vector);
}
}
}

View File

@@ -319,6 +319,8 @@ namespace OpenSim.Framework.Console
public override void Output(string text, string level)
{
FireOnOutput(text);
lock (m_commandLine)
{
if (m_cursorYPosition == -1)
@@ -509,4 +511,4 @@ namespace OpenSim.Framework.Console
}
}
}
}
}

View File

@@ -40,6 +40,8 @@ namespace OpenSim.Framework.Console
/// </summary>
public class MockConsole : ICommandConsole
{
public event OnOutputDelegate OnOutput;
private MockCommands m_commands = new MockCommands();
public ICommands Commands { get { return m_commands; } }
@@ -76,4 +78,4 @@ namespace OpenSim.Framework.Console
public string[] Resolve(string[] cmd) { return null; }
public XmlElement GetXml(XmlDocument doc) { return null; }
}
}
}

View File

@@ -100,6 +100,7 @@ namespace OpenSim.Framework.Console
m_LineNumber++;
m_Scrollback.Add(String.Format("{0}", m_LineNumber)+":"+level+":"+text);
}
FireOnOutput(text.Trim());
System.Console.WriteLine(text.Trim());
}

View File

@@ -31,7 +31,6 @@ namespace OpenSim.Framework
public class Constants
{
public const uint RegionSize = 256;
public const uint RegionHeight = 4096;
public const byte TerrainPatchSize = 16;
public const string DefaultTexture = "89556747-24cb-43ed-920b-47caed15465f";

View File

@@ -805,23 +805,8 @@ namespace OpenSim.Framework
event Action<IClientAPI> OnRegionHandShakeReply;
event GenericCall1 OnRequestWearables;
event Action<IClientAPI, bool> OnCompleteMovementToRegion;
/// <summary>
/// Called when an AgentUpdate message is received and before OnAgentUpdate.
/// </summary>
/// <remarks>
/// Listeners must not retain a reference to AgentUpdateArgs since this object may be reused for subsequent AgentUpdates.
/// </remarks>
event UpdateAgent OnPreAgentUpdate;
/// <summary>
/// Called when an AgentUpdate message is received and after OnPreAgentUpdate.
/// </summary>
/// <remarks>
/// Listeners must not retain a reference to AgentUpdateArgs since this object may be reused for subsequent AgentUpdates.
/// </remarks>
event UpdateAgent OnAgentUpdate;
event AgentRequestSit OnAgentRequestSit;
event AgentSit OnAgentSit;
event AvatarPickerRequest OnAvatarPickerRequest;
@@ -1099,20 +1084,8 @@ namespace OpenSim.Framework
void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs);
void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args);
/// <summary>
/// Send chat to the viewer.
/// </summary>
/// <param name='message'></param>
/// <param name='type'></param>
/// <param name='fromPos'></param>
/// <param name='fromName'></param>
/// <param name='fromAgentID'></param>
/// <param name='ownerID'></param>
/// <param name='source'></param>
/// <param name='audible'></param>
void SendChatMessage(
string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, UUID ownerID, byte source,
byte audible);
void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, byte source,
byte audible);
void SendInstantMessage(GridInstantMessage im);

View File

@@ -74,8 +74,12 @@ namespace OpenSim.Framework
XmlElement GetXml(XmlDocument doc);
}
public delegate void OnOutputDelegate(string message);
public interface ICommandConsole : IConsole
{
event OnOutputDelegate OnOutput;
ICommands Commands { get; }
/// <summary>
@@ -87,4 +91,4 @@ namespace OpenSim.Framework
string ReadLine(string p, bool isCommand, bool e);
}
}
}

View File

@@ -49,11 +49,7 @@ namespace OpenSim.Framework.Monitoring
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0));
sb.AppendFormat(
"OpenSim last object memory churn : {0} MB/s\n",
Math.Round((MemoryWatchdog.LastMemoryChurn * 1000) / 1024.0 / 1024, 3));
sb.AppendFormat(
"OpenSim average object memory churn : {0} MB/s\n",
"OpenSim object memory churn : {0} MB/s\n",
Math.Round((MemoryWatchdog.AverageMemoryChurn * 1000) / 1024.0 / 1024, 3));
sb.AppendFormat(

View File

@@ -60,21 +60,13 @@ namespace OpenSim.Framework.Monitoring
private static bool m_enabled;
/// <summary>
/// Last memory churn in bytes per millisecond.
/// Average memory churn in bytes per millisecond.
/// </summary>
public static double AverageMemoryChurn
{
get { if (m_samples.Count > 0) return m_samples.Average(); else return 0; }
}
/// <summary>
/// Average memory churn in bytes per millisecond.
/// </summary>
public static double LastMemoryChurn
{
get { if (m_samples.Count > 0) return m_samples.Last(); else return 0; }
}
/// <summary>
/// Maximum number of statistical samples.
/// </summary>

View File

@@ -355,25 +355,10 @@ Asset service request failures: {3}" + Environment.NewLine,
sb.Append(Environment.NewLine);
sb.Append(
string.Format(
"{0,6:0} {1,6:0} {2,6:0} {3,6:0} {4,6:0} {5,6:0.0} {6,6:0.0} {7,6:0.0} {8,6:0.0} {9,6:0.0} {10,6:0.0}\n\n",
"{0,6:0} {1,6:0} {2,6:0} {3,6:0} {4,6:0} {5,6:0.0} {6,6:0.0} {7,6:0.0} {8,6:0.0} {9,6:0.0} {10,6:0.0}",
inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime,
netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime));
Dictionary<string, Dictionary<string, Stat>> sceneStats;
if (StatsManager.TryGetStats("scene", out sceneStats))
{
foreach (KeyValuePair<string, Dictionary<string, Stat>> kvp in sceneStats)
{
foreach (Stat stat in kvp.Value.Values)
{
if (stat.Verbosity == StatVerbosity.Info)
{
sb.AppendFormat("{0} ({1}): {2}{3}\n", stat.Name, stat.Container, stat.Value, stat.UnitName);
}
}
}
}
sb.Append(Environment.NewLine);
/*
sb.Append(Environment.NewLine);

View File

@@ -25,9 +25,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
namespace OpenSim.Framework.Monitoring
{
/// <summary>
@@ -35,24 +32,6 @@ namespace OpenSim.Framework.Monitoring
/// </summary>
public class StatsManager
{
// Subcommand used to list other stats.
public const string AllSubCommand = "all";
// Subcommand used to list other stats.
public const string ListSubCommand = "list";
// All subcommands
public static HashSet<string> SubCommands = new HashSet<string> { AllSubCommand, ListSubCommand };
/// <summary>
/// Registered stats categorized by category/container/shortname
/// </summary>
/// <remarks>
/// Do not add or remove directly from this dictionary.
/// </remarks>
public static Dictionary<string, Dictionary<string, Dictionary<string, Stat>>> RegisteredStats
= new Dictionary<string, Dictionary<string, Dictionary<string, Stat>>>();
private static AssetStatsCollector assetStats;
private static UserStatsCollector userStats;
private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
@@ -61,75 +40,6 @@ namespace OpenSim.Framework.Monitoring
public static UserStatsCollector UserStats { get { return userStats; } }
public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
public static void RegisterConsoleCommands(ICommandConsole console)
{
console.Commands.AddCommand(
"General",
false,
"show stats",
"show stats [list|all|<category>]",
"Show statistical information for this server",
"If no final argument is specified then legacy statistics information is currently shown.\n"
+ "If list is specified then statistic categories are shown.\n"
+ "If all is specified then all registered statistics are shown.\n"
+ "If a category name is specified then only statistics from that category are shown.\n"
+ "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS",
HandleShowStatsCommand);
}
public static void HandleShowStatsCommand(string module, string[] cmd)
{
ICommandConsole con = MainConsole.Instance;
if (cmd.Length > 2)
{
var categoryName = cmd[2];
if (categoryName == AllSubCommand)
{
foreach (var category in RegisteredStats.Values)
{
OutputCategoryStatsToConsole(con, category);
}
}
else if (categoryName == ListSubCommand)
{
con.Output("Statistic categories available are:");
foreach (string category in RegisteredStats.Keys)
con.OutputFormat(" {0}", category);
}
else
{
Dictionary<string, Dictionary<string, Stat>> category;
if (!RegisteredStats.TryGetValue(categoryName, out category))
{
con.OutputFormat("No such category as {0}", categoryName);
}
else
{
OutputCategoryStatsToConsole(con, category);
}
}
}
else
{
// Legacy
con.Output(SimExtraStats.Report());
}
}
private static void OutputCategoryStatsToConsole(
ICommandConsole con, Dictionary<string, Dictionary<string, Stat>> category)
{
foreach (var container in category.Values)
{
foreach (Stat stat in container.Values)
{
con.Output(stat.ToConsoleString());
}
}
}
/// <summary>
/// Start collecting statistics related to assets.
/// Should only be called once.
@@ -151,275 +61,5 @@ namespace OpenSim.Framework.Monitoring
return userStats;
}
/// <summary>
/// Registers a statistic.
/// </summary>
/// <param name='stat'></param>
/// <returns></returns>
public static bool RegisterStat(Stat stat)
{
Dictionary<string, Dictionary<string, Stat>> category = null, newCategory;
Dictionary<string, Stat> container = null, newContainer;
lock (RegisteredStats)
{
// Stat name is not unique across category/container/shortname key.
// XXX: For now just return false. This is to avoid problems in regression tests where all tests
// in a class are run in the same instance of the VM.
if (TryGetStat(stat, out category, out container))
return false;
// We take a copy-on-write approach here of replacing dictionaries when keys are added or removed.
// This means that we don't need to lock or copy them on iteration, which will be a much more
// common operation after startup.
if (container != null)
newContainer = new Dictionary<string, Stat>(container);
else
newContainer = new Dictionary<string, Stat>();
if (category != null)
newCategory = new Dictionary<string, Dictionary<string, Stat>>(category);
else
newCategory = new Dictionary<string, Dictionary<string, Stat>>();
newContainer[stat.ShortName] = stat;
newCategory[stat.Container] = newContainer;
RegisteredStats[stat.Category] = newCategory;
}
return true;
}
/// <summary>
/// Deregister a statistic
/// </summary>>
/// <param name='stat'></param>
/// <returns></returns
public static bool DeregisterStat(Stat stat)
{
Dictionary<string, Dictionary<string, Stat>> category = null, newCategory;
Dictionary<string, Stat> container = null, newContainer;
lock (RegisteredStats)
{
if (!TryGetStat(stat, out category, out container))
return false;
newContainer = new Dictionary<string, Stat>(container);
newContainer.Remove(stat.ShortName);
newCategory = new Dictionary<string, Dictionary<string, Stat>>(category);
newCategory.Remove(stat.Container);
newCategory[stat.Container] = newContainer;
RegisteredStats[stat.Category] = newCategory;
return true;
}
}
public static bool TryGetStats(string category, out Dictionary<string, Dictionary<string, Stat>> stats)
{
return RegisteredStats.TryGetValue(category, out stats);
}
public static bool TryGetStat(
Stat stat,
out Dictionary<string, Dictionary<string, Stat>> category,
out Dictionary<string, Stat> container)
{
category = null;
container = null;
lock (RegisteredStats)
{
if (RegisteredStats.TryGetValue(stat.Category, out category))
{
if (category.TryGetValue(stat.Container, out container))
{
if (container.ContainsKey(stat.ShortName))
return true;
}
}
}
return false;
}
}
/// <summary>
/// Stat type.
/// </summary>
/// <remarks>
/// A push stat is one which is continually updated and so it's value can simply by read.
/// A pull stat is one where reading the value triggers a collection method - the stat is not continually updated.
/// </remarks>
public enum StatType
{
Push,
Pull
}
/// <summary>
/// Verbosity of stat.
/// </summary>
/// <remarks>
/// Info will always be displayed.
/// </remarks>
public enum StatVerbosity
{
Debug,
Info
}
/// <summary>
/// Holds individual static details
/// </summary>
public class Stat
{
/// <summary>
/// Category of this stat (e.g. cache, scene, etc).
/// </summary>
public string Category { get; private set; }
/// <summary>
/// Containing name for this stat.
/// FIXME: In the case of a scene, this is currently the scene name (though this leaves
/// us with a to-be-resolved problem of non-unique region names).
/// </summary>
/// <value>
/// The container.
/// </value>
public string Container { get; private set; }
public StatType StatType { get; private set; }
/// <summary>
/// Action used to update this stat when the value is requested if it's a pull type.
/// </summary>
public Action<Stat> PullAction { get; private set; }
public StatVerbosity Verbosity { get; private set; }
public string ShortName { get; private set; }
public string Name { get; private set; }
public string Description { get; private set; }
public virtual string UnitName { get; private set; }
public virtual double Value
{
get
{
// Asking for an update here means that the updater cannot access this value without infinite recursion.
// XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being
// called by the pull action and just return the value.
if (StatType == StatType.Pull)
PullAction(this);
return m_value;
}
set
{
m_value = value;
}
}
private double m_value;
/// <summary>
/// Constructor
/// </summary>
/// <param name='shortName'>Short name for the stat. Must not contain spaces. e.g. "LongFrames"</param>
/// <param name='name'>Human readable name for the stat. e.g. "Long frames"</param>
/// <param name='description'>Description of stat</param>
/// <param name='unitName'>
/// Unit name for the stat. Should be preceeded by a space if the unit name isn't normally appeneded immediately to the value.
/// e.g. " frames"
/// </param>
/// <param name='category'>Category under which this stat should appear, e.g. "scene". Do not capitalize.</param>
/// <param name='container'>Entity to which this stat relates. e.g. scene name if this is a per scene stat.</param>
/// <param name='type'>Push or pull</param>
/// <param name='pullAction'>Pull stats need an action to update the stat on request. Push stats should set null here.</param>
/// <param name='verbosity'>Verbosity of stat. Controls whether it will appear in short stat display or only full display.</param>
public Stat(
string shortName,
string name,
string description,
string unitName,
string category,
string container,
StatType type,
Action<Stat> pullAction,
StatVerbosity verbosity)
{
if (StatsManager.SubCommands.Contains(category))
throw new Exception(
string.Format("Stat cannot be in category '{0}' since this is reserved for a subcommand", category));
ShortName = shortName;
Name = name;
Description = description;
UnitName = unitName;
Category = category;
Container = container;
StatType = type;
if (StatType == StatType.Push && pullAction != null)
throw new Exception("A push stat cannot have a pull action");
else
PullAction = pullAction;
Verbosity = verbosity;
}
public virtual string ToConsoleString()
{
return string.Format(
"{0}.{1}.{2} : {3}{4}", Category, Container, ShortName, Value, UnitName);
}
}
public class PercentageStat : Stat
{
public int Antecedent { get; set; }
public int Consequent { get; set; }
public override double Value
{
get
{
int c = Consequent;
// Avoid any chance of a multi-threaded divide-by-zero
if (c == 0)
return 0;
return (double)Antecedent / c * 100;
}
set
{
throw new Exception("Cannot set value on a PercentageStat");
}
}
public PercentageStat(
string shortName,
string name,
string description,
string category,
string container,
StatType type,
Action<Stat> pullAction,
StatVerbosity verbosity)
: base(shortName, name, description, "%", category, container, type, pullAction, verbosity) {}
public override string ToConsoleString()
{
return string.Format(
"{0}.{1}.{2} : {3:0.##}{4} ({5}/{6})",
Category, Container, ShortName, Value, UnitName, Antecedent, Consequent);
}
}
}

View File

@@ -231,25 +231,7 @@ namespace OpenSim.Framework.Monitoring
private static bool RemoveThread(int threadID)
{
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);
m_threads.Remove(threadID);
return true;
}
else
{
m_log.WarnFormat(
"[WATCHDOG]: Requested to remove thread with ID {0} but this is not being monitored", threadID);
return false;
}
}
return m_threads.Remove(threadID);
}
public static bool AbortThread(int threadID)

View File

@@ -31,10 +31,10 @@ using System.Reflection;
using OpenMetaverse;
using OpenMetaverse.Packets;
using log4net;
using OpenSim.Framework.Monitoring;
namespace OpenSim.Region.ClientStack.LindenUDP
namespace OpenSim.Framework
{
public sealed class PacketPool
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -44,32 +44,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool packetPoolEnabled = true;
private bool dataBlockPoolEnabled = true;
private PercentageStat m_packetsReusedStat = new PercentageStat(
"PacketsReused",
"Packets reused",
"Number of packets reused out of all requests to the packet pool",
"clientstack",
"packetpool",
StatType.Push,
null,
StatVerbosity.Debug);
private PercentageStat m_blocksReusedStat = new PercentageStat(
"PacketDataBlocksReused",
"Packet data blocks reused",
"Number of data blocks reused out of all requests to the packet pool",
"clientstack",
"packetpool",
StatType.Push,
null,
StatVerbosity.Debug);
/// <summary>
/// Pool of packets available for reuse.
/// </summary>
private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>();
private static Dictionary<Type, Stack<Object>> DataBlocks = new Dictionary<Type, Stack<Object>>();
private static Dictionary<Type, Stack<Object>> DataBlocks =
new Dictionary<Type, Stack<Object>>();
static PacketPool()
{
}
public static PacketPool Instance
{
@@ -88,45 +70,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
get { return dataBlockPoolEnabled; }
}
private PacketPool()
{
StatsManager.RegisterStat(m_packetsReusedStat);
StatsManager.RegisterStat(m_blocksReusedStat);
StatsManager.RegisterStat(
new Stat(
"PacketsPoolCount",
"Objects within the packet pool",
"The number of objects currently stored within the packet pool",
"",
"clientstack",
"packetpool",
StatType.Pull,
stat => { lock (pool) { stat.Value = pool.Count; } },
StatVerbosity.Debug));
StatsManager.RegisterStat(
new Stat(
"PacketDataBlocksPoolCount",
"Objects within the packet data block pool",
"The number of objects currently stored within the packet data block pool",
"",
"clientstack",
"packetpool",
StatType.Pull,
stat => { lock (DataBlocks) { stat.Value = DataBlocks.Count; } },
StatVerbosity.Debug));
}
/// <summary>
/// Gets a packet of the given type.
/// </summary>
/// <param name='type'></param>
/// <returns>Guaranteed to always return a packet, whether from the pool or newly constructed.</returns>
public Packet GetPacket(PacketType type)
{
m_packetsReusedStat.Consequent++;
Packet packet;
if (!packetPoolEnabled)
@@ -136,19 +81,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
if (!pool.ContainsKey(type) || pool[type] == null || (pool[type]).Count == 0)
{
// m_log.DebugFormat("[PACKETPOOL]: Building {0} packet", type);
// Creating a new packet if we cannot reuse an old package
packet = Packet.BuildPacket(type);
}
else
{
// m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type);
// Recycle old packages
m_packetsReusedStat.Antecedent++;
packet = pool[type].Pop();
packet = (pool[type]).Pop();
}
}
@@ -197,7 +136,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
PacketType type = GetType(bytes);
// Array.Clear(zeroBuffer, 0, zeroBuffer.Length);
Array.Clear(zeroBuffer, 0, zeroBuffer.Length);
int i = 0;
Packet packet = GetPacket(type);
@@ -244,7 +183,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
switch (packet.Type)
{
// List pooling packets here
case PacketType.AgentUpdate:
case PacketType.PacketAck:
case PacketType.ObjectUpdate:
case PacketType.ImprovedTerseObjectUpdate:
@@ -259,9 +197,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if ((pool[type]).Count < 50)
{
// m_log.DebugFormat("[PACKETPOOL]: Pushing {0} packet", type);
pool[type].Push(packet);
(pool[type]).Push(packet);
}
}
break;
@@ -273,21 +209,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
public T GetDataBlock<T>() where T: new()
public static T GetDataBlock<T>() where T: new()
{
lock (DataBlocks)
{
m_blocksReusedStat.Consequent++;
Stack<Object> s;
if (DataBlocks.TryGetValue(typeof(T), out s))
{
if (s.Count > 0)
{
m_blocksReusedStat.Antecedent++;
return (T)s.Pop();
}
}
else
{
@@ -298,7 +229,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
public void ReturnDataBlock<T>(T block) where T: new()
public static void ReturnDataBlock<T>(T block) where T: new()
{
if (block == null)
return;
@@ -313,4 +244,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
}
}
}

View File

@@ -120,7 +120,9 @@ namespace OpenSim.Framework
public UUID lastMapUUID = UUID.Zero;
public string lastMapRefresh = "0";
private float m_nonphysPrimMin = 0;
private int m_nonphysPrimMax = 0;
private float m_physPrimMin = 0;
private int m_physPrimMax = 0;
private bool m_clampPrimSize = false;
private int m_objectCapacity = 0;
@@ -285,11 +287,21 @@ namespace OpenSim.Framework
set { m_windlight = value; }
}
public float NonphysPrimMin
{
get { return m_nonphysPrimMin; }
}
public int NonphysPrimMax
{
get { return m_nonphysPrimMax; }
}
public float PhysPrimMin
{
get { return m_physPrimMin; }
}
public int PhysPrimMax
{
get { return m_physPrimMax; }
@@ -623,16 +635,28 @@ namespace OpenSim.Framework
m_regionType = config.GetString("RegionType", String.Empty);
allKeys.Remove("RegionType");
// Prim stuff
//
#region Prim stuff
m_nonphysPrimMin = config.GetFloat("NonphysicalPrimMin", 0);
allKeys.Remove("NonphysicalPrimMin");
m_nonphysPrimMax = config.GetInt("NonphysicalPrimMax", 0);
allKeys.Remove("NonphysicalPrimMax");
m_physPrimMin = config.GetFloat("PhysicalPrimMin", 0);
allKeys.Remove("PhysicalPrimMin");
m_physPrimMax = config.GetInt("PhysicalPrimMax", 0);
allKeys.Remove("PhysicalPrimMax");
m_clampPrimSize = config.GetBoolean("ClampPrimSize", false);
allKeys.Remove("ClampPrimSize");
m_objectCapacity = config.GetInt("MaxPrims", 15000);
allKeys.Remove("MaxPrims");
#endregion
m_agentCapacity = config.GetInt("MaxAgents", 100);
allKeys.Remove("MaxAgents");
@@ -668,10 +692,18 @@ namespace OpenSim.Framework
config.Set("ExternalHostName", m_externalHostName);
if (m_nonphysPrimMin != 0)
config.Set("NonphysicalPrimMax", m_nonphysPrimMin);
if (m_nonphysPrimMax != 0)
config.Set("NonphysicalPrimMax", m_nonphysPrimMax);
if (m_physPrimMin != 0)
config.Set("PhysicalPrimMax", m_physPrimMin);
if (m_physPrimMax != 0)
config.Set("PhysicalPrimMax", m_physPrimMax);
config.Set("ClampPrimSize", m_clampPrimSize.ToString());
if (m_objectCapacity != 0)
@@ -754,9 +786,15 @@ namespace OpenSim.Framework
configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
configMember.addConfigurationOption("nonphysical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
"Minimum size for nonphysical prims", m_nonphysPrimMin.ToString(), true);
configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true);
configMember.addConfigurationOption("physical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
"Minimum size for nonphysical prims", m_physPrimMin.ToString(), true);
configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Maximum size for physical prims", m_physPrimMax.ToString(), true);

View File

@@ -96,6 +96,11 @@ namespace OpenSim.Framework.Servers
get { return m_httpServer; }
}
/// <summary>
/// Holds the non-viewer statistics collection object for this service/server
/// </summary>
protected IStatsCollector m_stats;
public BaseOpenSimServer()
{
m_startuptime = DateTime.Now;
@@ -172,6 +177,10 @@ namespace OpenSim.Framework.Servers
"show info",
"Show general information about the server", HandleShow);
m_console.Commands.AddCommand("General", false, "show stats",
"show stats",
"Show statistics", HandleShow);
m_console.Commands.AddCommand("General", false, "show threads",
"show threads",
"Show thread status", HandleShow);
@@ -192,19 +201,8 @@ namespace OpenSim.Framework.Servers
"threads show",
"Show thread status. Synonym for \"show threads\"",
(string module, string[] args) => Notice(GetThreadsReport()));
m_console.Commands.AddCommand("General", false, "force gc",
"force gc",
"Manually invoke runtime garbage collection. For debugging purposes",
HandleForceGc);
}
}
private void HandleForceGc(string module, string[] args)
{
MainConsole.Instance.Output("Manually invoking runtime garbage collection");
GC.Collect();
}
/// <summary>
/// Should be overriden and referenced by descendents if they need to perform extra shutdown processing
@@ -228,7 +226,12 @@ namespace OpenSim.Framework.Servers
{
StringBuilder sb = new StringBuilder("DIAGNOSTICS\n\n");
sb.Append(GetUptimeReport());
sb.Append(StatsManager.SimExtraStats.Report());
if (m_stats != null)
{
sb.Append(m_stats.Report());
}
sb.Append(Environment.NewLine);
sb.Append(GetThreadsReport());
@@ -379,6 +382,10 @@ namespace OpenSim.Framework.Servers
{
Notice("set log level [level] - change the console logging level only. For example, off or debug.");
Notice("show info - show server information (e.g. startup path).");
if (m_stats != null)
Notice("show stats - show statistical information for this server");
Notice("show threads - list tracked threads");
Notice("show uptime - show server startup time and uptime.");
Notice("show version - show server version.");
@@ -402,6 +409,11 @@ namespace OpenSim.Framework.Servers
ShowInfo();
break;
case "stats":
if (m_stats != null)
Notice(m_stats.Report());
break;
case "threads":
Notice(GetThreadsReport());
break;
@@ -592,7 +604,8 @@ namespace OpenSim.Framework.Servers
public string osSecret {
// Secret uuid for the simulator
get { return m_osSecret; }
get { return m_osSecret; }
}
public string StatReport(IOSHttpRequest httpRequest)
@@ -600,11 +613,11 @@ namespace OpenSim.Framework.Servers
// If we catch a request for "callback", wrap the response in the value for jsonp
if (httpRequest.Query.ContainsKey("callback"))
{
return httpRequest.Query["callback"].ToString() + "(" + StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");";
return httpRequest.Query["callback"].ToString() + "(" + m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");";
}
else
{
return StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version);
return m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version);
}
}

View File

@@ -54,23 +54,8 @@ namespace OpenSim.Framework.Servers.HttpServer
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private HttpServerLogWriter httpserverlog = new HttpServerLogWriter();
/// <summary>
/// Gets or sets the debug level.
/// </summary>
/// <value>
/// See MainServer.DebugLevel.
/// </value>
public int DebugLevel { get; set; }
/// <summary>
/// Request number for diagnostic purposes.
/// </summary>
/// <remarks>
/// This is an internal number. In some debug situations an external number may also be supplied in the
/// opensim-request-id header but we are not currently logging this.
/// </remarks>
public int RequestNumber { get; private set; }
private volatile int NotSocketErrors = 0;
public volatile bool HTTPDRunning = false;
@@ -82,7 +67,7 @@ namespace OpenSim.Framework.Servers.HttpServer
protected Dictionary<string, LLSDMethod> m_llsdHandlers = new Dictionary<string, LLSDMethod>();
protected Dictionary<string, IRequestHandler> m_streamHandlers = new Dictionary<string, IRequestHandler>();
protected Dictionary<string, GenericHTTPMethod> m_HTTPHandlers = new Dictionary<string, GenericHTTPMethod>();
// protected Dictionary<string, IHttpAgentHandler> m_agentHandlers = new Dictionary<string, IHttpAgentHandler>();
protected Dictionary<string, IHttpAgentHandler> m_agentHandlers = new Dictionary<string, IHttpAgentHandler>();
protected Dictionary<string, PollServiceEventArgs> m_pollHandlers =
new Dictionary<string, PollServiceEventArgs>();
@@ -260,29 +245,29 @@ namespace OpenSim.Framework.Servers.HttpServer
return new List<string>(m_pollHandlers.Keys);
}
// // Note that the agent string is provided simply to differentiate
// // the handlers - it is NOT required to be an actual agent header
// // value.
// public bool AddAgentHandler(string agent, IHttpAgentHandler handler)
// {
// lock (m_agentHandlers)
// {
// if (!m_agentHandlers.ContainsKey(agent))
// {
// m_agentHandlers.Add(agent, handler);
// return true;
// }
// }
//
// //must already have a handler for that path so return false
// return false;
// }
//
// public List<string> GetAgentHandlerKeys()
// {
// lock (m_agentHandlers)
// return new List<string>(m_agentHandlers.Keys);
// }
// Note that the agent string is provided simply to differentiate
// the handlers - it is NOT required to be an actual agent header
// value.
public bool AddAgentHandler(string agent, IHttpAgentHandler handler)
{
lock (m_agentHandlers)
{
if (!m_agentHandlers.ContainsKey(agent))
{
m_agentHandlers.Add(agent, handler);
return true;
}
}
//must already have a handler for that path so return false
return false;
}
public List<string> GetAgentHandlerKeys()
{
lock (m_agentHandlers)
return new List<string>(m_agentHandlers.Keys);
}
public bool AddLLSDHandler(string path, LLSDMethod handler)
{
@@ -311,8 +296,6 @@ namespace OpenSim.Framework.Servers.HttpServer
private void OnRequest(object source, RequestEventArgs args)
{
RequestNumber++;
try
{
IHttpClientContext context = (IHttpClientContext)source;
@@ -422,6 +405,7 @@ namespace OpenSim.Framework.Servers.HttpServer
string requestMethod = request.HttpMethod;
string uriString = request.RawUrl;
// string reqnum = "unknown";
int requestStartTick = Environment.TickCount;
// Will be adjusted later on.
@@ -438,22 +422,22 @@ namespace OpenSim.Framework.Servers.HttpServer
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true);
// // This is the REST agent interface. We require an agent to properly identify
// // itself. If the REST handler recognizes the prefix it will attempt to
// // satisfy the request. If it is not recognizable, and no damage has occurred
// // the request can be passed through to the other handlers. This is a low
// // probability event; if a request is matched it is normally expected to be
// // handled
// IHttpAgentHandler agentHandler;
//
// if (TryGetAgentHandler(request, response, out agentHandler))
// {
// if (HandleAgentRequest(agentHandler, request, response))
// {
// requestEndTick = Environment.TickCount;
// return;
// }
// }
// This is the REST agent interface. We require an agent to properly identify
// itself. If the REST handler recognizes the prefix it will attempt to
// satisfy the request. If it is not recognizable, and no damage has occurred
// the request can be passed through to the other handlers. This is a low
// probability event; if a request is matched it is normally expected to be
// handled
IHttpAgentHandler agentHandler;
if (TryGetAgentHandler(request, response, out agentHandler))
{
if (HandleAgentRequest(agentHandler, request, response))
{
requestEndTick = Environment.TickCount;
return;
}
}
//response.KeepAlive = true;
response.SendChunked = false;
@@ -465,7 +449,9 @@ namespace OpenSim.Framework.Servers.HttpServer
if (TryGetStreamHandler(handlerKey, out requestHandler))
{
if (DebugLevel >= 3)
LogIncomingToStreamHandler(request, requestHandler);
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}",
request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description);
response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type.
@@ -542,8 +528,11 @@ namespace OpenSim.Framework.Servers.HttpServer
{
case null:
case "text/html":
if (DebugLevel >= 3)
LogIncomingToContentTypeHandler(request);
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
buffer = HandleHTTPRequest(request, response);
break;
@@ -551,8 +540,11 @@ namespace OpenSim.Framework.Servers.HttpServer
case "application/llsd+xml":
case "application/xml+llsd":
case "application/llsd+json":
if (DebugLevel >= 3)
LogIncomingToContentTypeHandler(request);
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
buffer = HandleLLSDRequests(request, response);
break;
@@ -571,7 +563,9 @@ namespace OpenSim.Framework.Servers.HttpServer
if (DoWeHaveALLSDHandler(request.RawUrl))
{
if (DebugLevel >= 3)
LogIncomingToContentTypeHandler(request);
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
buffer = HandleLLSDRequests(request, response);
}
@@ -579,14 +573,18 @@ namespace OpenSim.Framework.Servers.HttpServer
else if (DoWeHaveAHTTPHandler(request.RawUrl))
{
if (DebugLevel >= 3)
LogIncomingToContentTypeHandler(request);
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
buffer = HandleHTTPRequest(request, response);
}
else
{
if (DebugLevel >= 3)
LogIncomingToXmlRpcHandler(request);
m_log.DebugFormat(
"[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
request.HttpMethod, request.Url.PathAndQuery);
// generic login request.
buffer = HandleXmlRpcRequests(request, response);
@@ -645,90 +643,14 @@ namespace OpenSim.Framework.Servers.HttpServer
if (tickdiff > 3000)
{
m_log.InfoFormat(
"[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms",
RequestNumber,
"[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms",
requestMethod,
uriString,
requestHandler != null ? requestHandler.Name : "",
requestHandler != null ? requestHandler.Description : "",
request.RemoteIPEndPoint,
request.RemoteIPEndPoint.ToString(),
tickdiff);
}
else if (DebugLevel >= 4)
{
m_log.DebugFormat(
"[BASE HTTP SERVER]: HTTP IN {0} :{1} took {2}ms",
RequestNumber,
Port,
tickdiff);
}
}
}
private void LogIncomingToStreamHandler(OSHttpRequest request, IRequestHandler requestHandler)
{
m_log.DebugFormat(
"[BASE HTTP SERVER]: HTTP IN {0} :{1} stream handler {2} {3} {4} {5} from {6}",
RequestNumber,
Port,
request.HttpMethod,
request.Url.PathAndQuery,
requestHandler.Name,
requestHandler.Description,
request.RemoteIPEndPoint);
if (DebugLevel >= 5)
LogIncomingInDetail(request);
}
private void LogIncomingToContentTypeHandler(OSHttpRequest request)
{
m_log.DebugFormat(
"[BASE HTTP SERVER]: HTTP IN {0} :{1} {2} content type handler {3} {4} from {5}",
RequestNumber,
Port,
(request.ContentType == null || request.ContentType == "") ? "not set" : request.ContentType,
request.HttpMethod,
request.Url.PathAndQuery,
request.RemoteIPEndPoint);
if (DebugLevel >= 5)
LogIncomingInDetail(request);
}
private void LogIncomingToXmlRpcHandler(OSHttpRequest request)
{
m_log.DebugFormat(
"[BASE HTTP SERVER]: HTTP IN {0} :{1} assumed generic XMLRPC request {2} {3} from {4}",
RequestNumber,
Port,
request.HttpMethod,
request.Url.PathAndQuery,
request.RemoteIPEndPoint);
if (DebugLevel >= 5)
LogIncomingInDetail(request);
}
private void LogIncomingInDetail(OSHttpRequest request)
{
using (StreamReader reader = new StreamReader(Util.Copy(request.InputStream), Encoding.UTF8))
{
string output;
if (DebugLevel == 5)
{
const int sampleLength = 80;
char[] sampleChars = new char[sampleLength];
reader.Read(sampleChars, 0, sampleLength);
output = new string(sampleChars);
}
else
{
output = reader.ReadToEnd();
}
m_log.DebugFormat("[BASE HTTP SERVER]: {0}...", output.Replace("\n", @"\n"));
}
}
@@ -824,24 +746,24 @@ namespace OpenSim.Framework.Servers.HttpServer
}
}
// private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler)
// {
// agentHandler = null;
//
// lock (m_agentHandlers)
// {
// foreach (IHttpAgentHandler handler in m_agentHandlers.Values)
// {
// if (handler.Match(request, response))
// {
// agentHandler = handler;
// return true;
// }
// }
// }
//
// return false;
// }
private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler)
{
agentHandler = null;
lock (m_agentHandlers)
{
foreach (IHttpAgentHandler handler in m_agentHandlers.Values)
{
if (handler.Match(request, response))
{
agentHandler = handler;
return true;
}
}
}
return false;
}
/// <summary>
/// Try all the registered xmlrpc handlers when an xmlrpc request is received.
@@ -1766,21 +1688,21 @@ namespace OpenSim.Framework.Servers.HttpServer
m_pollHandlers.Remove(path);
}
// public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler)
// {
// lock (m_agentHandlers)
// {
// IHttpAgentHandler foundHandler;
//
// if (m_agentHandlers.TryGetValue(agent, out foundHandler) && foundHandler == handler)
// {
// m_agentHandlers.Remove(agent);
// return true;
// }
// }
//
// return false;
// }
public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler)
{
lock (m_agentHandlers)
{
IHttpAgentHandler foundHandler;
if (m_agentHandlers.TryGetValue(agent, out foundHandler) && foundHandler == handler)
{
m_agentHandlers.Remove(agent);
return true;
}
}
return false;
}
public void RemoveXmlRPCHandler(string method)
{

View File

@@ -41,10 +41,10 @@ namespace OpenSim.Framework.Servers.HttpServer
uint Port { get; }
bool UseSSL { get; }
// // Note that the agent string is provided simply to differentiate
// // the handlers - it is NOT required to be an actual agent header
// // value.
// bool AddAgentHandler(string agent, IHttpAgentHandler handler);
// Note that the agent string is provided simply to differentiate
// the handlers - it is NOT required to be an actual agent header
// value.
bool AddAgentHandler(string agent, IHttpAgentHandler handler);
/// <summary>
/// Add a handler for an HTTP request.
@@ -106,13 +106,13 @@ namespace OpenSim.Framework.Servers.HttpServer
bool SetDefaultLLSDHandler(DefaultLLSDMethod handler);
// /// <summary>
// /// Remove the agent if it is registered.
// /// </summary>
// /// <param name="agent"></param>
// /// <param name="handler"></param>
// /// <returns></returns>
// bool RemoveAgentHandler(string agent, IHttpAgentHandler handler);
/// <summary>
/// Remove the agent if it is registered.
/// </summary>
/// <param name="agent"></param>
/// <param name="handler"></param>
/// <returns></returns>
bool RemoveAgentHandler(string agent, IHttpAgentHandler handler);
/// <summary>
/// Remove an HTTP handler

View File

@@ -29,7 +29,6 @@ using System;
using System.Collections.Generic;
using System.Reflection;
using System.Net;
using System.Text;
using log4net;
using OpenSim.Framework;
using OpenSim.Framework.Console;
@@ -48,12 +47,9 @@ namespace OpenSim.Framework.Servers
/// Control the printing of certain debug messages.
/// </summary>
/// <remarks>
/// If DebugLevel >= 1 then short warnings are logged when receiving bad input data.
/// If DebugLevel >= 2 then long warnings are logged when receiving bad input data.
/// If DebugLevel >= 3 then short notices about all incoming non-poll HTTP requests are logged.
/// If DebugLevel >= 4 then the time taken to fulfill the request is logged.
/// If DebugLevel >= 5 then the start of the body of incoming non-poll HTTP requests will be logged.
/// If DebugLevel >= 6 then the entire body of incoming non-poll HTTP requests will be logged.
/// If DebugLevel >= 1, then short warnings are logged when receiving bad input data.
/// If DebugLevel >= 2, then long warnings are logged when receiving bad input data.
/// If DebugLevel >= 3, then short notices about all incoming non-poll HTTP requests are logged.
/// </remarks>
public static int DebugLevel
{
@@ -105,28 +101,17 @@ namespace OpenSim.Framework.Servers
get { return new Dictionary<uint, BaseHttpServer>(m_Servers); }
}
public static void RegisterHttpConsoleCommands(ICommandConsole console)
{
console.Commands.AddCommand(
"Comms", false, "show http-handlers",
"show http-handlers",
"Show all registered http handlers", HandleShowHttpHandlersCommand);
console.Commands.AddCommand(
"Debug", false, "debug http", "debug http <in|out|all> [<level>]",
"Turn on http request logging.",
"If in or all and\n"
+ " level <= 0 then no extra logging is done.\n"
+ " level >= 1 then short warnings are logged when receiving bad input data.\n"
+ " level >= 2 then long warnings are logged when receiving bad input data.\n"
+ " level >= 3 then short notices about all incoming non-poll HTTP requests are logged.\n"
+ " level >= 4 then the time taken to fulfill the request is logged.\n"
+ " level >= 5 then a sample from the beginning of the incoming data is logged.\n"
+ " level >= 6 then the entire incoming data is logged.\n"
+ " no level is specified then the current level is returned.\n\n"
+ "If out or all and\n"
+ " level >= 3 then short notices about all outgoing requests going through WebUtil are logged.\n"
+ " level >= 4 then the time taken to fulfill the request is logged.\n",
"Debug", false, "debug http", "debug http [<level>]",
"Turn on inbound non-poll http request debugging.",
"If level <= 0, then no extra logging is done.\n"
+ "If level >= 1, then short warnings are logged when receiving bad input data.\n"
+ "If level >= 2, then long warnings are logged when receiving bad input data.\n"
+ "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n"
+ "If no level is specified then the current level is returned.",
HandleDebugHttpCommand);
}
@@ -134,122 +119,27 @@ namespace OpenSim.Framework.Servers
/// Turn on some debugging values for OpenSim.
/// </summary>
/// <param name="args"></param>
private static void HandleDebugHttpCommand(string module, string[] cmdparams)
private static void HandleDebugHttpCommand(string module, string[] args)
{
if (cmdparams.Length < 3)
if (args.Length == 3)
{
MainConsole.Instance.Output("Usage: debug http <in|out|all> 0..6");
return;
}
bool inReqs = false;
bool outReqs = false;
bool allReqs = false;
string subCommand = cmdparams[2];
if (subCommand.ToLower() == "in")
{
inReqs = true;
}
else if (subCommand.ToLower() == "out")
{
outReqs = true;
}
else if (subCommand.ToLower() == "all")
{
allReqs = true;
}
else
{
MainConsole.Instance.Output("You must specify in, out or all");
return;
}
if (cmdparams.Length >= 4)
{
string rawNewDebug = cmdparams[3];
int newDebug;
if (!int.TryParse(rawNewDebug, out newDebug))
{
MainConsole.Instance.OutputFormat("{0} is not a valid debug level", rawNewDebug);
return;
}
if (newDebug < 0 || newDebug > 6)
{
MainConsole.Instance.OutputFormat("{0} is outside the valid debug level range of 0..6", newDebug);
return;
}
if (allReqs || inReqs)
if (int.TryParse(args[2], out newDebug))
{
MainServer.DebugLevel = newDebug;
MainConsole.Instance.OutputFormat("IN debug level set to {0}", newDebug);
}
if (allReqs || outReqs)
{
WebUtil.DebugLevel = newDebug;
MainConsole.Instance.OutputFormat("OUT debug level set to {0}", newDebug);
MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug);
}
}
else if (args.Length == 2)
{
MainConsole.Instance.OutputFormat("Current debug http level is {0}", MainServer.DebugLevel);
}
else
{
if (allReqs || inReqs)
MainConsole.Instance.OutputFormat("Current IN debug level is {0}", MainServer.DebugLevel);
if (allReqs || outReqs)
MainConsole.Instance.OutputFormat("Current OUT debug level is {0}", WebUtil.DebugLevel);
MainConsole.Instance.Output("Usage: debug http 0..3");
}
}
private static void HandleShowHttpHandlersCommand(string module, string[] args)
{
if (args.Length != 2)
{
MainConsole.Instance.Output("Usage: show http-handlers");
return;
}
StringBuilder handlers = new StringBuilder();
lock (m_Servers)
{
foreach (BaseHttpServer httpServer in m_Servers.Values)
{
handlers.AppendFormat(
"Registered HTTP Handlers for server at {0}:{1}\n", httpServer.ListenIPAddress, httpServer.Port);
handlers.AppendFormat("* XMLRPC:\n");
foreach (String s in httpServer.GetXmlRpcHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
handlers.AppendFormat("* HTTP:\n");
List<String> poll = httpServer.GetPollServiceHandlerKeys();
foreach (String s in httpServer.GetHTTPHandlerKeys())
handlers.AppendFormat("\t{0} {1}\n", s, (poll.Contains(s) ? "(poll service)" : string.Empty));
// handlers.AppendFormat("* Agent:\n");
// foreach (String s in httpServer.GetAgentHandlerKeys())
// handlers.AppendFormat("\t{0}\n", s);
handlers.AppendFormat("* LLSD:\n");
foreach (String s in httpServer.GetLLSDHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
handlers.AppendFormat("* StreamHandlers ({0}):\n", httpServer.GetStreamHandlerKeys().Count);
foreach (String s in httpServer.GetStreamHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
handlers.Append("\n");
}
}
MainConsole.Instance.Output(handlers.ToString());
}
/// <summary>
/// Register an already started HTTP server to the collection of known servers.
/// </summary>

View File

@@ -29,8 +29,8 @@ namespace OpenSim
{
public class VersionInfo
{
private const string VERSION_NUMBER = "0.7.4";
private const Flavour VERSION_FLAVOUR = Flavour.Extended;
private const string VERSION_NUMBER = "0.7.5";
private const Flavour VERSION_FLAVOUR = Flavour.Dev;
public enum Flavour
{

View File

@@ -35,12 +35,10 @@ using OpenMetaverse;
namespace OpenSim.Framework
{
/// <summary>
/// A dictionary containing task inventory items. Indexed by item UUID.
/// A dictionary for task inventory.
/// </summary>
/// <remarks>
/// This class is not thread safe. Callers must synchronize on Dictionary methods or Clone() this object before
/// iterating over it.
/// </remarks>
public class TaskInventoryDictionary : Dictionary<UUID, TaskInventoryItem>,
ICloneable, IXmlSerializable
{

View File

@@ -73,6 +73,9 @@ namespace OpenSim.Framework
private bool _ownerChanged = false;
// This used ONLY during copy. It can't be relied on at other times!
private bool _scriptRunning = true;
public UUID AssetID {
get {
return _assetID;
@@ -350,13 +353,14 @@ namespace OpenSim.Framework
}
}
/// <summary>
/// This used ONLY during copy. It can't be relied on at other times!
/// </summary>
/// <remarks>
/// For true script running status, use IEntityInventory.TryGetScriptInstanceRunning() for now.
/// </remarks>
public bool ScriptRunning { get; set; }
public bool ScriptRunning {
get {
return _scriptRunning;
}
set {
_scriptRunning = value;
}
}
// See ICloneable
@@ -384,7 +388,6 @@ namespace OpenSim.Framework
public TaskInventoryItem()
{
ScriptRunning = true;
CreationDate = (uint)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
}
}

View File

@@ -533,19 +533,6 @@ namespace OpenSim.Framework
return (x + y - (min >> 1) - (min >> 2) + (min >> 4));
}
/// <summary>
/// Determines whether a point is inside a bounding box.
/// </summary>
/// <param name='v'></param>
/// <param name='min'></param>
/// <param name='max'></param>
/// <returns></returns>
public static bool IsInsideBox(Vector3 v, Vector3 min, Vector3 max)
{
return v.X >= min.X & v.Y >= min.Y && v.Z >= min.Z
&& v.X <= max.X && v.Y <= max.Y && v.Z <= max.Z;
}
/// <summary>
/// Are the co-ordinates of the new region visible from the old region?
/// </summary>
@@ -1020,38 +1007,6 @@ namespace OpenSim.Framework
}
}
/// <summary>
/// Copy data from one stream to another, leaving the read position of both streams at the beginning.
/// </summary>
/// <param name='inputStream'>
/// Input stream. Must be seekable.
/// </param>
/// <exception cref='ArgumentException'>
/// Thrown if the input stream is not seekable.
/// </exception>
public static Stream Copy(Stream inputStream)
{
if (!inputStream.CanSeek)
throw new ArgumentException("Util.Copy(Stream inputStream) must receive an inputStream that can seek");
const int readSize = 256;
byte[] buffer = new byte[readSize];
MemoryStream ms = new MemoryStream();
int count = inputStream.Read(buffer, 0, readSize);
while (count > 0)
{
ms.Write(buffer, 0, count);
count = inputStream.Read(buffer, 0, readSize);
}
ms.Position = 0;
inputStream.Position = 0;
return ms;
}
public static XmlRpcResponse XmlRpcCommand(string url, string methodName, params object[] args)
{
return SendXmlRpcCommand(url, methodName, args);

View File

@@ -53,18 +53,10 @@ namespace OpenSim.Framework
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Control the printing of certain debug messages.
/// </summary>
/// <remarks>
/// If DebugLevel >= 3 then short notices about outgoing HTTP requests are logged.
/// </remarks>
public static int DebugLevel { get; set; }
/// <summary>
/// Request number for diagnostic purposes.
/// </summary>
public static int RequestNumber { get; internal set; }
public static int RequestNumber = 0;
/// <summary>
/// this is the header field used to communicate the local request id
@@ -154,11 +146,7 @@ namespace OpenSim.Framework
private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed)
{
int reqnum = RequestNumber++;
if (DebugLevel >= 3)
m_log.DebugFormat(
"[WEB UTIL]: HTTP OUT {0} ServiceOSD {1} {2} (timeout {3}, compressed {4})",
reqnum, method, url, timeout, compressed);
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
string errorMessage = "unknown error";
int tickstart = Util.EnvironmentTickCount();
@@ -241,7 +229,7 @@ namespace OpenSim.Framework
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > LongCallTime)
m_log.InfoFormat(
"[WEB UTIL]: Slow ServiceOSD request {0} {1} {2} took {3}ms, {4}ms writing, {5}",
"[OSD REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
reqnum,
method,
url,
@@ -250,14 +238,10 @@ namespace OpenSim.Framework
strBuffer != null
? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer)
: "");
else if (DebugLevel >= 4)
m_log.DebugFormat(
"[WEB UTIL]: HTTP OUT {0} took {1}ms, {2}ms writing",
reqnum, tickdiff, tickdata);
}
m_log.DebugFormat(
"[WEB UTIL]: ServiceOSD request {0} {1} {2} FAILED: {3}", reqnum, url, method, errorMessage);
"[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage);
return ErrorResponseMap(errorMessage);
}
@@ -333,11 +317,7 @@ namespace OpenSim.Framework
{
int reqnum = RequestNumber++;
string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown";
if (DebugLevel >= 3)
m_log.DebugFormat(
"[WEB UTIL]: HTTP OUT {0} ServiceForm {1} {2} (timeout {3})",
reqnum, method, url, timeout);
// m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method);
string errorMessage = "unknown error";
int tickstart = Util.EnvironmentTickCount();
@@ -400,7 +380,7 @@ namespace OpenSim.Framework
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > LongCallTime)
m_log.InfoFormat(
"[WEB UTIL]: Slow ServiceForm request {0} {1} {2} took {3}ms, {4}ms writing, {5}",
"[SERVICE FORM]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
reqnum,
method,
url,
@@ -409,13 +389,9 @@ namespace OpenSim.Framework
queryString != null
? (queryString.Length > MaxRequestDiagLength) ? queryString.Remove(MaxRequestDiagLength) : queryString
: "");
else if (DebugLevel >= 4)
m_log.DebugFormat(
"[WEB UTIL]: HTTP OUT {0} took {1}ms, {2}ms writing",
reqnum, tickdiff, tickdata);
}
m_log.WarnFormat("[WEB UTIL]: ServiceForm request {0} {1} {2} failed: {2}", reqnum, method, url, errorMessage);
m_log.WarnFormat("[SERVICE FORM]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage);
return ErrorResponseMap(errorMessage);
}
@@ -667,6 +643,7 @@ namespace OpenSim.Framework
/// <returns></returns>
public static string[] GetPreferredImageTypes(string accept)
{
if (accept == null || accept == string.Empty)
return new string[0];
@@ -718,15 +695,13 @@ namespace OpenSim.Framework
string requestUrl, TRequest obj, Action<TResponse> action)
{
int reqnum = WebUtil.RequestNumber++;
if (WebUtil.DebugLevel >= 3)
m_log.DebugFormat(
"[WEB UTIL]: HTTP OUT {0} AsynchronousRequestObject {1} {2}",
reqnum, verb, requestUrl);
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
int tickstart = Util.EnvironmentTickCount();
int tickdata = 0;
// m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl);
Type type = typeof(TRequest);
WebRequest request = WebRequest.Create(requestUrl);
@@ -879,7 +854,7 @@ namespace OpenSim.Framework
}
m_log.InfoFormat(
"[ASYNC REQUEST]: Slow request {0} {1} {2} took {3}ms, {4}ms writing, {5}",
"[ASYNC REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
reqnum,
verb,
requestUrl,
@@ -887,12 +862,6 @@ namespace OpenSim.Framework
tickdata,
originalRequest);
}
else if (WebUtil.DebugLevel >= 4)
{
m_log.DebugFormat(
"[WEB UTIL]: HTTP OUT {0} took {1}ms, {2}ms writing",
reqnum, tickdiff, tickdata);
}
}
}
@@ -913,11 +882,7 @@ namespace OpenSim.Framework
public static string MakeRequest(string verb, string requestUrl, string obj)
{
int reqnum = WebUtil.RequestNumber++;
if (WebUtil.DebugLevel >= 3)
m_log.DebugFormat(
"[WEB UTIL]: HTTP OUT {0} SynchronousRestForms {1} {2}",
reqnum, verb, requestUrl);
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
int tickstart = Util.EnvironmentTickCount();
int tickdata = 0;
@@ -1002,17 +967,13 @@ namespace OpenSim.Framework
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > WebUtil.LongCallTime)
m_log.InfoFormat(
"[FORMS]: Slow request {0} {1} {2} took {3}ms, {4}ms writing, {5}",
"[FORMS]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
reqnum,
verb,
requestUrl,
tickdiff,
tickdata,
obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj);
else if (WebUtil.DebugLevel >= 4)
m_log.DebugFormat(
"[WEB UTIL]: HTTP OUT {0} took {1}ms, {2}ms writing",
reqnum, tickdiff, tickdata);
return respstring;
}
@@ -1037,11 +998,7 @@ namespace OpenSim.Framework
public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj)
{
int reqnum = WebUtil.RequestNumber++;
if (WebUtil.DebugLevel >= 3)
m_log.DebugFormat(
"[WEB UTIL]: HTTP OUT {0} SynchronousRestObject {1} {2}",
reqnum, verb, requestUrl);
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
int tickstart = Util.EnvironmentTickCount();
int tickdata = 0;
@@ -1154,7 +1111,7 @@ namespace OpenSim.Framework
}
m_log.InfoFormat(
"[SynchronousRestObjectRequester]: Slow request {0} {1} {2} took {3}ms, {4}ms writing, {5}",
"[SynchronousRestObjectRequester]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
reqnum,
verb,
requestUrl,
@@ -1162,12 +1119,6 @@ namespace OpenSim.Framework
tickdata,
originalRequest);
}
else if (WebUtil.DebugLevel >= 4)
{
m_log.DebugFormat(
"[WEB UTIL]: HTTP OUT {0} took {1}ms, {2}ms writing",
reqnum, tickdiff, tickdata);
}
return deserial;
}

View File

@@ -254,14 +254,8 @@ namespace OpenSim
m_console.Commands.AddCommand("Debug", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
m_console.Commands.AddCommand("Debug", false, "debug scene",
"debug scene active|collisions|physics|scripting|teleport true|false",
"Turn on scene debugging.",
"If active is false then main scene update and maintenance loops are suspended.\n"
+ "If collisions is false then collisions with other objects are turned off.\n"
+ "If physics is false then all physics objects are non-physical.\n"
+ "If scripting is false then no scripting operations happen.\n"
+ "If teleport is true then some extra teleport debug information is logged.",
Debug);
"debug scene <scripting> <collisions> <physics>",
"Turn on scene debugging", Debug);
m_console.Commands.AddCommand("General", false, "change region",
"change region <region name>",
@@ -338,6 +332,10 @@ namespace OpenSim
"show circuits",
"Show agent circuit data", HandleShow);
m_console.Commands.AddCommand("Comms", false, "show http-handlers",
"show http-handlers",
"Show all registered http handlers", HandleShow);
m_console.Commands.AddCommand("Comms", false, "show pending-objects",
"show pending-objects",
"Show # of objects on the pending queues of all scene viewers", HandleShow);
@@ -422,6 +420,7 @@ namespace OpenSim
{
RunCommandScript(m_shutdownCommandsFile);
}
base.ShutdownSpecific();
}
@@ -934,8 +933,7 @@ namespace OpenSim
}
else
{
MainConsole.Instance.Output(
"Usage: debug scene active|scripting|collisions|physics|teleport true|false");
MainConsole.Instance.Output("Usage: debug scene scripting|collisions|physics|teleport true|false");
}
break;
@@ -1015,6 +1013,33 @@ namespace OpenSim
HandleShowCircuits();
break;
case "http-handlers":
System.Text.StringBuilder handlers = new System.Text.StringBuilder("Registered HTTP Handlers:\n");
handlers.AppendFormat("* XMLRPC:\n");
foreach (String s in HttpServer.GetXmlRpcHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
handlers.AppendFormat("* HTTP:\n");
List<String> poll = HttpServer.GetPollServiceHandlerKeys();
foreach (String s in HttpServer.GetHTTPHandlerKeys())
handlers.AppendFormat("\t{0} {1}\n", s, (poll.Contains(s) ? "(poll service)" : string.Empty));
handlers.AppendFormat("* Agent:\n");
foreach (String s in HttpServer.GetAgentHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
handlers.AppendFormat("* LLSD:\n");
foreach (String s in HttpServer.GetLLSDHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
handlers.AppendFormat("* StreamHandlers ({0}):\n", HttpServer.GetStreamHandlerKeys().Count);
foreach (String s in HttpServer.GetStreamHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
MainConsole.Instance.Output(handlers.ToString());
break;
case "modules":
MainConsole.Instance.Output("The currently loaded shared modules are:");
foreach (IRegionModule module in m_moduleLoader.GetLoadedSharedModules)
@@ -1109,7 +1134,7 @@ namespace OpenSim
aCircuit.Name,
aCircuit.child ? "child" : "root",
aCircuit.circuitcode.ToString(),
aCircuit.IPAddress != null ? aCircuit.IPAddress.ToString() : "not set",
aCircuit.IPAddress.ToString(),
aCircuit.Viewer);
});

View File

@@ -207,36 +207,24 @@ namespace OpenSim
IConfig simDataConfig = m_config.Source.Configs["SimulationDataStore"];
if (simDataConfig == null)
throw new Exception("Configuration file is missing the [SimulationDataStore] section. Have you copied OpenSim.ini.example to OpenSim.ini to reference config-include/ files?");
string module = simDataConfig.GetString("LocalServiceModule", String.Empty);
if (String.IsNullOrEmpty(module))
throw new Exception("Configuration file is missing the LocalServiceModule parameter in the [SimulationDataStore] section.");
m_simulationDataService = ServerUtils.LoadPlugin<ISimulationDataService>(module, new object[] { m_config.Source });
if (m_simulationDataService == null)
throw new Exception(
string.Format(
"Could not load an ISimulationDataService implementation from {0}, as configured in the LocalServiceModule parameter of the [SimulationDataStore] config section.",
module));
// Load the estate data service
IConfig estateDataConfig = m_config.Source.Configs["EstateDataStore"];
if (estateDataConfig == null)
throw new Exception("Configuration file is missing the [EstateDataStore] section. Have you copied OpenSim.ini.example to OpenSim.ini to reference config-include/ files?");
module = estateDataConfig.GetString("LocalServiceModule", String.Empty);
if (String.IsNullOrEmpty(module))
throw new Exception("Configuration file is missing the LocalServiceModule parameter in the [EstateDataStore] section");
m_estateDataService = ServerUtils.LoadPlugin<IEstateDataService>(module, new object[] { m_config.Source });
if (m_estateDataService == null)
throw new Exception(
string.Format(
"Could not load an IEstateDataService implementation from {0}, as configured in the LocalServiceModule parameter of the [EstateDataStore] config section.",
module));
base.StartupSpecific();
m_stats = StatsManager.SimExtraStats;
// Create a ModuleLoader instance
m_moduleLoader = new ModuleLoader(m_config.Source);
@@ -246,51 +234,51 @@ namespace OpenSim
plugin.PostInitialise();
}
if (m_console != null)
{
StatsManager.RegisterConsoleCommands(m_console);
AddPluginCommands(m_console);
}
AddPluginCommands();
}
protected virtual void AddPluginCommands(CommandConsole console)
protected virtual void AddPluginCommands()
{
List<string> topics = GetHelpTopics();
foreach (string topic in topics)
// If console exists add plugin commands.
if (m_console != null)
{
string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1);
List<string> topics = GetHelpTopics();
// This is a hack to allow the user to enter the help command in upper or lowercase. This will go
// away at some point.
console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
"help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'",
HandleCommanderHelp);
console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
"help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'",
HandleCommanderHelp);
ICommander commander = null;
Scene s = SceneManager.CurrentOrFirstScene;
if (s != null && s.GetCommanders() != null)
foreach (string topic in topics)
{
if (s.GetCommanders().ContainsKey(topic))
commander = s.GetCommanders()[topic];
}
string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1);
if (commander == null)
continue;
// This is a hack to allow the user to enter the help command in upper or lowercase. This will go
// away at some point.
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
"help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'",
HandleCommanderHelp);
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
"help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'",
HandleCommanderHelp);
foreach (string command in commander.Commands.Keys)
{
console.Commands.AddCommand(capitalizedTopic, false,
topic + " " + command,
topic + " " + commander.Commands[command].ShortHelp(),
String.Empty, HandleCommanderCommand);
ICommander commander = null;
Scene s = SceneManager.CurrentOrFirstScene;
if (s != null && s.GetCommanders() != null)
{
if (s.GetCommanders().ContainsKey(topic))
commander = s.GetCommanders()[topic];
}
if (commander == null)
continue;
foreach (string command in commander.Commands.Keys)
{
m_console.Commands.AddCommand(capitalizedTopic, false,
topic + " " + command,
topic + " " + commander.Commands[command].ShortHelp(),
String.Empty, HandleCommanderCommand);
}
}
}
}
@@ -557,7 +545,7 @@ namespace OpenSim
if (account == null)
{
m_log.ErrorFormat(
"[OPENSIM]: Unable to store account. If this simulator is connected to a grid, you must create the estate owner account first at the grid level.");
"[OPENSIM]: Unable to store account. If this simulator is connected to a grid, you must create the estate owner account first.");
}
else
{

View File

@@ -163,8 +163,8 @@ namespace OpenSim.Region.ClientStack.Linden
m_HostCapsObj.RegisterHandler(
"SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null));
// m_log.DebugFormat(
// "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
m_log.DebugFormat(
"[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
//m_capsHandlers["MapLayer"] =
// new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
@@ -254,12 +254,11 @@ 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.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName);
if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
{
m_log.WarnFormat(
m_log.DebugFormat(
"[CAPS]: Unauthorized CAPS client {0} from {1}",
m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint);

View File

@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden
//scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack);
// scene.EventManager.OnNewClient += OnNewClient;
scene.EventManager.OnNewClient += OnNewClient;
// TODO: Leaving these open, or closing them when we
// become a child is incorrect. It messes up TP in a big
@@ -102,7 +102,6 @@ namespace OpenSim.Region.ClientStack.Linden
// circuit is there.
scene.EventManager.OnClientClosed += ClientClosed;
scene.EventManager.OnMakeChildAgent += MakeChildAgent;
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
@@ -111,10 +110,10 @@ namespace OpenSim.Region.ClientStack.Linden
false,
"debug eq",
"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"
+ " >= 2 - turns on poll notification",
"Turn on event queue debugging"
+ "<= 0 - turns off all event queue logging"
+ ">= 1 - turns on outgoing event logging"
+ ">= 2 - turns on poll notification",
HandleDebugEq);
}
else
@@ -227,6 +226,16 @@ namespace OpenSim.Region.ClientStack.Linden
#endregion
private void OnNewClient(IClientAPI client)
{
//client.OnLogout += ClientClosed;
}
// private void ClientClosed(IClientAPI client)
// {
// ClientClosed(client.AgentId);
// }
private void ClientClosed(UUID agentID, Scene scene)
{
// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);

View File

@@ -0,0 +1,234 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
using System.IO;
using System.Web;
using log4net;
using Nini.Config;
using Mono.Addins;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenMetaverse.Imaging;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
using OpenSim.Capabilities.Handlers;
namespace OpenSim.Region.ClientStack.Linden
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionConsoleModule")]
public class RegionConsoleModule : INonSharedRegionModule, IRegionConsole
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
private IEventQueue m_eventQueue;
private Commands m_commands = new Commands();
public ICommands Commands { get { return m_commands; } }
public void Initialise(IConfigSource source)
{
m_commands.AddCommand( "Help", false, "help", "help [<item>]", "Display help on a particular command or on a list of commands in a category", Help);
}
public void AddRegion(Scene s)
{
m_scene = s;
m_scene.RegisterModuleInterface<IRegionConsole>(this);
}
public void RemoveRegion(Scene s)
{
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
m_scene = null;
}
public void RegionLoaded(Scene s)
{
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
m_eventQueue = m_scene.RequestModuleInterface<IEventQueue>();
}
public void PostInitialise()
{
}
public void Close() { }
public string Name { get { return "RegionConsoleModule"; } }
public Type ReplaceableInterface
{
get { return null; }
}
public void RegisterCaps(UUID agentID, Caps caps)
{
if (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(agentID))
return;
UUID capID = UUID.Random();
m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
caps.RegisterHandler(
"SimConsoleAsync",
new ConsoleHandler("/CAPS/" + capID + "/", "SimConsoleAsync", agentID, this, m_scene));
}
public void SendConsoleOutput(UUID agentID, string message)
{
OSD osd = OSD.FromString(message);
m_eventQueue.Enqueue(EventQueueHelper.BuildEvent("SimConsoleResponse", osd), agentID);
}
public bool RunCommand(string command, UUID invokerID)
{
string[] parts = Parser.Parse(command);
Array.Resize(ref parts, parts.Length + 1);
parts[parts.Length - 1] = invokerID.ToString();
if (m_commands.Resolve(parts).Length == 0)
return false;
return true;
}
private void Help(string module, string[] cmd)
{
UUID agentID = new UUID(cmd[cmd.Length - 1]);
Array.Resize(ref cmd, cmd.Length - 1);
List<string> help = Commands.GetHelp(cmd);
string reply = String.Empty;
foreach (string s in help)
{
reply += s + "\n";
}
SendConsoleOutput(agentID, reply);
}
public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn)
{
m_commands.AddCommand(module, shared, command, help, longhelp, fn);
}
}
public class ConsoleHandler : BaseStreamHandler
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private RegionConsoleModule m_consoleModule;
private UUID m_agentID;
private bool m_isGod;
private Scene m_scene;
private bool m_consoleIsOn = false;
public ConsoleHandler(string path, string name, UUID agentID, RegionConsoleModule module, Scene scene)
:base("POST", path, name, agentID.ToString())
{
m_agentID = agentID;
m_consoleModule = module;
m_scene = scene;
m_isGod = m_scene.Permissions.IsGod(agentID);
}
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
StreamReader reader = new StreamReader(request);
string message = reader.ReadToEnd();
OSD osd = OSDParser.DeserializeLLSDXml(message);
string cmd = osd.AsString();
if (cmd == "set console on")
{
if (m_isGod)
{
MainConsole.Instance.OnOutput += ConsoleSender;
m_consoleIsOn = true;
m_consoleModule.SendConsoleOutput(m_agentID, "Console is now on");
}
return new byte[0];
}
else if (cmd == "set console off")
{
MainConsole.Instance.OnOutput -= ConsoleSender;
m_consoleIsOn = false;
m_consoleModule.SendConsoleOutput(m_agentID, "Console is now off");
return new byte[0];
}
if (m_consoleIsOn == false && m_consoleModule.RunCommand(osd.AsString().Trim(), m_agentID))
return new byte[0];
if (m_isGod && m_consoleIsOn)
{
MainConsole.Instance.RunCommand(osd.AsString().Trim());
}
else
{
m_consoleModule.SendConsoleOutput(m_agentID, "Unknown command");
}
return new byte[0];
}
private void ConsoleSender(string text)
{
m_consoleModule.SendConsoleOutput(m_agentID, text);
}
private void OnMakeChildAgent(ScenePresence presence)
{
if (presence.UUID == m_agentID)
{
MainConsole.Instance.OnOutput -= ConsoleSender;
m_consoleIsOn = false;
}
}
}
}

View File

@@ -45,12 +45,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public Packet Packet;
/// <summary>
/// No arg constructor.
/// </summary>
public IncomingPacket() {}
/// <summary>
/// Constructor
/// Default constructor
/// </summary>
/// <param name="client">Reference to the client this packet came from</param>
/// <param name="packet">Packet data</param>

View File

@@ -346,17 +346,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private int m_moneyBalance;
private int m_animationSequenceNumber = 1;
private bool m_SendLogoutPacketWhenClosing = true;
/// <summary>
/// We retain a single AgentUpdateArgs so that we can constantly reuse it rather than construct a new one for
/// every single incoming AgentUpdate. Every client sends 10 AgentUpdate UDP messages per second, even if it
/// is doing absolutely nothing.
/// </summary>
/// <remarks>
/// This does mean that agent updates must be processed synchronously, at least for each client, and called methods
/// cannot retain a reference to it outside of that method.
/// </remarks>
private AgentUpdateArgs m_lastAgentUpdateArgs;
private AgentUpdateArgs lastarg;
protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
@@ -816,9 +806,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(mov, ThrottleOutPacketType.Unknown);
}
public void SendChatMessage(
string message, byte type, Vector3 fromPos, string fromName,
UUID fromAgentID, UUID ownerID, byte source, byte audible)
public void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName,
UUID fromAgentID, byte source, byte audible)
{
ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator);
reply.ChatData.Audible = audible;
@@ -827,7 +816,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
reply.ChatData.SourceType = source;
reply.ChatData.Position = fromPos;
reply.ChatData.FromName = Util.StringToBytes256(fromName);
reply.ChatData.OwnerID = ownerID;
reply.ChatData.OwnerID = fromAgentID;
reply.ChatData.SourceID = fromAgentID;
OutPacket(reply, ThrottleOutPacketType.Task);
@@ -3932,9 +3921,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
ImprovedTerseObjectUpdatePacket packet
= (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation;
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
@@ -3979,10 +3966,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
ImprovedTerseObjectUpdatePacket packet
= (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
PacketType.ImprovedTerseObjectUpdate);
ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation;
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
@@ -4974,9 +4958,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2;
Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2;
ImprovedTerseObjectUpdatePacket.ObjectDataBlock block
= PacketPool.Instance.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
block.Data = data;
if (textureEntry != null && textureEntry.Length > 0)
@@ -5208,18 +5190,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected virtual void RegisterLocalPacketHandlers()
{
AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout);
// If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
// for each AgentUpdate packet.
AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false);
AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest);
AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest);
AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest, false);
AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest, false);
AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage);
AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest);
AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer);
@@ -5439,83 +5417,80 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Scene/Avatar
private bool HandleAgentUpdate(IClientAPI sener, Packet packet)
private bool HandleAgentUpdate(IClientAPI sener, Packet Pack)
{
if (OnAgentUpdate != null)
{
AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
bool update = false;
AgentUpdatePacket agenUpdate = (AgentUpdatePacket)Pack;
#region Packet Session and User Check
if (agentUpdate.AgentData.SessionID != SessionId || agentUpdate.AgentData.AgentID != AgentId)
{
PacketPool.Instance.ReturnPacket(packet);
if (agenUpdate.AgentData.SessionID != SessionId || agenUpdate.AgentData.AgentID != AgentId)
return false;
}
#endregion
bool update = false;
AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData;
AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData;
if (m_lastAgentUpdateArgs != null)
// We can only check when we have something to check
// against.
if (lastarg != null)
{
// These should be ordered from most-likely to
// least likely to change. I've made an initial
// guess at that.
update =
(
(x.BodyRotation != m_lastAgentUpdateArgs.BodyRotation) ||
(x.CameraAtAxis != m_lastAgentUpdateArgs.CameraAtAxis) ||
(x.CameraCenter != m_lastAgentUpdateArgs.CameraCenter) ||
(x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
(x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
(x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
(x.Far != m_lastAgentUpdateArgs.Far) ||
(x.Flags != m_lastAgentUpdateArgs.Flags) ||
(x.State != m_lastAgentUpdateArgs.State) ||
(x.HeadRotation != m_lastAgentUpdateArgs.HeadRotation) ||
(x.SessionID != m_lastAgentUpdateArgs.SessionID) ||
(x.AgentID != m_lastAgentUpdateArgs.AgentID)
(x.BodyRotation != lastarg.BodyRotation) ||
(x.CameraAtAxis != lastarg.CameraAtAxis) ||
(x.CameraCenter != lastarg.CameraCenter) ||
(x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
(x.CameraUpAxis != lastarg.CameraUpAxis) ||
(x.ControlFlags != lastarg.ControlFlags) ||
(x.Far != lastarg.Far) ||
(x.Flags != lastarg.Flags) ||
(x.State != lastarg.State) ||
(x.HeadRotation != lastarg.HeadRotation) ||
(x.SessionID != lastarg.SessionID) ||
(x.AgentID != lastarg.AgentID)
);
}
else
{
m_lastAgentUpdateArgs = new AgentUpdateArgs();
update = true;
}
// These should be ordered from most-likely to
// least likely to change. I've made an initial
// guess at that.
if (update)
{
// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name);
m_lastAgentUpdateArgs.AgentID = x.AgentID;
m_lastAgentUpdateArgs.BodyRotation = x.BodyRotation;
m_lastAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis;
m_lastAgentUpdateArgs.CameraCenter = x.CameraCenter;
m_lastAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis;
m_lastAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis;
m_lastAgentUpdateArgs.ControlFlags = x.ControlFlags;
m_lastAgentUpdateArgs.Far = x.Far;
m_lastAgentUpdateArgs.Flags = x.Flags;
m_lastAgentUpdateArgs.HeadRotation = x.HeadRotation;
m_lastAgentUpdateArgs.SessionID = x.SessionID;
m_lastAgentUpdateArgs.State = x.State;
AgentUpdateArgs arg = new AgentUpdateArgs();
arg.AgentID = x.AgentID;
arg.BodyRotation = x.BodyRotation;
arg.CameraAtAxis = x.CameraAtAxis;
arg.CameraCenter = x.CameraCenter;
arg.CameraLeftAxis = x.CameraLeftAxis;
arg.CameraUpAxis = x.CameraUpAxis;
arg.ControlFlags = x.ControlFlags;
arg.Far = x.Far;
arg.Flags = x.Flags;
arg.HeadRotation = x.HeadRotation;
arg.SessionID = x.SessionID;
arg.State = x.State;
UpdateAgent handlerAgentUpdate = OnAgentUpdate;
UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate;
lastarg = arg; // save this set of arguments for nexttime
if (handlerPreAgentUpdate != null)
OnPreAgentUpdate(this, m_lastAgentUpdateArgs);
OnPreAgentUpdate(this, arg);
if (handlerAgentUpdate != null)
OnAgentUpdate(this, m_lastAgentUpdateArgs);
OnAgentUpdate(this, arg);
handlerAgentUpdate = null;
handlerPreAgentUpdate = null;
}
}
PacketPool.Instance.ReturnPacket(packet);
return true;
}
@@ -9079,9 +9054,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
#endregion
string method = Utils.BytesToString(messagePacket.MethodData.Method);
switch (method)
switch (Utils.BytesToString(messagePacket.MethodData.Method))
{
case "getinfo":
if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
@@ -9397,17 +9370,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true;
default:
m_log.WarnFormat(
"[LLCLIENTVIEW]: EstateOwnerMessage: Unknown method {0} requested for {1} in {2}",
method, Name, Scene.Name);
for (int i = 0; i < messagePacket.ParamList.Length; i++)
{
EstateOwnerMessagePacket.ParamListBlock block = messagePacket.ParamList[i];
string data = (string)Utils.BytesToString(block.Parameter);
m_log.DebugFormat("[LLCLIENTVIEW]: Param {0}={1}", i, data);
}
m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket);
return true;
}
@@ -11793,7 +11756,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
logPacket = false;
if (DebugPacketLevel <= 50
&& (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
& (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
logPacket = false;
if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily)
@@ -11867,6 +11830,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (!ProcessPacketMethod(packet))
m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
PacketPool.Instance.ReturnPacket(packet);
}
private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket)
@@ -12319,10 +12284,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
ImprovedTerseObjectUpdatePacket packet
= (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
PacketType.ImprovedTerseObjectUpdate);
ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation;
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];

View File

@@ -37,7 +37,6 @@ using log4net;
using Nini.Config;
using OpenMetaverse.Packets;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Scenes;
using OpenMetaverse;
@@ -101,11 +100,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>The measured resolution of Environment.TickCount</summary>
public readonly float TickCountResolution;
/// <summary>Number of prim updates to put on the queue each time the
/// OnQueueEmpty event is triggered for updates</summary>
public readonly int PrimUpdatesPerCallback;
/// <summary>Number of texture packets to put on the queue each time the
/// OnQueueEmpty event is triggered for textures</summary>
public readonly int TextureSendLimit;
@@ -114,7 +111,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//PacketEventDictionary packetEvents = new PacketEventDictionary();
/// <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>
@@ -125,37 +121,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <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;
/// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary>
private Location m_location;
/// <summary>The size of the receive buffer for the UDP socket. This value
/// is passed up to the operating system and used in the system networking
/// stack. Use zero to leave this value as the default</summary>
private int m_recvBufferSize;
/// <summary>Flag to process packets asynchronously or synchronously</summary>
private bool m_asyncPacketHandling;
/// <summary>Tracks whether or not a packet was sent each round so we know
/// whether or not to sleep</summary>
private bool m_packetSent;
/// <summary>Environment.TickCount of the last time that packet stats were reported to the scene</summary>
private int m_elapsedMSSinceLastStatReport = 0;
/// <summary>Environment.TickCount of the last time the outgoing packet handler executed</summary>
private int m_tickLastOutgoingPacketHandler;
/// <summary>Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler looped</summary>
private int m_elapsedMSOutgoingPacketHandler;
/// <summary>Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed</summary>
private int m_elapsed100MSOutgoingPacketHandler;
/// <summary>Keeps track of the number of 500 millisecond periods elapsed in the outgoing packet handler executed</summary>
private int m_elapsed500MSOutgoingPacketHandler;
@@ -168,10 +155,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Flag to signal when clients should send pings</summary>
protected bool m_sendPing;
private Pool<IncomingPacket> m_incomingPacketPool;
private Stat m_incomingPacketPoolStat;
private int m_defaultRTO = 0;
private int m_maxRTO = 0;
private int m_ackTimeout = 0;
@@ -192,9 +175,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary>
private IClientAPI m_currentIncomingClient;
public LLUDPServer(
IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port,
IConfigSource configSource, AgentCircuitManager circuitManager)
public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
: base(listenIP, (int)port)
{
#region Environment.TickCount Measurement
@@ -216,7 +197,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_circuitManager = circuitManager;
int sceneThrottleBps = 0;
bool usePools = false;
IConfig config = configSource.Configs["ClientStack.LindenUDP"];
if (config != null)
@@ -242,16 +222,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_pausedAckTimeout = 1000 * 300; // 5 minutes
}
// FIXME: This actually only needs to be done once since the PacketPool is shared across all servers.
// However, there is no harm in temporarily doing it multiple times.
IConfig packetConfig = configSource.Configs["PacketPool"];
if (packetConfig != null)
{
PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
usePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", usePools);
}
#region BinaryStats
config = configSource.Configs["Statistics.Binary"];
m_shouldCollectStats = false;
@@ -279,28 +249,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_throttle = new TokenBucket(null, sceneThrottleBps);
ThrottleRates = new ThrottleRates(configSource);
if (usePools)
EnablePools();
}
public void Start()
{
StartInbound();
StartOutbound();
if (m_scene == null)
throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference");
m_elapsedMSSinceLastStatReport = Environment.TickCount;
}
private void StartInbound()
{
m_log.InfoFormat(
"[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}",
m_asyncPacketHandling ? "asynchronous" : "synchronous", UsePools);
"[LLUDPSERVER]: Starting the LLUDP server in {0} mode",
m_asyncPacketHandling ? "asynchronous" : "synchronous");
base.StartInbound(m_recvBufferSize, m_asyncPacketHandling);
base.Start(m_recvBufferSize, m_asyncPacketHandling);
// This thread will process the packets received that are placed on the packetInbox
// Start the packet processing threads
Watchdog.StartThread(
IncomingPacketHandler,
string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName),
@@ -309,13 +271,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
true,
GetWatchdogIncomingAlarmData,
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
}
private new void StartOutbound()
{
m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server");
base.StartOutbound();
Watchdog.StartThread(
OutgoingPacketHandler,
@@ -325,57 +280,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
true,
GetWatchdogOutgoingAlarmData,
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
}
public void Stop()
{
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
base.StopOutbound();
base.StopInbound();
}
protected override bool EnablePools()
{
if (!UsePools)
{
base.EnablePools();
m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500);
m_incomingPacketPoolStat
= new Stat(
"IncomingPacketPoolCount",
"Objects within incoming packet pool",
"The number of objects currently stored within the incoming packet pool",
"",
"clientstack",
"packetpool",
StatType.Pull,
stat => stat.Value = m_incomingPacketPool.Count,
StatVerbosity.Debug);
StatsManager.RegisterStat(m_incomingPacketPoolStat);
return true;
}
return false;
}
protected override bool DisablePools()
{
if (UsePools)
{
base.DisablePools();
StatsManager.DeregisterStat(m_incomingPacketPoolStat);
// We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
return true;
}
return false;
m_elapsedMSSinceLastStatReport = Environment.TickCount;
}
/// <summary>
@@ -400,6 +306,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none");
}
public new void Stop()
{
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
base.Stop();
}
public void AddScene(IScene scene)
{
if (m_scene != null)
@@ -416,117 +328,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_scene = (Scene)scene;
m_location = new Location(m_scene.RegionInfo.RegionHandle);
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);
}
private void HandleStartCommand(string module, string[] args)
{
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 (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 (args.Length != 4)
{
MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
return;
}
string enabled = args[3];
if (enabled == "on")
{
if (EnablePools())
MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name);
}
else if (enabled == "off")
{
if (DisablePools())
MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name);
}
else
{
MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
}
}
private void HandleStatusCommand(string module, string[] args)
{
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");
}
public bool HandlesRegion(Location x)
@@ -610,8 +411,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
byte[] data = packet.ToBytes();
SendPacketData(udpClient, data, packet.Type, category, method);
}
PacketPool.Instance.ReturnPacket(packet);
}
/// <summary>
@@ -896,7 +695,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
LLUDPClient udpClient = null;
Packet packet = null;
int packetEnd = buffer.DataLength - 1;
IPEndPoint endPoint = (IPEndPoint)buffer.RemoteEndPoint;
IPEndPoint address = (IPEndPoint)buffer.RemoteEndPoint;
#region Decoding
@@ -906,7 +705,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}",
// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
return; // Drop undersized packet
return; // Drop undersizd packet
}
int headerLen = 7;
@@ -929,13 +728,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
try
{
// packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
// // Only allocate a buffer for zerodecoding if the packet is zerocoded
// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
// If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we
// assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all
// bytes are copied out).
packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd,
packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
// Only allocate a buffer for zerodecoding if the packet is zerocoded
((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
}
@@ -950,13 +743,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return; // Drop short packet
}
catch (Exception e)
catch(Exception e)
{
if (m_malformedCount < 100)
m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString());
m_malformedCount++;
if ((m_malformedCount % 100000) == 0)
m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount);
}
@@ -977,9 +768,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// UseCircuitCode handling
if (packet.Type == PacketType.UseCircuitCode)
{
// We need to copy the endpoint so that it doesn't get changed when another thread reuses the
// buffer.
object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
object[] array = new object[] { buffer, packet };
Util.FireAndForget(HandleUseCircuitCode, array);
@@ -988,7 +777,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 (!m_scene.TryGetClient(address, out client) || !(client is LLClientView))
{
//m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
return;
@@ -1012,10 +801,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Handle appended ACKs
if (packet.Header.AppendedAcks && packet.Header.AckList != null)
{
// m_log.DebugFormat(
// "[LLUDPSERVER]: Handling {0} appended acks from {1} in {2}",
// packet.Header.AckList.Length, client.Name, m_scene.Name);
for (int i = 0; i < packet.Header.AckList.Length; i++)
udpClient.NeedAcks.Acknowledge(packet.Header.AckList[i], now, packet.Header.Resent);
}
@@ -1025,10 +810,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
PacketAckPacket ackPacket = (PacketAckPacket)packet;
// m_log.DebugFormat(
// "[LLUDPSERVER]: Handling {0} packet acks for {1} in {2}",
// ackPacket.Packets.Length, client.Name, m_scene.Name);
for (int i = 0; i < ackPacket.Packets.Length; i++)
udpClient.NeedAcks.Acknowledge(ackPacket.Packets[i].ID, now, packet.Header.Resent);
@@ -1042,10 +823,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (packet.Header.Reliable)
{
// m_log.DebugFormat(
// "[LLUDPSERVER]: Adding ack request for {0} {1} from {2} in {3}",
// packet.Type, packet.Header.Sequence, client.Name, m_scene.Name);
udpClient.PendingAcks.Enqueue(packet.Header.Sequence);
// This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out,
@@ -1092,8 +869,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (packet.Type == PacketType.StartPingCheck)
{
// m_log.DebugFormat("[LLUDPSERVER]: Handling ping from {0} in {1}", client.Name, m_scene.Name);
// We don't need to do anything else with ping checks
StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
CompletePing(udpClient, startPing.PingID.PingID);
@@ -1113,21 +888,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion Ping Check Handling
IncomingPacket incomingPacket;
// Inbox insertion
if (UsePools)
{
incomingPacket = m_incomingPacketPool.GetObject();
incomingPacket.Client = (LLClientView)client;
incomingPacket.Packet = packet;
}
else
{
incomingPacket = new IncomingPacket((LLClientView)client, packet);
}
packetInbox.Enqueue(incomingPacket);
packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet));
}
#region BinaryStats
@@ -1213,19 +975,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private void HandleUseCircuitCode(object o)
{
IPEndPoint endPoint = null;
IPEndPoint remoteEndPoint = null;
IClientAPI client = null;
try
{
// DateTime startTime = DateTime.Now;
object[] array = (object[])o;
endPoint = (IPEndPoint)array[0];
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
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, m_scene.RegionInfo.RegionName, buffer.RemoteEndPoint);
remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
AuthenticateResponse sessionInfo;
if (IsClientAuthorized(uccp, out sessionInfo))
@@ -1236,13 +1000,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
uccp.CircuitCode.Code,
uccp.CircuitCode.ID,
uccp.CircuitCode.SessionID,
endPoint,
remoteEndPoint,
sessionInfo);
// Send ack straight away to let the viewer know that the connection is active.
// The client will be null if it already exists (e.g. if on a region crossing the client sends a use
// circuit code to the existing child agent. This is not particularly obvious.
SendAckImmediate(endPoint, uccp.Header.Sequence);
SendAckImmediate(remoteEndPoint, uccp.Header.Sequence);
// We only want to send initial data to new clients, not ones which are being converted from child to root.
if (client != null)
@@ -1253,7 +1017,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, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint);
}
// m_log.DebugFormat(
@@ -1265,7 +1029,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
m_log.ErrorFormat(
"[LLUDPSERVER]: UseCircuitCode handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
endPoint != null ? endPoint.ToString() : "n/a",
remoteEndPoint != null ? remoteEndPoint.ToString() : "n/a",
client != null ? client.Name : "unknown",
client != null ? client.AgentId.ToString() : "unknown",
e.Message,
@@ -1330,20 +1094,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
IClientAPI client = null;
// We currently synchronize this code across the whole scene to avoid issues such as
// http://opensimulator.org/mantis/view.php?id=5365 However, once locking per agent circuit can be done
// consistently, this lock could probably be removed.
lock (this)
// In priciple there shouldn't be more than one thread here, ever.
// But in case that happens, we need to synchronize this piece of code
// because it's too important
lock (this)
{
if (!m_scene.TryGetClient(agentID, out client))
{
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client.OnLogout += LogoutHandler;
((LLClientView)client).DisableFacelights = m_disableFacelights;
client.Start();
}
}
@@ -1382,7 +1146,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// on to en-US to avoid number parsing issues
Culture.SetCurrentCulture();
while (IsRunningInbound)
while (base.IsRunning)
{
try
{
@@ -1397,12 +1161,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
if (packetInbox.Dequeue(100, ref incomingPacket))
{
ProcessInPacket(incomingPacket);//, incomingPacket); Util.FireAndForget(ProcessInPacket, incomingPacket);
if (UsePools)
m_incomingPacketPool.ReturnObject(incomingPacket);
}
}
catch (Exception ex)
{
@@ -1429,7 +1188,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Action generic every round
Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler;
while (base.IsRunningOutbound)
while (base.IsRunning)
{
try
{

View File

@@ -30,8 +30,6 @@ using System.Net;
using System.Net.Sockets;
using System.Threading;
using log4net;
using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
namespace OpenMetaverse
{
@@ -60,31 +58,17 @@ namespace OpenMetaverse
/// <summary>Flag to process packets asynchronously or synchronously</summary>
private bool m_asyncPacketHandling;
/// <summary>
/// Pool to use for handling data. May be null if UsePools = false;
/// </summary>
protected OpenSim.Framework.Pool<UDPPacketBuffer> m_pool;
/// <summary>The all important shutdown flag</summary>
private volatile bool m_shutdownFlag = true;
/// <summary>
/// Are we to use object pool(s) to reduce memory churn when receiving data?
/// </summary>
public bool UsePools { get; protected set; }
/// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary>
public bool IsRunningInbound { get; private set; }
/// <summary>Returns true if the server is currently sending outbound packets, otherwise false</summary>
/// <remarks>If IsRunningOut = false, then any request to send a packet is simply dropped.</remarks>
public bool IsRunningOutbound { get; private set; }
private Stat m_poolCountStat;
/// <summary>Returns true if the server is currently listening, otherwise false</summary>
public bool IsRunning { get { return !m_shutdownFlag; } }
/// <summary>
/// Default constructor
/// </summary>
/// <param name="bindAddress">Local IP address to bind the server to</param>
/// <param name="port">Port to listening for incoming UDP packets on</param>
/// /// <param name="usePool">Are we to use an object pool to get objects for handing inbound data?</param>
public OpenSimUDPBase(IPAddress bindAddress, int port)
{
m_localBindAddress = bindAddress;
@@ -92,7 +76,7 @@ namespace OpenMetaverse
}
/// <summary>
/// Start inbound UDP packet handling.
/// Start the UDP server
/// </summary>
/// <param name="recvBufferSize">The size of the receive buffer for
/// the UDP socket. This value is passed up to the operating system
@@ -107,11 +91,11 @@ 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 void Start(int recvBufferSize, bool asyncPacketHandling)
{
m_asyncPacketHandling = asyncPacketHandling;
if (!IsRunningInbound)
if (m_shutdownFlag)
{
const int SIO_UDP_CONNRESET = -1744830452;
@@ -143,7 +127,8 @@ namespace OpenMetaverse
m_udpSocket.Bind(ipep);
IsRunningInbound = true;
// we're not shutting down, we're starting up
m_shutdownFlag = false;
// kick off an async receive. The Start() method will return, the
// actual receives will occur asynchronously and will be caught in
@@ -153,84 +138,28 @@ namespace OpenMetaverse
}
/// <summary>
/// Start outbound UDP packet handling.
/// Stops the UDP server
/// </summary>
public void StartOutbound()
public void Stop()
{
IsRunningOutbound = true;
}
public void StopInbound()
{
if (IsRunningInbound)
if (!m_shutdownFlag)
{
// wait indefinitely for a writer lock. Once this is called, the .NET runtime
// will deny any more reader locks, in effect blocking all other send/receive
// threads. Once we have the lock, we set IsRunningInbound = false to inform the other
// threads. Once we have the lock, we set shutdownFlag to inform the other
// threads that the socket is closed.
IsRunningInbound = false;
m_shutdownFlag = true;
m_udpSocket.Close();
}
}
public void StopOutbound()
{
IsRunningOutbound = false;
}
protected virtual bool EnablePools()
{
if (!UsePools)
{
m_pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500);
m_poolCountStat
= new Stat(
"UDPPacketBufferPoolCount",
"Objects within the UDPPacketBuffer pool",
"The number of objects currently stored within the UDPPacketBuffer pool",
"",
"clientstack",
"packetpool",
StatType.Pull,
stat => stat.Value = m_pool.Count,
StatVerbosity.Debug);
StatsManager.RegisterStat(m_poolCountStat);
UsePools = true;
return true;
}
return false;
}
protected virtual bool DisablePools()
{
if (UsePools)
{
UsePools = false;
StatsManager.DeregisterStat(m_poolCountStat);
// We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
return true;
}
return false;
}
private void AsyncBeginReceive()
{
UDPPacketBuffer buf;
// allocate a packet buffer
//WrappedObject<UDPPacketBuffer> wrappedBuffer = Pool.CheckOut();
UDPPacketBuffer buf = new UDPPacketBuffer();
if (UsePools)
buf = m_pool.GetObject();
else
buf = new UDPPacketBuffer();
if (IsRunningInbound)
if (!m_shutdownFlag)
{
try
{
@@ -283,7 +212,7 @@ namespace OpenMetaverse
{
// Asynchronous receive operations will complete here through the call
// to AsyncBeginReceive
if (IsRunningInbound)
if (!m_shutdownFlag)
{
// Asynchronous mode will start another receive before the
// callback for this packet is even fired. Very parallel :-)
@@ -292,6 +221,8 @@ namespace OpenMetaverse
// get the buffer that was created in AsyncBeginReceive
// this is the received data
//WrappedObject<UDPPacketBuffer> wrappedBuffer = (WrappedObject<UDPPacketBuffer>)iar.AsyncState;
//UDPPacketBuffer buffer = wrappedBuffer.Instance;
UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState;
try
@@ -308,8 +239,7 @@ namespace OpenMetaverse
catch (ObjectDisposedException) { }
finally
{
if (UsePools)
m_pool.ReturnObject(buffer);
//wrappedBuffer.Dispose();
// Synchronous mode waits until the packet callback completes
// before starting the receive to fetch another packet
@@ -322,7 +252,7 @@ namespace OpenMetaverse
public void AsyncBeginSend(UDPPacketBuffer buf)
{
if (IsRunningOutbound)
if (!m_shutdownFlag)
{
try
{

View File

@@ -43,7 +43,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
/// This will contain basic tests for the LindenUDP client stack
/// </summary>
[TestFixture]
public class BasicCircuitTests : OpenSimTestCase
public class BasicCircuitTests
{
private Scene m_scene;
private TestLLUDPServer m_udpServer;
@@ -65,9 +65,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
}
[SetUp]
public override void SetUp()
public void SetUp()
{
base.SetUp();
m_scene = new SceneHelpers().SetupScene();
}
@@ -144,7 +143,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
public void TestAddClient()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
// XmlConfigurator.Configure();
AddUdpServer();

View File

@@ -57,36 +57,39 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
}
/// <summary>
/// Return the xfer uploader for the given transaction.
/// Return a xfer uploader if one does not already exist.
/// </summary>
/// <remarks>
/// If an uploader does not already exist for this transaction then it is created, otherwise the existing
/// uploader is returned.
/// </remarks>
/// <param name="transactionID"></param>
/// <returns>The asset xfer uploader</returns>
public AssetXferUploader RequestXferUploader(UUID transactionID)
/// <param name="assetID">
/// We must transfer the new asset ID into the uploader on creation, otherwise
/// we can see race conditions with other threads which can retrieve an item before it is updated with the new
/// asset id.
/// </param>
/// <returns>
/// The xfer uploader requested. Null if one is already in existence.
/// FIXME: This is a bizarre thing to do, and is probably meant to signal an error condition if multiple
/// transfers are made. Needs to be corrected.
/// </returns>
public AssetXferUploader RequestXferUploader(UUID transactionID, UUID assetID)
{
AssetXferUploader uploader;
lock (XferUploaders)
{
if (!XferUploaders.ContainsKey(transactionID))
{
uploader = new AssetXferUploader(this, m_Scene, transactionID, m_dumpAssetsToFile);
AssetXferUploader uploader = new AssetXferUploader(this, m_Scene, assetID, m_dumpAssetsToFile);
// m_log.DebugFormat(
// "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID);
XferUploaders.Add(transactionID, uploader);
}
else
{
uploader = XferUploaders[transactionID];
return uploader;
}
}
return uploader;
m_log.WarnFormat("[AGENT ASSETS TRANSACTIONS]: Ignoring request for asset xfer uploader {0} since it already exists", transactionID);
return null;
}
public void HandleXfer(ulong xferID, uint packetID, byte[] data)
@@ -148,28 +151,115 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
string description, string name, sbyte invType,
sbyte type, byte wearableType, uint nextOwnerMask)
{
AssetXferUploader uploader = RequestXferUploader(transactionID);
AssetXferUploader uploader = null;
uploader.RequestCreateInventoryItem(
remoteClient, folderID, callbackID,
description, name, invType, type, wearableType, nextOwnerMask);
lock (XferUploaders)
{
if (XferUploaders.ContainsKey(transactionID))
uploader = XferUploaders[transactionID];
}
if (uploader != null)
uploader.RequestCreateInventoryItem(
remoteClient, transactionID, folderID,
callbackID, description, name, invType, type,
wearableType, nextOwnerMask);
else
m_log.ErrorFormat(
"[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to create inventory item {1} from {2}",
transactionID, name, remoteClient.Name);
}
/// <summary>
/// Get an uploaded asset. If the data is successfully retrieved,
/// the transaction will be removed.
/// </summary>
/// <param name="transactionID"></param>
/// <returns>The asset if the upload has completed, null if it has not.</returns>
private AssetBase GetTransactionAsset(UUID transactionID)
{
lock (XferUploaders)
{
if (XferUploaders.ContainsKey(transactionID))
{
AssetXferUploader uploader = XferUploaders[transactionID];
AssetBase asset = uploader.GetAssetData();
RemoveXferUploader(transactionID);
return asset;
}
}
return null;
}
public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient,
SceneObjectPart part, UUID transactionID,
TaskInventoryItem item)
{
AssetXferUploader uploader = RequestXferUploader(transactionID);
AssetXferUploader uploader = null;
uploader.RequestUpdateTaskInventoryItem(remoteClient, item);
lock (XferUploaders)
{
if (XferUploaders.ContainsKey(transactionID))
uploader = XferUploaders[transactionID];
}
if (uploader != null)
{
AssetBase asset = GetTransactionAsset(transactionID);
// Only legacy viewers use this, and they prefer CAPS, which
// we have, so this really never runs.
// Allow it, but only for "safe" types.
if ((InventoryType)item.InvType != InventoryType.Notecard &&
(InventoryType)item.InvType != InventoryType.LSL)
return;
if (asset != null)
{
// m_log.DebugFormat(
// "[AGENT ASSETS TRANSACTIONS]: Updating item {0} in {1} for transaction {2}",
// item.Name, part.Name, transactionID);
asset.FullID = UUID.Random();
asset.Name = item.Name;
asset.Description = item.Description;
asset.Type = (sbyte)item.Type;
item.AssetID = asset.FullID;
m_Scene.AssetService.Store(asset);
}
}
else
{
m_log.ErrorFormat(
"[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update task inventory item {1} in {2}",
transactionID, item.Name, part.Name);
}
}
public void RequestUpdateInventoryItem(IClientAPI remoteClient,
UUID transactionID, InventoryItemBase item)
{
AssetXferUploader uploader = RequestXferUploader(transactionID);
AssetXferUploader uploader = null;
uploader.RequestUpdateInventoryItem(remoteClient, item);
lock (XferUploaders)
{
if (XferUploaders.ContainsKey(transactionID))
uploader = XferUploaders[transactionID];
}
if (uploader != null)
{
uploader.RequestUpdateInventoryItem(remoteClient, transactionID, item);
}
else
{
m_log.ErrorFormat(
"[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update inventory item {1} for {2}",
transactionID, item.Name, remoteClient.Name);
}
}
}
}
}

View File

@@ -215,7 +215,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item)
{
m_log.DebugFormat(
"[ASSET TRANSACTION MODULE] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}",
"[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}",
item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName);
AgentAssetTransactions transactions =
@@ -274,8 +274,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
}
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
uploader.StartUpload(remoteClient, assetID, transaction, type, data, storeLocal, tempFile);
AssetXferUploader uploader = transactions.RequestXferUploader(transaction, assetID);
if (uploader != null)
{
uploader.Initialise(remoteClient, assetID, transaction, type,
data, storeLocal, tempFile);
}
}
/// <summary>

View File

@@ -40,75 +40,39 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Upload state.
/// </summary>
/// <remarks>
/// New -> Uploading -> Complete
/// </remarks>
private enum UploadState
{
New,
Uploading,
Complete
}
/// <summary>
/// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we
/// are performing a delayed update.
/// </summary>
AgentAssetTransactions m_transactions;
private UploadState m_uploadState = UploadState.New;
private AssetBase m_asset;
private UUID InventFolder = UUID.Zero;
private sbyte invType = 0;
private bool m_createItem;
private uint m_createItemCallback;
private bool m_updateItem;
private bool m_createItem = false;
private uint m_createItemCallback = 0;
private bool m_updateItem = false;
private InventoryItemBase m_updateItemData;
private bool m_updateTaskItem;
private TaskInventoryItem m_updateTaskItemData;
private string m_description = String.Empty;
private bool m_dumpAssetToFile;
private bool m_finished = false;
private string m_name = String.Empty;
// private bool m_storeLocal;
private bool m_storeLocal;
private uint nextPerm = 0;
private IClientAPI ourClient;
private UUID m_transactionID;
private UUID TransactionID = UUID.Zero;
private sbyte type = 0;
private byte wearableType = 0;
public ulong XferID;
private Scene m_Scene;
/// <summary>
/// AssetXferUploader constructor
/// </summary>
/// <param name='transactions'>/param>
/// <param name='scene'></param>
/// <param name='transactionID'></param>
/// <param name='dumpAssetToFile'>
/// If true then when the asset is uploaded it is dumped to a file with the format
/// String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat",
/// now.Year, now.Month, now.Day, now.Hour, now.Minute,
/// now.Second, m_asset.Name, m_asset.Type);
/// for debugging purposes.
/// </param>
public AssetXferUploader(
AgentAssetTransactions transactions, Scene scene, UUID transactionID, bool dumpAssetToFile)
public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile)
{
m_asset = new AssetBase();
m_transactions = transactions;
m_transactionID = transactionID;
m_Scene = scene;
m_asset = new AssetBase() { FullID = assetID };
m_dumpAssetToFile = dumpAssetToFile;
}
@@ -154,50 +118,30 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
}
/// <summary>
/// Start asset transfer from the client
/// Initialise asset transfer from the client
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="assetID"></param>
/// <param name="transaction"></param>
/// <param name="type"></param>
/// <param name="data">
/// Optional data. If present then the asset is created immediately with this data
/// rather than requesting an upload from the client. The data must be longer than 2 bytes.
/// </param>
/// <param name="storeLocal"></param>
/// <param name="tempFile"></param>
public void StartUpload(
IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, bool storeLocal,
bool tempFile)
/// <param name="xferID"></param>
/// <param name="packetID"></param>
/// <param name="data"></param>
public void Initialise(IClientAPI remoteClient, UUID assetID,
UUID transaction, sbyte type, byte[] data, bool storeLocal,
bool tempFile)
{
// m_log.DebugFormat(
// "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}",
// remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length);
lock (this)
{
if (m_uploadState != UploadState.New)
{
m_log.WarnFormat(
"[ASSET XFER UPLOADER]: Tried to start upload of asset {0}, transaction {1} for {2} but this is already in state {3}. Aborting.",
assetID, transaction, remoteClient.Name, m_uploadState);
return;
}
m_uploadState = UploadState.Uploading;
}
ourClient = remoteClient;
m_asset.FullID = assetID;
m_asset.Name = "blank";
m_asset.Description = "empty";
m_asset.Type = type;
m_asset.CreatorID = remoteClient.AgentId.ToString();
m_asset.Data = data;
m_asset.Local = storeLocal;
m_asset.Temporary = tempFile;
// m_storeLocal = storeLocal;
TransactionID = transaction;
m_storeLocal = storeLocal;
if (m_asset.Data.Length > 2)
{
@@ -222,35 +166,36 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
protected void SendCompleteMessage()
{
ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true,
m_asset.FullID);
// We must lock in order to avoid a race with a separate thread dealing with an inventory item or create
// message from other client UDP.
lock (this)
{
m_uploadState = UploadState.Complete;
ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID);
m_finished = true;
if (m_createItem)
{
CompleteCreateItem(m_createItemCallback);
DoCreateItem(m_createItemCallback);
}
else if (m_updateItem)
{
CompleteItemUpdate(m_updateItemData);
StoreAssetForItemUpdate(m_updateItemData);
// Remove ourselves from the list of transactions if completion was delayed until the transaction
// was complete.
// TODO: Should probably do the same for create item.
m_transactions.RemoveXferUploader(TransactionID);
}
else if (m_updateTaskItem)
else if (m_storeLocal)
{
CompleteTaskItemUpdate(m_updateTaskItemData);
m_Scene.AssetService.Store(m_asset);
}
// else if (m_storeLocal)
// {
// m_Scene.AssetService.Store(m_asset);
// }
}
m_log.DebugFormat(
"[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}",
m_asset.FullID, m_transactionID);
m_asset.FullID, TransactionID);
if (m_dumpAssetToFile)
{
@@ -278,37 +223,40 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
}
public void RequestCreateInventoryItem(IClientAPI remoteClient,
UUID folderID, uint callbackID,
UUID transactionID, UUID folderID, uint callbackID,
string description, string name, sbyte invType,
sbyte type, byte wearableType, uint nextOwnerMask)
{
InventFolder = folderID;
m_name = name;
m_description = description;
this.type = type;
this.invType = invType;
this.wearableType = wearableType;
nextPerm = nextOwnerMask;
m_asset.Name = name;
m_asset.Description = description;
m_asset.Type = type;
// We must lock to avoid a race with a separate thread uploading the asset.
lock (this)
if (TransactionID == transactionID)
{
if (m_uploadState == UploadState.Complete)
InventFolder = folderID;
m_name = name;
m_description = description;
this.type = type;
this.invType = invType;
this.wearableType = wearableType;
nextPerm = nextOwnerMask;
m_asset.Name = name;
m_asset.Description = description;
m_asset.Type = type;
// We must lock to avoid a race with a separate thread uploading the asset.
lock (this)
{
CompleteCreateItem(callbackID);
}
else
{
m_createItem = true; //set flag so the inventory item is created when upload is complete
m_createItemCallback = callbackID;
if (m_finished)
{
DoCreateItem(callbackID);
}
else
{
m_createItem = true; //set flag so the inventory item is created when upload is complete
m_createItemCallback = callbackID;
}
}
}
}
public void RequestUpdateInventoryItem(IClientAPI remoteClient, InventoryItemBase item)
public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item)
{
// We must lock to avoid a race with a separate thread uploading the asset.
lock (this)
@@ -323,9 +271,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
item.AssetID = m_asset.FullID;
m_Scene.InventoryService.UpdateItem(item);
if (m_uploadState == UploadState.Complete)
if (m_finished)
{
CompleteItemUpdate(item);
StoreAssetForItemUpdate(item);
}
else
{
@@ -339,59 +287,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
}
}
public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, TaskInventoryItem taskItem)
{
// We must lock to avoid a race with a separate thread uploading the asset.
lock (this)
{
m_asset.Name = taskItem.Name;
m_asset.Description = taskItem.Description;
m_asset.Type = (sbyte)taskItem.Type;
taskItem.AssetID = m_asset.FullID;
if (m_uploadState == UploadState.Complete)
{
CompleteTaskItemUpdate(taskItem);
}
else
{
m_updateTaskItem = true;
m_updateTaskItemData = taskItem;
}
}
}
/// <summary>
/// Store the asset for the given item when it has been uploaded.
/// Store the asset for the given item.
/// </summary>
/// <param name="item"></param>
private void CompleteItemUpdate(InventoryItemBase item)
private void StoreAssetForItemUpdate(InventoryItemBase item)
{
// m_log.DebugFormat(
// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
// m_asset.FullID, item.Name, ourClient.Name);
m_Scene.AssetService.Store(m_asset);
m_transactions.RemoveXferUploader(m_transactionID);
}
/// <summary>
/// Store the asset for the given task item when it has been uploaded.
/// </summary>
/// <param name="taskItem"></param>
private void CompleteTaskItemUpdate(TaskInventoryItem taskItem)
{
// m_log.DebugFormat(
// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}",
// m_asset.FullID, taskItem.Name, ourClient.Name);
m_Scene.AssetService.Store(m_asset);
m_transactions.RemoveXferUploader(m_transactionID);
}
private void CompleteCreateItem(uint callbackID)
private void DoCreateItem(uint callbackID)
{
m_Scene.AssetService.Store(m_asset);
@@ -417,8 +326,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
ourClient.SendInventoryItemCreateUpdate(item, callbackID);
else
ourClient.SendAlertMessage("Unable to create inventory item");
}
m_transactions.RemoveXferUploader(m_transactionID);
/// <summary>
/// Get the asset data uploaded in this transfer.
/// </summary>
/// <returns>null if the asset has not finished uploading</returns>
public AssetBase GetAssetData()
{
if (m_finished)
{
return m_asset;
}
return null;
}
}
}
}

View File

@@ -107,6 +107,8 @@ namespace Flotsam.RegionModules.AssetCache
private IAssetService m_AssetService;
private List<Scene> m_Scenes = new List<Scene>();
private bool m_DeepScanBeforePurge;
public FlotsamAssetCache()
{
m_InvalidChars.AddRange(Path.GetInvalidPathChars());
@@ -168,6 +170,8 @@ namespace Flotsam.RegionModules.AssetCache
m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", m_CacheDirectoryTierLen);
m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", m_CacheWarnAt);
m_DeepScanBeforePurge = assetConfig.GetBoolean("DeepScanBeforePurge", m_DeepScanBeforePurge);
}
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory);
@@ -502,10 +506,13 @@ namespace Flotsam.RegionModules.AssetCache
// Purge all files last accessed prior to this point
DateTime purgeLine = DateTime.Now - m_FileExpiration;
// An asset cache may contain local non-temporary assets that are not in the asset service. Therefore,
// before cleaning up expired files we must scan the objects in the scene to make sure that we retain
// such local assets if they have not been recently accessed.
TouchAllSceneAssets(false);
// An optional deep scan at this point will ensure assets present in scenes,
// or referenced by objects in the scene, but not recently accessed
// are not purged.
if (m_DeepScanBeforePurge)
{
CacheScenes();
}
foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
{
@@ -698,14 +705,11 @@ namespace Flotsam.RegionModules.AssetCache
/// <summary>
/// Iterates through all Scenes, doing a deep scan through assets
/// to update the access time of all assets present in the scene or referenced by assets
/// in the scene.
/// to cache all assets present in the scene or referenced by assets
/// in the scene
/// </summary>
/// <param name="storeUncached">
/// If true, then assets scanned which are not found in cache are added to the cache.
/// </param>
/// <returns>Number of distinct asset references found in the scene.</returns>
private int TouchAllSceneAssets(bool storeUncached)
/// <returns></returns>
private int CacheScenes()
{
UuidGatherer gatherer = new UuidGatherer(m_AssetService);
@@ -728,7 +732,7 @@ namespace Flotsam.RegionModules.AssetCache
{
File.SetLastAccessTime(filename, DateTime.Now);
}
else if (storeUncached)
else
{
m_AssetService.Get(assetID.ToString());
}
@@ -856,14 +860,13 @@ namespace Flotsam.RegionModules.AssetCache
break;
case "assets":
m_log.Info("[FLOTSAM ASSET CACHE]: Ensuring assets are cached for all scenes.");
m_log.Info("[FLOTSAM ASSET CACHE]: Caching all assets, in all scenes.");
Util.FireAndForget(delegate {
int assetReferenceTotal = TouchAllSceneAssets(true);
m_log.InfoFormat(
"[FLOTSAM ASSET CACHE]: Completed check with {0} assets.",
assetReferenceTotal);
int assetsCached = CacheScenes();
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached);
});
break;

View File

@@ -239,7 +239,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
sp.ClearAttachments();
}
public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp)
{
lock (sp.AttachmentsSyncLock)
{
@@ -298,7 +298,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
group.AbsolutePosition = attachPos;
if (sp.PresenceType != PresenceType.Npc)
UpdateUserInventoryWithAttachment(sp, group, attachmentPt);
UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp);
AttachToAgent(sp, group, attachmentPt, attachPos, silent);
}
@@ -306,7 +306,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return true;
}
private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt)
private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp)
{
// Remove any previous attachments
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
@@ -316,18 +316,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
{
if (attachments[0].FromItemID != UUID.Zero)
DetachSingleAttachmentToInvInternal(sp, attachments[0]);
else
m_log.WarnFormat(
"[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
// Error logging commented because UUID.Zero now means temp attachment
// else
// m_log.WarnFormat(
// "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
// attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
}
// Add the new attachment to inventory if we don't already have it.
UUID newAttachmentItemID = group.FromItemID;
if (newAttachmentItemID == UUID.Zero)
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
if (!temp)
{
UUID newAttachmentItemID = group.FromItemID;
if (newAttachmentItemID == UUID.Zero)
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
}
}
public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
@@ -406,6 +410,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
UUID inventoryID = so.FromItemID;
// As per Linden spec, drop is disabled for temp attachs
if (inventoryID == UUID.Zero)
return;
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
// so.Name, so.LocalId, inventoryID);
@@ -416,7 +424,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
so.PrimCount, sp.UUID, sp.AbsolutePosition))
return;
bool changed = sp.Appearance.DetachAttachment(inventoryID);
bool changed = false;
if (inventoryID != UUID.Zero)
changed = sp.Appearance.DetachAttachment(inventoryID);
if (changed && m_scene.AvatarFactory != null)
m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
@@ -521,6 +531,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
/// <param name="saveAllScripted"></param>
private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, string scriptedState)
{
if (grp.FromItemID == UUID.Zero)
{
// We can't save temp attachments
grp.HasGroupChanged = false;
return;
}
// Saving attachments for NPCs messes them up for the real owner!
INPCModule module = m_scene.RequestModuleInterface<INPCModule>();
if (module != null)
@@ -531,9 +548,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
if (grp.HasGroupChanged)
{
m_log.DebugFormat(
"[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
grp.UUID, grp.AttachmentPoint);
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
// grp.UUID, grp.AttachmentPoint);
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, scriptedState);
@@ -777,7 +794,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// This will throw if the attachment fails
try
{
AttachObject(sp, objatt, attachmentPt, false);
AttachObject(sp, objatt, attachmentPt, false, false);
}
catch (Exception e)
{
@@ -931,7 +948,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
AttachmentPt &= 0x7f;
// Calls attach with a Zero position
if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false))
{
// m_log.Debug(
// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
@@ -955,7 +972,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
if (sp != null && group != null)
if (sp != null && group != null && group.FromItemID != UUID.Zero)
DetachSingleAttachmentToInv(sp, group);
}
@@ -973,7 +990,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
foreach (SceneObjectGroup group in attachments)
{
if (group.FromItemID == itemID)
if (group.FromItemID == itemID && group.FromItemID != UUID.Zero)
{
DetachSingleAttachmentToInv(sp, group);
return;

View File

@@ -189,7 +189,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false);
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false);
// Check status on scene presence
Assert.That(sp.HasAttachments(), Is.True);
@@ -243,7 +243,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
sp2.AbsolutePosition = new Vector3(0, 0, 0);
sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false);
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false);
Assert.That(sp.HasAttachments(), Is.False);
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));

View File

@@ -186,7 +186,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
{
string fromName = c.From;
UUID fromID = UUID.Zero;
UUID ownerID = UUID.Zero;
UUID targetID = c.TargetUUID;
string message = c.Message;
IScene scene = c.Scene;
@@ -209,16 +208,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
fromPos = avatar.AbsolutePosition;
fromName = avatar.Name;
fromID = c.Sender.AgentId;
ownerID = c.Sender.AgentId;
break;
case ChatSourceType.Object:
fromID = c.SenderUUID;
if (c.SenderObject != null && c.SenderObject is SceneObjectPart)
ownerID = ((SceneObjectPart)c.SenderObject).OwnerID;
break;
}
@@ -241,8 +236,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
s.ForEachRootScenePresence(
delegate(ScenePresence presence)
{
if (TrySendChatMessage(
presence, fromPos, regionPos, fromID, ownerID, fromName, c.Type, message, sourceType, false))
if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType, false))
receiverIDs.Add(presence.UUID);
}
);
@@ -254,9 +248,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
ScenePresence presence = s.GetScenePresence(targetID);
if (presence != null && !presence.IsChildAgent)
{
if (TrySendChatMessage(
presence, fromPos, regionPos, fromID, ownerID, fromName, ChatTypeEnum.Say, message, sourceType, true))
receiverIDs.Add(presence.UUID);
if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, ChatTypeEnum.Say, message, sourceType, true))
receiverIDs.Add(presence.UUID);
}
}
}
@@ -312,11 +305,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
(null != c.SenderObject) &&
(((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
return;
client.SendChatMessage(
c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID,
(byte)sourceType, (byte)ChatAudibleLevel.Fully);
client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID,
(byte)sourceType, (byte)ChatAudibleLevel.Fully);
receiverIDs.Add(client.AgentId);
});
@@ -331,20 +322,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
/// <param name="fromPos"></param>
/// <param name="regionPos">/param>
/// <param name="fromAgentID"></param>
/// <param name='ownerID'>
/// Owner of the message. For at least some messages from objects, this has to be correctly filled with the owner's UUID.
/// This is the case for script error messages in viewer 3 since LLViewer change EXT-7762
/// </param>
/// <param name="fromName"></param>
/// <param name="type"></param>
/// <param name="message"></param>
/// <param name="src"></param>
/// <returns>true if the message was sent to the receiver, false if it was not sent due to failing a
/// precondition</returns>
protected virtual bool TrySendChatMessage(
ScenePresence presence, Vector3 fromPos, Vector3 regionPos,
UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type,
string message, ChatSourceType src, bool ignoreDistance)
protected virtual bool TrySendChatMessage(ScenePresence presence, Vector3 fromPos, Vector3 regionPos,
UUID fromAgentID, string fromName, ChatTypeEnum type,
string message, ChatSourceType src, bool ignoreDistance)
{
// don't send stuff to child agents
if (presence.IsChildAgent) return false;
@@ -367,11 +353,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
}
// TODO: should change so the message is sent through the avatar rather than direct to the ClientView
presence.ControllingClient.SendChatMessage(
message, (byte) type, fromPos, fromName,
fromAgentID, ownerID, (byte)src, (byte)ChatAudibleLevel.Fully);
presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName,
fromAgentID, (byte)src, (byte)ChatAudibleLevel.Fully);
return true;
}
}
}
}

View File

@@ -28,7 +28,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using log4net;
@@ -483,9 +482,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
Util.FireAndForget(
delegate
{
// m_log.DebugFormat(
// "[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}",
// friendList.Count, agentID, online);
m_log.DebugFormat(
"[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}",
friendList.Count, agentID, online);
// Notify about this user status
StatusNotify(friendList, agentID, online);
@@ -496,36 +495,42 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
{
List<string> friendStringIds = friendList.ConvertAll<string>(friend => friend.Friend);
List<string> remoteFriendStringIds = new List<string>();
foreach (string friendStringId in friendStringIds)
foreach (FriendInfo friend in friendList)
{
UUID friendUuid;
if (UUID.TryParse(friendStringId, out friendUuid))
UUID friendID;
if (UUID.TryParse(friend.Friend, out friendID))
{
if (LocalStatusNotification(userID, friendUuid, online))
// Try local
if (LocalStatusNotification(userID, friendID, online))
continue;
remoteFriendStringIds.Add(friendStringId);
// The friend is not here [as root]. Let's forward.
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
if (friendSessions != null && friendSessions.Length > 0)
{
PresenceInfo friendSession = null;
foreach (PresenceInfo pinfo in friendSessions)
{
if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
{
friendSession = pinfo;
break;
}
}
if (friendSession != null)
{
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
//m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
}
}
// Friend is not online. Ignore.
}
else
{
m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friendStringId);
}
}
// We do this regrouping so that we can efficiently send a single request rather than one for each
// friend in what may be a very large friends list.
PresenceInfo[] friendSessions = PresenceService.GetAgents(remoteFriendStringIds.ToArray());
foreach (PresenceInfo friendSession in friendSessions)
{
// let's guard against sessions-gone-bad
if (friendSession.RegionID != UUID.Zero)
{
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
//m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
m_FriendsSimConnector.StatusNotify(region, userID, friendSession.UserID, online);
m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
}
}
}

View File

@@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (options.ContainsKey("verbose"))
m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Saving item {0} {1} (asset UUID {2})",
"[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}",
inventoryItem.ID, inventoryItem.Name, inventoryItem.AssetID);
string filename = path + CreateArchiveItemName(inventoryItem);
@@ -337,14 +337,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{
m_log.DebugFormat("[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetUuids.Count);
AssetsRequest ar
= new AssetsRequest(
new AssetsArchiver(m_archiveWriter),
m_assetUuids, m_scene.AssetService,
m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
options, ReceivedAllAssets);
Util.FireAndForget(o => ar.Execute());
new AssetsRequest(
new AssetsArchiver(m_archiveWriter),
m_assetUuids, m_scene.AssetService,
m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
options, ReceivedAllAssets).Execute();
}
else
{

View File

@@ -82,25 +82,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
protected string m_item1Name = "Ray Gun Item";
protected string m_coaItemName = "Coalesced Item";
[TestFixtureSetUp]
public void FixtureSetup()
{
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
ConstructDefaultIarBytesForTestLoad();
}
[TestFixtureTearDown]
public void TearDown()
{
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
// threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
// tests really shouldn't).
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
}
[SetUp]
public override void SetUp()
{
@@ -108,6 +90,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
m_iarStream = new MemoryStream(m_iarStreamBytes);
}
[TestFixtureSetUp]
public void FixtureSetup()
{
ConstructDefaultIarBytesForTestLoad();
}
protected void ConstructDefaultIarBytesForTestLoad()
{
// log4net.Config.XmlConfigurator.Configure();

View File

@@ -49,7 +49,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{
[TestFixture]
public class InventoryArchiverTests : InventoryArchiveTestCase
{
{
protected TestScene m_scene;
protected InventoryArchiverModule m_archiverModule;
@@ -69,7 +69,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
public void TestLoadCoalesecedItem()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
// log4net.Config.XmlConfigurator.Configure();
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password");
m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream);

View File

@@ -38,15 +38,15 @@ using OpenSim.Services.Interfaces;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
{
public class InventoryTransferModule : ISharedRegionModule
public class InventoryTransferModule : IInventoryTransferModule, ISharedRegionModule
{
private static readonly ILog m_log
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
private List<Scene> m_Scenelist = new List<Scene>();
// private Dictionary<UUID, Scene> m_AgentRegions =
// new Dictionary<UUID, Scene>();
private Dictionary<UUID, Scene> m_AgentRegions =
new Dictionary<UUID, Scene>();
private IMessageTransferModule m_TransferModule = null;
private bool m_Enabled = true;
@@ -76,12 +76,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
m_Scenelist.Add(scene);
// scene.RegisterModuleInterface<IInventoryTransferModule>(this);
scene.RegisterModuleInterface<IInventoryTransferModule>(this);
scene.EventManager.OnNewClient += OnNewClient;
// scene.EventManager.OnClientClosed += ClientLoggedOut;
scene.EventManager.OnClientClosed += ClientLoggedOut;
scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
// scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene;
scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene;
}
public void RegionLoaded(Scene scene)
@@ -96,9 +96,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
m_Scenelist.Clear();
scene.EventManager.OnNewClient -= OnNewClient;
// scene.EventManager.OnClientClosed -= ClientLoggedOut;
scene.EventManager.OnClientClosed -= ClientLoggedOut;
scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
// scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene;
scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene;
}
}
}
@@ -106,9 +106,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
public void RemoveRegion(Scene scene)
{
scene.EventManager.OnNewClient -= OnNewClient;
// scene.EventManager.OnClientClosed -= ClientLoggedOut;
scene.EventManager.OnClientClosed -= ClientLoggedOut;
scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
// scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene;
scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene;
m_Scenelist.Remove(scene);
}
@@ -138,10 +138,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
client.OnInstantMessage += OnInstantMessage;
}
// protected void OnSetRootAgentScene(UUID id, Scene scene)
// {
// m_AgentRegions[id] = scene;
// }
protected void OnSetRootAgentScene(UUID id, Scene scene)
{
m_AgentRegions[id] = scene;
}
private Scene FindClientScene(UUID agentId)
{
@@ -367,69 +367,69 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
}
}
// public bool NeedSceneCacheClear(UUID agentID, Scene scene)
// {
// if (!m_AgentRegions.ContainsKey(agentID))
// {
// // Since we can get here two ways, we need to scan
// // the scenes here. This is somewhat more expensive
// // but helps avoid a nasty bug
// //
//
// foreach (Scene s in m_Scenelist)
// {
// ScenePresence presence;
//
// if (s.TryGetScenePresence(agentID, out presence))
// {
// // If the agent is in this scene, then we
// // are being called twice in a single
// // teleport. This is wasteful of cycles
// // but harmless due to this 2nd level check
// //
// // If the agent is found in another scene
// // then the list wasn't current
// //
// // If the agent is totally unknown, then what
// // are we even doing here??
// //
// if (s == scene)
// {
// //m_log.Debug("[INVTRANSFERMOD]: s == scene. Returning true in " + scene.RegionInfo.RegionName);
// return true;
// }
// else
// {
// //m_log.Debug("[INVTRANSFERMOD]: s != scene. Returning false in " + scene.RegionInfo.RegionName);
// return false;
// }
// }
// }
// //m_log.Debug("[INVTRANSFERMOD]: agent not in scene. Returning true in " + scene.RegionInfo.RegionName);
// return true;
// }
//
// // The agent is left in current Scene, so we must be
// // going to another instance
// //
// if (m_AgentRegions[agentID] == scene)
// {
// //m_log.Debug("[INVTRANSFERMOD]: m_AgentRegions[agentID] == scene. Returning true in " + scene.RegionInfo.RegionName);
// m_AgentRegions.Remove(agentID);
// return true;
// }
//
// // Another region has claimed the agent
// //
// //m_log.Debug("[INVTRANSFERMOD]: last resort. Returning false in " + scene.RegionInfo.RegionName);
// return false;
// }
//
// public void ClientLoggedOut(UUID agentID, Scene scene)
// {
// if (m_AgentRegions.ContainsKey(agentID))
// m_AgentRegions.Remove(agentID);
// }
public bool NeedSceneCacheClear(UUID agentID, Scene scene)
{
if (!m_AgentRegions.ContainsKey(agentID))
{
// Since we can get here two ways, we need to scan
// the scenes here. This is somewhat more expensive
// but helps avoid a nasty bug
//
foreach (Scene s in m_Scenelist)
{
ScenePresence presence;
if (s.TryGetScenePresence(agentID, out presence))
{
// If the agent is in this scene, then we
// are being called twice in a single
// teleport. This is wasteful of cycles
// but harmless due to this 2nd level check
//
// If the agent is found in another scene
// then the list wasn't current
//
// If the agent is totally unknown, then what
// are we even doing here??
//
if (s == scene)
{
//m_log.Debug("[INVTRANSFERMOD]: s == scene. Returning true in " + scene.RegionInfo.RegionName);
return true;
}
else
{
//m_log.Debug("[INVTRANSFERMOD]: s != scene. Returning false in " + scene.RegionInfo.RegionName);
return false;
}
}
}
//m_log.Debug("[INVTRANSFERMOD]: agent not in scene. Returning true in " + scene.RegionInfo.RegionName);
return true;
}
// The agent is left in current Scene, so we must be
// going to another instance
//
if (m_AgentRegions[agentID] == scene)
{
//m_log.Debug("[INVTRANSFERMOD]: m_AgentRegions[agentID] == scene. Returning true in " + scene.RegionInfo.RegionName);
m_AgentRegions.Remove(agentID);
return true;
}
// Another region has claimed the agent
//
//m_log.Debug("[INVTRANSFERMOD]: last resort. Returning false in " + scene.RegionInfo.RegionName);
return false;
}
public void ClientLoggedOut(UUID agentID, Scene scene)
{
if (m_AgentRegions.ContainsKey(agentID))
m_AgentRegions.Remove(agentID);
}
/// <summary>
///

View File

@@ -471,8 +471,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (sp.ParentID != (uint)0)
sp.StandUp();
// At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to
// the viewer. However, it might mean that the viewer does not see the black teleport screen (untested).
sp.ControllingClient.SendTeleportStart(teleportFlags);
// the avatar.Close below will clear the child region list. We need this below for (possibly)
@@ -548,11 +546,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// So let's wait
Thread.Sleep(200);
// At least on LL 3.3.4 for teleports between different regions on the same simulator this appears
// unnecessary - teleport will succeed and SEED caps will be requested without it (though possibly
// only on TeleportFinish). This is untested for region teleport between different simulators
// though this probably also works.
m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath);
}
else
{
@@ -657,14 +652,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Reset();
}
// Commented pending deletion since this method no longer appears to do anything at all
// // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
// if (sp.Scene.NeedSceneCacheClear(sp.UUID))
// {
// m_log.DebugFormat(
// "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
// sp.UUID);
// }
// REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
if (sp.Scene.NeedSceneCacheClear(sp.UUID))
{
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
sp.UUID);
}
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
}
@@ -1211,14 +1205,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
AgentHasMovedAway(agent, false);
// // the user may change their profile information in other region,
// // so the userinfo in UserProfileCache is not reliable any more, delete it
// // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
// {
// m_log.DebugFormat(
// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
// }
// the user may change their profile information in other region,
// so the userinfo in UserProfileCache is not reliable any more, delete it
// REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
if (agent.Scene.NeedSceneCacheClear(agent.UUID))
{
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
}
//m_log.Debug("AFTER CROSS");
//Scene.DumpChildrenSeeds(UUID);

View File

@@ -40,7 +40,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
protected string m_assetServerURL;
protected HGAssetMapper m_assetMapper;
public HGUuidGatherer(HGAssetMapper assMap, IAssetService assetService, string assetServerURL) : base(assetService)
public HGUuidGatherer(HGAssetMapper assMap, IAssetService assetCache, string assetServerURL) : base(assetCache)
{
m_assetMapper = assMap;
m_assetServerURL = assetServerURL;
@@ -49,7 +49,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
protected override AssetBase GetAsset(UUID uuid)
{
if (string.Empty == m_assetServerURL)
return base.GetAsset(uuid);
return m_assetCache.Get(uuid.ToString());
else
return m_assetMapper.FetchAsset(m_assetServerURL, uuid);
}

View File

@@ -95,14 +95,14 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
{
foreach (IMonitor monitor in m_staticMonitors)
{
MainConsole.Instance.OutputFormat(
m_log.InfoFormat(
"[MONITOR MODULE]: {0} reports {1} = {2}",
m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue());
}
foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats())
{
MainConsole.Instance.OutputFormat(
m_log.InfoFormat(
"[MONITOR MODULE]: {0} reports {1} = {2}",
m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value);
}

View File

@@ -31,7 +31,6 @@ using System.Reflection;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.ClientStack.LindenUDP;
using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;

View File

@@ -42,7 +42,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
{
public class DynamicTextureModule : IRegionModule, IDynamicTextureManager
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private const int ALL_SIDES = -1;
@@ -54,17 +54,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
/// </summary>
public bool ReuseTextures { get; set; }
/// <summary>
/// If false, then textures which have a low data size are not reused when ReuseTextures = true.
/// </summary>
/// <remarks>
/// LL viewers 3.3.4 and before appear to not fully render textures pulled from the viewer cache if those
/// textures have a relatively high pixel surface but a small data size. Typically, this appears to happen
/// if the data size is smaller than the viewer's discard level 2 size estimate. So if this is setting is
/// false, textures smaller than the calculation in IsSizeReuseable are always regenerated rather than reused
/// to work around this problem.</remarks>
public bool ReuseLowDataTextures { get; set; }
private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>();
private Dictionary<string, IDynamicTextureRender> RenderPlugins =
@@ -94,17 +83,18 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
/// <summary>
/// Called by code which actually renders the dynamic texture to supply texture data.
/// </summary>
/// <param name="updaterId"></param>
/// <param name="texture"></param>
public void ReturnData(UUID updaterId, IDynamicTexture texture)
/// <param name="id"></param>
/// <param name="data"></param>
/// <param name="isReuseable">True if the data generated can be reused for subsequent identical requests</param>
public void ReturnData(UUID id, byte[] data, bool isReuseable)
{
DynamicTextureUpdater updater = null;
lock (Updaters)
{
if (Updaters.ContainsKey(updaterId))
if (Updaters.ContainsKey(id))
{
updater = Updaters[updaterId];
updater = Updaters[id];
}
}
@@ -113,16 +103,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
if (RegisteredScenes.ContainsKey(updater.SimUUID))
{
Scene scene = RegisteredScenes[updater.SimUUID];
UUID newTextureID = updater.DataReceived(texture.Data, scene);
UUID newTextureID = updater.DataReceived(data, scene);
if (ReuseTextures
&& !updater.BlendWithOldTexture
&& texture.IsReuseable
&& (ReuseLowDataTextures || IsDataSizeReuseable(texture)))
{
if (ReuseTextures && isReuseable && !updater.BlendWithOldTexture)
m_reuseableDynamicTextures.Store(
GenerateReusableTextureKey(texture.InputCommands, texture.InputParams), newTextureID);
}
GenerateReusableTextureKey(updater.BodyData, updater.Params), newTextureID);
}
}
@@ -138,27 +123,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
}
}
/// <summary>
/// Determines whether the texture is reuseable based on its data size.
/// </summary>
/// <remarks>
/// This is a workaround for a viewer bug where very small data size textures relative to their pixel size
/// are not redisplayed properly when pulled from cache. The calculation here is based on the typical discard
/// level of 2, a 'rate' of 0.125 and 4 components (which makes for a factor of 0.5).
/// </remarks>
/// <returns></returns>
private bool IsDataSizeReuseable(IDynamicTexture texture)
{
// Console.WriteLine("{0} {1}", texture.Size.Width, texture.Size.Height);
int discardLevel2DataThreshold = (int)Math.Ceiling((texture.Size.Width >> 2) * (texture.Size.Height >> 2) * 0.5);
// m_log.DebugFormat(
// "[DYNAMIC TEXTURE MODULE]: Discard level 2 threshold {0}, texture data length {1}",
// discardLevel2DataThreshold, texture.Data.Length);
return discardLevel2DataThreshold < texture.Data.Length;
}
public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
string extraParams, int updateTimer)
{
@@ -285,18 +249,10 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
}
}
// m_log.DebugFormat(
// "[DYNAMIC TEXTURE MODULE]: Requesting generation of new dynamic texture for {0} in {1}",
// part.Name, part.ParentGroup.Scene.Name);
RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
}
else
{
// m_log.DebugFormat(
// "[DYNAMIC TEXTURE MODULE]: Reusing cached texture {0} for {1} in {2}",
// objReusableTextureUUID, part.Name, part.ParentGroup.Scene.Name);
// No need to add to updaters as the texture is always the same. Not that this functionality
// apppears to be implemented anyway.
updater.UpdatePart(part, (UUID)objReusableTextureUUID);
@@ -329,10 +285,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
{
IConfig texturesConfig = config.Configs["Textures"];
if (texturesConfig != null)
{
ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false);
ReuseLowDataTextures = texturesConfig.GetBoolean("ReuseDynamicLowDataTextures", false);
}
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
{
@@ -495,10 +448,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>();
if (cacheLayerDecode != null)
{
if (!cacheLayerDecode.Decode(asset.FullID, asset.Data))
m_log.WarnFormat(
"[DYNAMIC TEXTURE MODULE]: Decoding of dynamically generated asset {0} for {1} in {2} failed",
asset.ID, part.Name, part.ParentGroup.Scene.Name);
cacheLayerDecode.Decode(asset.FullID, asset.Data);
cacheLayerDecode = null;
}
UUID oldID = UpdatePart(part, asset.FullID);

View File

@@ -84,6 +84,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
public string body;
public int responseCode;
public string responseBody;
public string responseType = "text/plain";
//public ManualResetEvent ev;
public bool requestDone;
public int startTime;
@@ -302,6 +303,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
}
}
public void HttpContentType(UUID request, string type)
{
lock (m_UrlMap)
{
if (m_RequestMap.ContainsKey(request))
{
UrlData urlData = m_RequestMap[request];
urlData.requests[request].responseType = type;
}
else
{
m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString());
}
}
}
public void HttpResponse(UUID request, int status, string body)
{
lock (m_UrlMap)
@@ -504,7 +521,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
//put response
response["int_response_code"] = requestData.responseCode;
response["str_response_string"] = requestData.responseBody;
response["content_type"] = "text/plain";
response["content_type"] = requestData.responseType;
// response["content_type"] = "text/plain";
response["keepalive"] = false;
response["reusecontext"] = false;

View File

@@ -32,7 +32,6 @@ using System.Net;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.Imaging;
using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using log4net;
@@ -74,12 +73,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
// return false;
// }
public IDynamicTexture ConvertUrl(string url, string extraParams)
public byte[] ConvertUrl(string url, string extraParams)
{
return null;
}
public IDynamicTexture ConvertData(string bodyData, string extraParams)
public byte[] ConvertData(string bodyData, string extraParams)
{
return null;
}
@@ -172,11 +171,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
private void HttpRequestReturn(IAsyncResult result)
{
RequestState state = (RequestState) result.AsyncState;
WebRequest request = (WebRequest) state.Request;
Stream stream = null;
byte[] imageJ2000 = new byte[0];
Size newSize = new Size(0, 0);
try
{
@@ -189,43 +188,37 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
try
{
Bitmap image = new Bitmap(stream);
Size newsize;
// TODO: make this a bit less hard coded
if ((image.Height < 64) && (image.Width < 64))
{
newSize.Width = 32;
newSize.Height = 32;
newsize = new Size(32, 32);
}
else if ((image.Height < 128) && (image.Width < 128))
{
newSize.Width = 64;
newSize.Height = 64;
newsize = new Size(64, 64);
}
else if ((image.Height < 256) && (image.Width < 256))
{
newSize.Width = 128;
newSize.Height = 128;
newsize = new Size(128, 128);
}
else if ((image.Height < 512 && image.Width < 512))
{
newSize.Width = 256;
newSize.Height = 256;
newsize = new Size(256, 256);
}
else if ((image.Height < 1024 && image.Width < 1024))
{
newSize.Width = 512;
newSize.Height = 512;
newsize = new Size(512, 512);
}
else
{
newSize.Width = 1024;
newSize.Height = 1024;
newsize = new Size(1024, 1024);
}
using (Bitmap resize = new Bitmap(image, newSize))
{
imageJ2000 = OpenJPEG.EncodeFromImage(resize, true);
}
Bitmap resize = new Bitmap(image, newsize);
imageJ2000 = OpenJPEG.EncodeFromImage(resize, true);
}
catch (Exception)
{
@@ -240,6 +233,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
}
catch (WebException)
{
}
finally
{
@@ -249,13 +243,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
}
}
m_log.DebugFormat("[LOADIMAGEURLMODULE]: Returning {0} bytes of image data for request {1}",
m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}",
imageJ2000.Length, state.RequestID);
m_textureManager.ReturnData(
state.RequestID,
new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture(
request.RequestUri, null, imageJ2000, newSize, false));
m_textureManager.ReturnData(state.RequestID, imageJ2000, false);
}
#region Nested type: RequestState

View File

@@ -57,7 +57,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
m_dtm = new DynamicTextureModule();
m_dtm.ReuseTextures = reuseTextures;
// m_dtm.ReuseLowDataTextures = reuseTextures;
m_vrm = new VectorRenderModule();
@@ -202,7 +201,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
public void TestRepeatSameDrawReusingTexture()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
@@ -230,46 +228,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
/// <summary>
/// Test a low data dynamically generated texture such that it is treated as a low data texture that causes
/// problems for current viewers.
/// </summary>
/// <remarks>
/// As we do not set DynamicTextureModule.ReuseLowDataTextures = true in this test, it should not reuse the
/// texture
/// </remarks>
[Test]
public void TestRepeatSameDrawLowDataTexture()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
SetupScene(true);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"1024",
0);
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"1024",
0);
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestRepeatSameDrawDifferentExtraParamsReusingTexture()
{

View File

@@ -35,7 +35,6 @@ using System.Net;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.Imaging;
using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using log4net;
@@ -47,11 +46,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
{
public class VectorRenderModule : IRegionModule, IDynamicTextureRender
{
// These fields exist for testing purposes, please do not remove.
// private static bool s_flipper;
// private static byte[] s_asset1Data;
// private static byte[] s_asset2Data;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
@@ -86,14 +80,20 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
// return lines.Any((str, r) => str.StartsWith("Image"));
// }
public IDynamicTexture ConvertUrl(string url, string extraParams)
public byte[] ConvertUrl(string url, string extraParams)
{
return null;
}
public IDynamicTexture ConvertData(string bodyData, string extraParams)
public byte[] ConvertData(string bodyData, string extraParams)
{
return Draw(bodyData, extraParams);
bool reuseable;
return Draw(bodyData, extraParams, out reuseable);
}
private byte[] ConvertData(string bodyData, string extraParams, out bool reuseable)
{
return Draw(bodyData, extraParams, out reuseable);
}
public bool AsyncConvertUrl(UUID id, string url, string extraParams)
@@ -104,7 +104,10 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
public bool AsyncConvertData(UUID id, string bodyData, string extraParams)
{
// XXX: This isn't actually being done asynchronously!
m_textureManager.ReturnData(id, ConvertData(bodyData, extraParams));
bool reuseable;
byte[] data = ConvertData(bodyData, extraParams, out reuseable);
m_textureManager.ReturnData(id, data, reuseable);
return true;
}
@@ -112,19 +115,14 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
public void GetDrawStringSize(string text, string fontName, int fontSize,
out double xSize, out double ySize)
{
lock (this)
using (Font myFont = new Font(fontName, fontSize))
{
using (Font myFont = new Font(fontName, fontSize))
SizeF stringSize = new SizeF();
lock (m_graph)
{
SizeF stringSize = new SizeF();
// XXX: This lock may be unnecessary.
lock (m_graph)
{
stringSize = m_graph.MeasureString(text, myFont);
xSize = stringSize.Width;
ySize = stringSize.Height;
}
stringSize = m_graph.MeasureString(text, myFont);
xSize = stringSize.Width;
ySize = stringSize.Height;
}
}
}
@@ -163,13 +161,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
{
m_textureManager.RegisterRender(GetContentType(), this);
}
// This code exists for testing purposes, please do not remove.
// s_asset1Data = m_scene.AssetService.Get("00000000-0000-1111-9999-000000000001").Data;
// s_asset1Data = m_scene.AssetService.Get("9f4acf0d-1841-4e15-bdb8-3a12efc9dd8f").Data;
// Terrain dirt - smallest bin/assets file (6004 bytes)
// s_asset2Data = m_scene.AssetService.Get("b8d3965a-ad78-bf43-699b-bff8eca6c975").Data;
}
public void Close()
@@ -188,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
#endregion
private IDynamicTexture Draw(string data, string extraParams)
private byte[] Draw(string data, string extraParams, out bool reuseable)
{
// We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha
// we will now support multiple comma seperated params in the form width:256,height:512,alpha:255
@@ -331,7 +322,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
Bitmap bitmap = null;
Graphics graph = null;
bool reuseable = false;
try
{
@@ -374,14 +364,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
byte[] imageJ2000 = new byte[0];
// This code exists for testing purposes, please do not remove.
// if (s_flipper)
// imageJ2000 = s_asset1Data;
// else
// imageJ2000 = s_asset2Data;
//
// s_flipper = !s_flipper;
try
{
@@ -394,8 +376,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
e.Message, e.StackTrace);
}
return new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture(
data, extraParams, imageJ2000, new Size(width, height), reuseable);
return imageJ2000;
}
finally
{

View File

@@ -472,8 +472,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
if (coll.Count > 0)
{
// special case, called with same filter settings, return same
// handle (2008-05-02, tested on 1.21.1 server, still holds)
// special case, called with same filter settings, return same handle
// (2008-05-02, tested on 1.21.1 server, still holds)
return coll[0].GetHandle();
}
@@ -712,7 +712,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
}
}
public class ListenerInfo : IWorldCommListenerInfo
public class ListenerInfo: IWorldCommListenerInfo
{
private bool m_active; // Listener is active or not
private int m_handle; // Assigned handle of this listener

View File

@@ -204,11 +204,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
public byte[] GetData(string id)
{
// m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Requesting data for asset {0}", id);
AssetBase asset = null;
if (m_Cache != null)
asset = m_Cache.Get(id);
AssetBase asset = m_Cache.Get(id);
if (asset != null)
return asset.Data;

View File

@@ -1,136 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using log4net.Config;
using Nini.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset;
using OpenSim.Tests.Common;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.Tests
{
[TestFixture]
public class AssetConnectorsTests : OpenSimTestCase
{
[Test]
public void TestAddAsset()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
IConfigSource config = new IniConfigSource();
config.AddConfig("Modules");
config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
config.AddConfig("AssetService");
config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
LocalAssetServicesConnector lasc = new LocalAssetServicesConnector();
lasc.Initialise(config);
AssetBase a1 = AssetHelpers.CreateNotecardAsset();
lasc.Store(a1);
AssetBase retreivedA1 = lasc.Get(a1.ID);
Assert.That(retreivedA1.ID, Is.EqualTo(a1.ID));
Assert.That(retreivedA1.Metadata.ID, Is.EqualTo(a1.Metadata.ID));
Assert.That(retreivedA1.Data.Length, Is.EqualTo(a1.Data.Length));
AssetMetadata retrievedA1Metadata = lasc.GetMetadata(a1.ID);
Assert.That(retrievedA1Metadata.ID, Is.EqualTo(a1.ID));
byte[] retrievedA1Data = lasc.GetData(a1.ID);
Assert.That(retrievedA1Data.Length, Is.EqualTo(a1.Data.Length));
// TODO: Add cache and check that this does receive a copy of the asset
}
[Test]
public void TestAddTemporaryAsset()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
IConfigSource config = new IniConfigSource();
config.AddConfig("Modules");
config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
config.AddConfig("AssetService");
config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
LocalAssetServicesConnector lasc = new LocalAssetServicesConnector();
lasc.Initialise(config);
AssetBase a1 = AssetHelpers.CreateNotecardAsset();
a1.Temporary = true;
lasc.Store(a1);
Assert.That(lasc.Get(a1.ID), Is.Null);
Assert.That(lasc.GetData(a1.ID), Is.Null);
Assert.That(lasc.GetMetadata(a1.ID), Is.Null);
// TODO: Add cache and check that this does receive a copy of the asset
}
[Test]
public void TestAddLocalAsset()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
IConfigSource config = new IniConfigSource();
config.AddConfig("Modules");
config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
config.AddConfig("AssetService");
config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
LocalAssetServicesConnector lasc = new LocalAssetServicesConnector();
lasc.Initialise(config);
AssetBase a1 = AssetHelpers.CreateNotecardAsset();
a1.Local = true;
lasc.Store(a1);
Assert.That(lasc.Get(a1.ID), Is.Null);
Assert.That(lasc.GetData(a1.ID), Is.Null);
Assert.That(lasc.GetMetadata(a1.ID), Is.Null);
// TODO: Add cache and check that this does receive a copy of the asset
}
}
}

View File

@@ -43,7 +43,7 @@ using OpenSim.Tests.Common;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
{
[TestFixture]
public class GridConnectorsTests : OpenSimTestCase
public class GridConnectorsTests
{
LocalGridServicesConnector m_LocalConnector;
private void SetUp()

View File

@@ -97,6 +97,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
}
}
/// <summary>
/// Used to cache lookups for valid groups.
/// </summary>
private IDictionary<UUID, bool> m_validGroupUuids = new Dictionary<UUID, bool>();
private IGroupsModule m_groupsModule;
public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId)
{
m_scene = scene;
@@ -120,6 +127,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// Zero can never be a valid user id
m_validUserUuids[UUID.Zero] = false;
m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
}
public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId)
@@ -132,6 +141,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// Zero can never be a valid user id
m_validUserUuids[UUID.Zero] = false;
m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
}
/// <summary>
@@ -302,6 +313,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
if (!ResolveUserUuid(part.LastOwnerID))
part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
if (!ResolveGroupUuid(part.GroupID))
part.GroupID = UUID.Zero;
// And zap any troublesome sit target information
// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
// part.SitTargetPosition = new Vector3(0, 0, 0);
@@ -318,13 +332,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver
{
kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
}
if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty)
{
if (!ResolveUserUuid(kvp.Value.CreatorID))
kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
}
if (UserManager != null)
UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData);
if (!ResolveGroupUuid(kvp.Value.GroupID))
kvp.Value.GroupID = UUID.Zero;
}
}
}
@@ -364,9 +383,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver
foreach (string serialisedParcel in serialisedParcels)
{
LandData parcel = LandDataSerializer.Deserialize(serialisedParcel);
// Validate User and Group UUID's
if (!ResolveUserUuid(parcel.OwnerID))
parcel.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
if (!ResolveGroupUuid(parcel.GroupID))
{
parcel.GroupID = UUID.Zero;
parcel.IsGroupOwned = false;
}
List<LandAccessEntry> accessList = new List<LandAccessEntry>();
foreach (LandAccessEntry entry in parcel.ParcelAccessList)
{
if (ResolveUserUuid(entry.AgentID))
accessList.Add(entry);
// else, drop this access rule
}
parcel.ParcelAccessList = accessList;
// m_log.DebugFormat(
// "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}",
// parcel.Name, parcel.LocalID, parcel.Area);
@@ -401,6 +438,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver
}
/// <summary>
/// Look up the given group id to check whether it's one that is valid for this grid.
/// </summary>
/// <param name="uuid"></param>
/// <returns></returns>
private bool ResolveGroupUuid(UUID uuid)
{
if (uuid == UUID.Zero)
return true; // this means the object has no group
if (!m_validGroupUuids.ContainsKey(uuid))
{
bool exists;
if (m_groupsModule == null)
exists = false;
else
exists = (m_groupsModule.GetGroupRecord(uuid) != null);
m_validGroupUuids.Add(uuid, exists);
}
return m_validGroupUuids[uuid];
}
/// Load an asset
/// </summary>
/// <param name="assetFilename"></param>

View File

@@ -123,10 +123,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
m_options = options;
m_repliesRequired = uuids.Count;
// FIXME: This is a really poor way of handling the timeout since it will always leave the original requesting thread
// hanging. Need to restructure so an original request thread waits for a ManualResetEvent on asset received
// so we can properly abort that thread. Or request all assets synchronously, though that would be a more
// radical change
m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT);
m_requestCallbackTimer.AutoReset = false;
m_requestCallbackTimer.Elapsed += new ElapsedEventHandler(OnRequestCallbackTimeout);

View File

@@ -51,7 +51,7 @@ using RegionSettings = OpenSim.Framework.RegionSettings;
namespace OpenSim.Region.CoreModules.World.Archiver.Tests
{
[TestFixture]
public class ArchiverTests : OpenSimTestCase
public class ArchiverTests
{
private Guid m_lastRequestId;
private string m_lastErrorMessage;

View File

@@ -950,7 +950,6 @@ namespace OpenSim.Region.CoreModules.World.Land
ILandObject newLand = startLandObject.Copy();
newLand.LandData.Name = newLand.LandData.Name;
newLand.LandData.GlobalID = UUID.Random();
newLand.LandData.Dwell = 0;
newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y));

View File

@@ -69,7 +69,7 @@ namespace OpenSim.Region.CoreModules.World.Land
/// without recounting the whole sim.
///
/// We start out tainted so that the first get call resets the various prim counts.
/// </value>
/// <value>
private bool m_Tainted = true;
private Object m_TaintLock = new Object();

View File

@@ -27,12 +27,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using log4net;
using Mono.Addins;
using NDesk.Options;
@@ -43,7 +40,6 @@ using OpenSim.Framework.Console;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
namespace OpenSim.Region.CoreModules.World.Objects.Commands
{
@@ -87,85 +83,52 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
m_console.Commands.AddCommand(
"Objects", false, "delete object owner",
"delete object owner <UUID>",
"Delete scene objects by owner",
"Command will ask for confirmation before proceeding.",
HandleDeleteObject);
"Delete a scene object by owner", HandleDeleteObject);
m_console.Commands.AddCommand(
"Objects", false, "delete object creator",
"delete object creator <UUID>",
"Delete scene objects by creator",
"Command will ask for confirmation before proceeding.",
HandleDeleteObject);
"Delete a scene object by creator", HandleDeleteObject);
m_console.Commands.AddCommand(
"Objects", false, "delete object id",
"delete object id <UUID-or-localID>",
"Delete a scene object by uuid or localID",
HandleDeleteObject);
"Objects", false, "delete object uuid",
"delete object uuid <UUID>",
"Delete a scene object by uuid", HandleDeleteObject);
m_console.Commands.AddCommand(
"Objects", false, "delete object name",
"delete object name [--regex] <name>",
"Delete a scene object by name.",
"Command will ask for confirmation before proceeding.\n"
+ "If --regex is specified then the name is treatead as a regular expression",
"If --regex is specified then the name is treatead as a regular expression",
HandleDeleteObject);
m_console.Commands.AddCommand(
"Objects", false, "delete object outside",
"delete object outside",
"Delete all scene objects outside region boundaries",
"Command will ask for confirmation before proceeding.",
HandleDeleteObject);
"Delete all scene objects outside region boundaries", HandleDeleteObject);
m_console.Commands.AddCommand(
"Objects",
false,
"delete object pos",
"delete object pos <start-coord> to <end-coord>",
"Delete scene objects within the given area.",
ConsoleUtil.CoordHelp,
HandleDeleteObject);
m_console.Commands.AddCommand(
"Objects",
false,
"show object id",
"show object id [--full] <UUID-or-localID>",
"Show details of a scene object with the given UUID or localID",
"The --full option will print out information on all the parts of the object.\n"
+ "For yet more detailed part information, use the \"show part\" commands.",
HandleShowObjectById);
"show object uuid",
"show object uuid <UUID>",
"Show details of a scene object with the given UUID", HandleShowObjectByUuid);
m_console.Commands.AddCommand(
"Objects",
false,
"show object name",
"show object name [--full] [--regex] <name>",
"show object name [--regex] <name>",
"Show details of scene objects with the given name.",
"The --full option will print out information on all the parts of the object.\n"
+ "For yet more detailed part information, use the \"show part\" commands.\n"
+ "If --regex is specified then the name is treatead as a regular expression.",
"If --regex is specified then the name is treatead as a regular expression",
HandleShowObjectByName);
m_console.Commands.AddCommand(
"Objects",
false,
"show object pos",
"show object pos [--full] <start-coord> to <end-coord>",
"Show details of scene objects within the given area.",
"The --full option will print out information on all the parts of the object.\n"
+ "For yet more detailed part information, use the \"show part\" commands.\n"
+ ConsoleUtil.CoordHelp,
HandleShowObjectByPos);
m_console.Commands.AddCommand(
"Objects",
false,
"show part id",
"show part id <UUID-or-localID>",
"Show details of a scene object part with the given UUID or localID", HandleShowPartById);
"show part uuid",
"show part uuid <UUID>",
"Show details of a scene object parts with the given UUID", HandleShowPartByUuid);
m_console.Commands.AddCommand(
"Objects",
@@ -173,28 +136,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
"show part name",
"show part name [--regex] <name>",
"Show details of scene object parts with the given name.",
"If --regex is specified then the name is treated as a regular expression",
"If --regex is specified then the name is treatead as a regular expression",
HandleShowPartByName);
m_console.Commands.AddCommand(
"Objects",
false,
"show part pos",
"show part pos <start-coord> to <end-coord>",
"Show details of scene object parts within the given area.",
ConsoleUtil.CoordHelp,
HandleShowPartByPos);
m_console.Commands.AddCommand(
"Objects",
false,
"dump object id",
"dump object id <UUID-or-localID>",
"Dump the formatted serialization of the given object to the file <UUID>.xml",
"e.g. dump object uuid c1ed6809-cc24-4061-a4c2-93082a2d1f1d will dump serialization to c1ed6809-cc24-4061-a4c2-93082a2d1f1d.xml\n"
+ "To locate the UUID or localID in the first place, you need to use the other show object commands.\n"
+ "If a local ID is given then the filename used is still that for the UUID",
HandleDumpObjectById);
}
public void RemoveRegion(Scene scene)
@@ -207,75 +150,25 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
// m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
}
/// <summary>
/// Outputs the sogs to console.
/// </summary>
/// <param name='searchPredicate'></param>
/// <param name='showFull'>If true then output all part details. If false then output summary.</param>
private void OutputSogsToConsole(Predicate<SceneObjectGroup> searchPredicate, bool showFull)
{
List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups().FindAll(searchPredicate);
StringBuilder sb = new StringBuilder();
foreach (SceneObjectGroup so in sceneObjects)
{
AddSceneObjectReport(sb, so, showFull);
sb.Append("\n");
}
sb.AppendFormat("{0} object(s) found in {1}\n", sceneObjects.Count, m_scene.Name);
m_console.OutputFormat(sb.ToString());
}
private void OutputSopsToConsole(Predicate<SceneObjectPart> searchPredicate, bool showFull)
{
List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups();
List<SceneObjectPart> parts = new List<SceneObjectPart>();
sceneObjects.ForEach(so => parts.AddRange(Array.FindAll<SceneObjectPart>(so.Parts, searchPredicate)));
StringBuilder sb = new StringBuilder();
foreach (SceneObjectPart part in parts)
{
AddScenePartReport(sb, part, showFull);
sb.Append("\n");
}
sb.AppendFormat("{0} parts found in {1}\n", parts.Count, m_scene.Name);
m_console.OutputFormat(sb.ToString());
}
private void HandleShowObjectById(string module, string[] cmdparams)
private void HandleShowObjectByUuid(string module, string[] cmd)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
return;
bool showFull = false;
OptionSet options = new OptionSet().Add("full", v => showFull = v != null );
List<string> mainParams = options.Parse(cmdparams);
if (mainParams.Count < 4)
if (cmd.Length < 4)
{
m_console.OutputFormat("Usage: show object uuid <uuid>");
return;
}
UUID uuid;
uint localId;
if (!ConsoleUtil.TryParseConsoleId(m_console, mainParams[3], out uuid, out localId))
UUID objectUuid;
if (!UUID.TryParse(cmd[3], out objectUuid))
{
m_console.OutputFormat("{0} is not a valid uuid", cmd[3]);
return;
}
SceneObjectGroup so;
if (localId != ConsoleUtil.LocalIdNotFound)
so = m_scene.GetSceneObjectGroup(localId);
else
so = m_scene.GetSceneObjectGroup(uuid);
SceneObjectGroup so = m_scene.GetSceneObjectGroup(objectUuid);
if (so == null)
{
@@ -284,7 +177,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
}
StringBuilder sb = new StringBuilder();
AddSceneObjectReport(sb, so, showFull);
AddSceneObjectReport(sb, so);
m_console.OutputFormat(sb.ToString());
}
@@ -294,91 +187,70 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
return;
bool showFull = false;
bool useRegex = false;
OptionSet options = new OptionSet();
options.Add("full", v => showFull = v != null );
options.Add("regex", v => useRegex = v != null );
OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null );
List<string> mainParams = options.Parse(cmdparams);
if (mainParams.Count < 4)
{
m_console.OutputFormat("Usage: show object name [--full] [--regex] <name>");
m_console.OutputFormat("Usage: show object name [--regex] <name>");
return;
}
string name = mainParams[3];
Predicate<SceneObjectGroup> searchPredicate;
List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
Action<SceneObjectGroup> searchAction;
if (useRegex)
{
Regex nameRegex = new Regex(name);
searchPredicate = so => nameRegex.IsMatch(so.Name);
searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }};
}
else
{
searchPredicate = so => so.Name == name;
searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }};
}
OutputSogsToConsole(searchPredicate, showFull);
m_scene.ForEachSOG(searchAction);
if (sceneObjects.Count == 0)
{
m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName);
return;
}
StringBuilder sb = new StringBuilder();
foreach (SceneObjectGroup so in sceneObjects)
{
AddSceneObjectReport(sb, so);
sb.Append("\n");
}
m_console.OutputFormat(sb.ToString());
}
private void HandleShowObjectByPos(string module, string[] cmdparams)
private void HandleShowPartByUuid(string module, string[] cmd)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
return;
bool showFull = false;
OptionSet options = new OptionSet().Add("full", v => showFull = v != null );
List<string> mainParams = options.Parse(cmdparams);
if (mainParams.Count < 5)
if (cmd.Length < 4)
{
m_console.OutputFormat("Usage: show object pos [--full] <start-coord> to <end-coord>");
return;
}
Vector3 startVector, endVector;
if (!TryParseVectorRange(cmdparams.Skip(3).Take(3), out startVector, out endVector))
return;
Predicate<SceneObjectGroup> searchPredicate
= so => Util.IsInsideBox(so.AbsolutePosition, startVector, endVector);
OutputSogsToConsole(searchPredicate, showFull);
}
private void HandleShowPartById(string module, string[] cmdparams)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
return;
// bool showFull = false;
OptionSet options = new OptionSet();
// options.Add("full", v => showFull = v != null );
List<string> mainParams = options.Parse(cmdparams);
if (mainParams.Count < 4)
{
m_console.OutputFormat("Usage: show part id [--full] <UUID-or-localID>");
m_console.OutputFormat("Usage: show part uuid <uuid>");
return;
}
UUID objectUuid;
uint localId;
if (!ConsoleUtil.TryParseConsoleId(m_console, mainParams[3], out objectUuid, out localId))
if (!UUID.TryParse(cmd[3], out objectUuid))
{
m_console.OutputFormat("{0} is not a valid uuid", cmd[3]);
return;
}
SceneObjectPart sop;
if (localId == ConsoleUtil.LocalIdNotFound)
sop = m_scene.GetSceneObjectPart(objectUuid);
else
sop = m_scene.GetSceneObjectPart(localId);
SceneObjectPart sop = m_scene.GetSceneObjectPart(objectUuid);
if (sop == null)
{
@@ -387,242 +259,84 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
}
StringBuilder sb = new StringBuilder();
AddScenePartReport(sb, sop, true);
AddScenePartReport(sb, sop);
m_console.OutputFormat(sb.ToString());
}
private void HandleShowPartByPos(string module, string[] cmdparams)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
return;
// bool showFull = false;
OptionSet options = new OptionSet();
// options.Add("full", v => showFull = v != null );
List<string> mainParams = options.Parse(cmdparams);
if (mainParams.Count < 5)
{
m_console.OutputFormat("Usage: show part pos [--full] <start-coord> to <end-coord>");
return;
}
string rawConsoleStartVector = mainParams[3];
Vector3 startVector;
if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector))
{
m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector);
return;
}
string rawConsoleEndVector = mainParams[5];
Vector3 endVector;
if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector))
{
m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector);
return;
}
OutputSopsToConsole(sop => Util.IsInsideBox(sop.AbsolutePosition, startVector, endVector), true);
}
private void HandleShowPartByName(string module, string[] cmdparams)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
return;
// bool showFull = false;
bool useRegex = false;
OptionSet options = new OptionSet();
// options.Add("full", v => showFull = v != null );
options.Add("regex", v => useRegex = v != null );
OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null );
List<string> mainParams = options.Parse(cmdparams);
if (mainParams.Count < 4)
{
m_console.OutputFormat("Usage: show part name [--full] [--regex] <name>");
m_console.OutputFormat("Usage: show part name [--regex] <name>");
return;
}
string name = mainParams[3];
Predicate<SceneObjectPart> searchPredicate;
List<SceneObjectPart> parts = new List<SceneObjectPart>();
Action<SceneObjectGroup> searchAction;
if (useRegex)
{
Regex nameRegex = new Regex(name);
searchPredicate = sop => nameRegex.IsMatch(sop.Name);
searchAction = so => so.ForEachPart(sop => { if (nameRegex.IsMatch(sop.Name)) { parts.Add(sop); } });
}
else
{
searchPredicate = sop => sop.Name == name;
searchAction = so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } });
}
OutputSopsToConsole(searchPredicate, true);
m_scene.ForEachSOG(searchAction);
if (parts.Count == 0)
{
m_console.OutputFormat("No parts with name {0} found in {1}", name, m_scene.RegionInfo.RegionName);
return;
}
StringBuilder sb = new StringBuilder();
foreach (SceneObjectPart part in parts)
{
AddScenePartReport(sb, part);
sb.Append("\n");
}
m_console.OutputFormat(sb.ToString());
}
private void HandleDumpObjectById(string module, string[] cmdparams)
private StringBuilder AddSceneObjectReport(StringBuilder sb, SceneObjectGroup so)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
return;
if (cmdparams.Length < 4)
{
m_console.OutputFormat("Usage: dump object id <UUID-or-localID>");
return;
}
UUID objectUuid;
uint localId;
if (!ConsoleUtil.TryParseConsoleId(m_console, cmdparams[3], out objectUuid, out localId))
return;
SceneObjectGroup so;
if (localId == ConsoleUtil.LocalIdNotFound)
so = m_scene.GetSceneObjectGroup(objectUuid);
else
so = m_scene.GetSceneObjectGroup(localId);
if (so == null)
{
// m_console.OutputFormat("No part found with uuid {0}", objectUuid);
return;
}
// In case we found it via local ID.
objectUuid = so.UUID;
string fileName = string.Format("{0}.xml", objectUuid);
if (File.Exists(fileName))
{
m_console.OutputFormat("File {0} already exists. Please move or remove it.", fileName);
return;
}
using (XmlTextWriter xtw = new XmlTextWriter(fileName, Encoding.UTF8))
{
xtw.Formatting = Formatting.Indented;
SceneObjectSerializer.ToOriginalXmlFormat(so, xtw, true);
}
m_console.OutputFormat("Object dumped to file {0}", fileName);
}
/// <summary>
/// Append a scene object report to an input StringBuilder
/// </summary>
/// <returns></returns>
/// <param name='sb'></param>
/// <param name='so'</param>
/// <param name='showFull'>
/// If true then information on all parts of an object is appended.
/// If false then only summary information about an object is appended.
/// </param>
private StringBuilder AddSceneObjectReport(StringBuilder sb, SceneObjectGroup so, bool showFull)
{
if (showFull)
{
foreach (SceneObjectPart sop in so.Parts)
{
AddScenePartReport(sb, sop, false);
sb.Append("\n");
}
}
else
{
AddSummarySceneObjectReport(sb, so);
}
sb.AppendFormat("Name: {0}\n", so.Name);
sb.AppendFormat("Description: {0}\n", so.Description);
sb.AppendFormat("Location: {0} @ {1}\n", so.AbsolutePosition, so.Scene.RegionInfo.RegionName);
sb.AppendFormat("Parts: {0}\n", so.PrimCount);
sb.AppendFormat("Flags: {0}\n", so.RootPart.Flags);
return sb;
}
private StringBuilder AddSummarySceneObjectReport(StringBuilder sb, SceneObjectGroup so)
private StringBuilder AddScenePartReport(StringBuilder sb, SceneObjectPart sop)
{
ConsoleDisplayList cdl = new ConsoleDisplayList();
cdl.AddRow("Name", so.Name);
cdl.AddRow("Descrition", so.Description);
cdl.AddRow("Local ID", so.LocalId);
cdl.AddRow("UUID", so.UUID);
cdl.AddRow("Location", string.Format("{0} @ {1}", so.AbsolutePosition, so.Scene.Name));
cdl.AddRow("Parts", so.PrimCount);
cdl.AddRow("Flags", so.RootPart.Flags);
sb.AppendFormat("Name: {0}\n", sop.Name);
sb.AppendFormat("Description: {0}\n", sop.Description);
sb.AppendFormat("Location: {0} @ {1}\n", sop.AbsolutePosition, sop.ParentGroup.Scene.RegionInfo.RegionName);
sb.AppendFormat("Parent: {0}",
sop.IsRoot ? "Is Root\n" : string.Format("{0} {1}\n", sop.ParentGroup.Name, sop.ParentGroup.UUID));
sb.AppendFormat("Link number: {0}\n", sop.LinkNum);
sb.AppendFormat("Flags: {0}\n", sop.Flags);
return sb.Append(cdl.ToString());
}
/// <summary>
/// Append a scene object part report to an input StringBuilder
/// </summary>
/// <returns></returns>
/// <param name='sb'></param>
/// <param name='sop'</param>
/// <param name='showFull'>
/// If true then information on each inventory item will be shown.
/// If false then only summary inventory information is shown.
/// </param>
private StringBuilder AddScenePartReport(StringBuilder sb, SceneObjectPart sop, bool showFull)
{
ConsoleDisplayList cdl = new ConsoleDisplayList();
cdl.AddRow("Name", sop.Name);
cdl.AddRow("Description", sop.Description);
cdl.AddRow("Local ID", sop.LocalId);
cdl.AddRow("UUID", sop.UUID);
cdl.AddRow("Location", string.Format("{0} @ {1}", sop.AbsolutePosition, sop.ParentGroup.Scene.Name));
cdl.AddRow(
"Parent",
sop.IsRoot ? "Is Root" : string.Format("{0} {1}", sop.ParentGroup.Name, sop.ParentGroup.UUID));
cdl.AddRow("Link number", sop.LinkNum);
cdl.AddRow("Flags", sop.Flags);
object itemsOutput;
if (showFull)
{
StringBuilder itemsSb = new StringBuilder("\n");
itemsOutput = AddScenePartItemsReport(itemsSb, sop.Inventory).ToString();
}
else
{
itemsOutput = sop.Inventory.Count;
}
cdl.AddRow("Items", itemsOutput);
return sb.Append(cdl.ToString());
}
private StringBuilder AddScenePartItemsReport(StringBuilder sb, IEntityInventory inv)
{
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
cdt.Indent = 2;
cdt.AddColumn("Name", 50);
cdt.AddColumn("Type", 12);
cdt.AddColumn("Running", 7);
cdt.AddColumn("Item UUID", 36);
cdt.AddColumn("Asset UUID", 36);
foreach (TaskInventoryItem item in inv.GetInventoryItems())
{
bool foundScriptInstance, scriptRunning;
foundScriptInstance
= SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, item, out scriptRunning);
cdt.AddRow(
item.Name,
((InventoryType)item.InvType).ToString(),
foundScriptInstance ? scriptRunning.ToString() : "n/a",
item.ItemID.ToString(),
item.AssetID.ToString());
}
return sb.Append(cdt.ToString());
return sb;
}
private void HandleDeleteObject(string module, string[] cmd)
@@ -684,24 +398,19 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
break;
case "id":
UUID uuid;
uint localId;
if (!ConsoleUtil.TryParseConsoleId(m_console, o, out uuid, out localId))
case "uuid":
if (!UUID.TryParse(o, out match))
return;
requireConfirmation = false;
deletes = new List<SceneObjectGroup>();
SceneObjectGroup so;
if (localId == ConsoleUtil.LocalIdNotFound)
so = m_scene.GetSceneObjectGroup(uuid);
else
so = m_scene.GetSceneObjectGroup(localId);
if (!so.IsAttachment)
deletes.Add(so);
m_scene.ForEachSOG(delegate (SceneObjectGroup g)
{
if (g.UUID == match && !g.IsAttachment)
deletes.Add(g);
});
// if (deletes.Count == 0)
// m_console.OutputFormat("No objects were found with uuid {0}", match);
@@ -741,10 +450,6 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
break;
case "pos":
deletes = GetDeleteCandidatesByPos(module, cmd);
break;
default:
m_console.OutputFormat("Unrecognized mode {0}", mode);
return;
@@ -759,7 +464,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
string.Format(
"Are you sure that you want to delete {0} objects from {1}",
deletes.Count, m_scene.RegionInfo.RegionName),
"y/N");
"n");
if (response.ToLower() != "y")
{
@@ -781,6 +486,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
private List<SceneObjectGroup> GetDeleteCandidatesByName(string module, string[] cmdparams)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
return null;
bool useRegex = false;
OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null );
@@ -814,52 +522,5 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
return sceneObjects;
}
/// <summary>
/// Get scene object delete candidates by position
/// </summary>
/// <param name='module'></param>
/// <param name='cmdparams'></param>
/// <returns>null if parsing failed on one of the arguments, otherwise a list of objects to delete. If there
/// are no objects to delete then the list will be empty./returns>
private List<SceneObjectGroup> GetDeleteCandidatesByPos(string module, string[] cmdparams)
{
if (cmdparams.Length < 5)
{
m_console.OutputFormat("Usage: delete object pos <start-coord> to <end-coord>");
return null;
}
Vector3 startVector, endVector;
if (!TryParseVectorRange(cmdparams.Skip(3).Take(3), out startVector, out endVector))
return null;
return m_scene.GetSceneObjectGroups().FindAll(
so => !so.IsAttachment && Util.IsInsideBox(so.AbsolutePosition, startVector, endVector));
}
private bool TryParseVectorRange(IEnumerable<string> rawComponents, out Vector3 startVector, out Vector3 endVector)
{
string rawConsoleStartVector = rawComponents.Take(1).Single();
if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector))
{
m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector);
endVector = Vector3.Zero;
return false;
}
string rawConsoleEndVector = rawComponents.Skip(1).Take(1).Single();
if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector))
{
m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector);
return false;
}
return true;
}
}
}

View File

@@ -414,6 +414,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
private void LoadPlugins()
{
m_plugineffects = new Dictionary<string, ITerrainEffect>();
LoadPlugins(Assembly.GetCallingAssembly());
string plugineffectsPath = "Terrain";
// Load the files in the Terrain/ dir
@@ -427,32 +428,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
try
{
Assembly library = Assembly.LoadFrom(file);
foreach (Type pluginType in library.GetTypes())
{
try
{
if (pluginType.IsAbstract || pluginType.IsNotPublic)
continue;
string typeName = pluginType.Name;
if (pluginType.GetInterface("ITerrainEffect", false) != null)
{
ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString()));
InstallPlugin(typeName, terEffect);
}
else if (pluginType.GetInterface("ITerrainLoader", false) != null)
{
ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString()));
m_loaders[terLoader.FileExtension] = terLoader;
m_log.Info("L ... " + typeName);
}
}
catch (AmbiguousMatchException)
{
}
}
LoadPlugins(library);
}
catch (BadImageFormatException)
{
@@ -460,6 +436,36 @@ namespace OpenSim.Region.CoreModules.World.Terrain
}
}
private void LoadPlugins(Assembly library)
{
foreach (Type pluginType in library.GetTypes())
{
try
{
if (pluginType.IsAbstract || pluginType.IsNotPublic)
continue;
string typeName = pluginType.Name;
if (pluginType.GetInterface("ITerrainEffect", false) != null)
{
ITerrainEffect terEffect = (ITerrainEffect)Activator.CreateInstance(library.GetType(pluginType.ToString()));
InstallPlugin(typeName, terEffect);
}
else if (pluginType.GetInterface("ITerrainLoader", false) != null)
{
ITerrainLoader terLoader = (ITerrainLoader)Activator.CreateInstance(library.GetType(pluginType.ToString()));
m_loaders[terLoader.FileExtension] = terLoader;
m_log.Info("L ... " + typeName);
}
}
catch (AmbiguousMatchException)
{
}
}
}
public void InstallPlugin(string pluginName, ITerrainEffect effect)
{
lock (m_plugineffects)
@@ -1176,7 +1182,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
private void InterfaceRunPluginEffect(Object[] args)
{
if ((string) args[0] == "list")
string firstArg = (string)args[0];
if (firstArg == "list")
{
m_log.Info("List of loaded plugins");
foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects)
@@ -1185,14 +1192,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain
}
return;
}
if ((string) args[0] == "reload")
if (firstArg == "reload")
{
LoadPlugins();
return;
}
if (m_plugineffects.ContainsKey((string) args[0]))
if (m_plugineffects.ContainsKey(firstArg))
{
m_plugineffects[(string) args[0]].RunEffect(m_channel);
m_plugineffects[firstArg].RunEffect(m_channel);
CheckForTerrainUpdates();
}
else

View File

@@ -208,6 +208,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height);
}
GC.Collect();
m_log.Debug("[WARP 3D IMAGE MODULE]: GC.Collect()");
return bitmap;
}
@@ -673,4 +676,4 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
return result;
}
}
}
}

View File

@@ -44,7 +44,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
Scene m_scene = null; // only need one for communication with GridService
List<Scene> m_scenes = new List<Scene>();
List<UUID> m_Clients;
#region IRegionModule Members
public void Initialise(Scene scene, IConfigSource source)
@@ -56,7 +55,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
m_scenes.Add(scene);
scene.EventManager.OnNewClient += OnNewClient;
m_Clients = new List<UUID>();
}
public void PostInitialise()
@@ -83,51 +81,17 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
private void OnNewClient(IClientAPI client)
{
client.OnMapNameRequest += OnMapNameRequestHandler;
}
private void OnMapNameRequestHandler(IClientAPI remoteClient, string mapName, uint flags)
{
lock (m_Clients)
{
if (m_Clients.Contains(remoteClient.AgentId))
return;
m_Clients.Add(remoteClient.AgentId);
}
Util.FireAndForget(delegate
{
try
{
OnMapNameRequest(remoteClient, mapName, flags);
}
finally
{
lock (m_Clients)
m_Clients.Remove(remoteClient.AgentId);
}
});
client.OnMapNameRequest += OnMapNameRequest;
}
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags)
{
List<MapBlockData> blocks = new List<MapBlockData>();
MapBlockData data;
if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4))
if (mapName.Length < 3)
{
// final block, closing the search result
AddFinalBlock(blocks);
// flags are agent flags sent from the viewer.
// they have different values depending on different viewers, apparently
remoteClient.SendMapBlock(blocks, flags);
remoteClient.SendAlertMessage("Use a search string with at least 3 characters");
return;
}
//m_log.DebugFormat("MAP NAME=({0})", mapName);
// Hack to get around the fact that ll V3 now drops the port from the
@@ -148,8 +112,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
// try to fetch from GridServer
List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
if (regionInfos.Count == 0)
remoteClient.SendAlertMessage("Hyperlink could not be established.");
m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags);
List<MapBlockData> blocks = new List<MapBlockData>();
MapBlockData data;
if (regionInfos.Count > 0)
{
foreach (GridRegion info in regionInfos)
@@ -176,7 +145,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
}
// final block, closing the search result
AddFinalBlock(blocks);
data = new MapBlockData();
data.Agents = 0;
data.Access = 255;
data.MapImageId = UUID.Zero;
data.Name = ""; // mapName;
data.RegionFlags = 0;
data.WaterHeight = 0; // not used
data.X = 0;
data.Y = 0;
blocks.Add(data);
// flags are agent flags sent from the viewer.
// they have different values depending on different viewers, apparently
@@ -188,26 +166,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
if (flags == 2)
{
if (regionInfos.Count == 0)
remoteClient.SendAlertMessage("No regions found with that name.");
remoteClient.SendAgentAlertMessage("No regions found with that name.", true);
else if (regionInfos.Count == 1)
remoteClient.SendAlertMessage("Region found!");
remoteClient.SendAgentAlertMessage("Region found!", false);
}
}
private void AddFinalBlock(List<MapBlockData> blocks)
{
// final block, closing the search result
MapBlockData data = new MapBlockData();
data.Agents = 0;
data.Access = 255;
data.MapImageId = UUID.Zero;
data.Name = "";
data.RegionFlags = 0;
data.WaterHeight = 0; // not used
data.X = 0;
data.Y = 0;
blocks.Add(data);
}
// private Scene GetClientScene(IClientAPI client)
// {
// foreach (Scene s in m_scenes)

View File

@@ -83,7 +83,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="AttachmentPt"></param>
/// <param name="silent"></param>
/// <returns>true if the object was successfully attached, false otherwise</returns>
bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent);
bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool temp);
/// <summary>
/// Rez an attachment from user inventory and change inventory status to match.

View File

@@ -25,8 +25,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Drawing;
using System.IO;
using OpenMetaverse;
@@ -35,14 +33,7 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IDynamicTextureManager
{
void RegisterRender(string handleType, IDynamicTextureRender render);
/// <summary>
/// Used by IDynamicTextureRender implementations to return renders
/// </summary>
/// <param name='id'></param>
/// <param name='data'></param>
/// <param name='isReuseable'></param>
void ReturnData(UUID id, IDynamicTexture texture);
void ReturnData(UUID id, byte[] data, bool isReuseable);
UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
int updateTimer);
@@ -134,53 +125,11 @@ namespace OpenSim.Region.Framework.Interfaces
// /// <param name='extraParams'></param>
// bool AlwaysIdenticalConversion(string bodyData, string extraParams);
IDynamicTexture ConvertUrl(string url, string extraParams);
IDynamicTexture ConvertData(string bodyData, string extraParams);
byte[] ConvertUrl(string url, string extraParams);
byte[] ConvertData(string bodyData, string extraParams);
bool AsyncConvertUrl(UUID id, string url, string extraParams);
bool AsyncConvertData(UUID id, string bodyData, string extraParams);
void GetDrawStringSize(string text, string fontName, int fontSize,
out double xSize, out double ySize);
}
public interface IDynamicTexture
{
/// <summary>
/// Input commands used to generate this data.
/// </summary>
/// <remarks>
/// Null if input commands were not used.
/// </remarks>
string InputCommands { get; }
/// <summary>
/// Uri used to generate this data.
/// </summary>
/// <remarks>
/// Null if a uri was not used.
/// </remarks>
Uri InputUri { get; }
/// <summary>
/// Extra input params used to generate this data.
/// </summary>
string InputParams { get; }
/// <summary>
/// Texture data.
/// </summary>
byte[] Data { get; }
/// <summary>
/// Size of texture.
/// </summary>
Size Size { get; }
/// <summary>
/// Signal whether the texture is reuseable (i.e. whether the same input data will always generate the same
/// texture).
/// </summary>
bool IsReuseable { get; }
}
}

View File

@@ -149,19 +149,6 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="itemId"></param>
void StopScriptInstance(UUID itemId);
/// <summary>
/// Try to get the script running status.
/// </summary>
/// <returns>
/// Returns true if a script for the item was found in one of the simulator's script engines. In this case,
/// the running parameter will reflect the running status.
/// Returns false if the item could not be found, if the item is not a script or if a script instance for the
/// item was not found in any of the script engines. In this case, running status is irrelevant.
/// </returns>
/// <param name='itemId'></param>
/// <param name='running'></param>
bool TryGetScriptInstanceRunning(UUID itemId, out bool running);
/// <summary>
/// Add an item to this entity's inventory. If an item with the same name already exists, then an alternative
/// name is chosen.
@@ -280,26 +267,18 @@ namespace OpenSim.Region.Framework.Interfaces
void ApplyGodPermissions(uint perms);
/// <summary>
/// Number of items in this inventory.
/// </summary>
int Count { get; }
/// <summary>
/// Returns true if this inventory contains any scripts
/// </summary></returns>
bool ContainsScripts();
/// <summary>
/// Number of scripts in this inventory.
/// </summary>
/// <remarks>
/// Includes both running and non running scripts.
/// </remarks>
/// Returns the count of scripts contained
/// </summary></returns>
int ScriptCount();
/// <summary>
/// Number of running scripts in this inventory.
/// Returns the count of running scripts contained
/// </summary></returns>
int RunningScriptCount();

View File

@@ -35,7 +35,7 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IJsonStoreModule
{
bool CreateStore(string value, ref UUID result);
bool CreateStore(string value, out UUID result);
bool DestroyStore(UUID storeID);
bool TestPath(UUID storeID, string path, bool useJson);
bool SetValue(UUID storeID, string path, string value, bool useJson);

View File

@@ -25,20 +25,15 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Runtime.Serialization;
using OpenMetaverse;
using OpenSim.Framework;
namespace OpenSim.Region.ScriptEngine.Shared
namespace OpenSim.Region.Framework.Interfaces
{
[Serializable]
public class ScriptException : Exception
public interface IRegionConsole
{
public ScriptException() : base() {}
public ScriptException(string message) : base(message) {}
public ScriptException(string message, Exception innerException) : base(message, innerException) {}
public ScriptException(SerializationInfo info, StreamingContext context) :base(info, context) {}
bool RunCommand(string command, UUID invokerID);
void SendConsoleOutput(UUID agentID, string message);
void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn);
}
}
}

View File

@@ -54,9 +54,9 @@ namespace OpenSim.Region.Framework.Interfaces
void RegisterScriptInvocation(object target, string method);
/// <summary>
/// Register an instance method as a script call by method info
/// Register a static or instance method as a script call by method info
/// </summary>
/// <param name="target"></param>
/// <param name="target">If target is a Type object, will assume method is static.</param>
/// <param name="method"></param>
void RegisterScriptInvocation(object target, MethodInfo method);
@@ -67,6 +67,13 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="methods"></param>
void RegisterScriptInvocation(object target, string[] methods);
/// <summary>
/// Register one or more static methods as script calls by method name
/// </summary>
/// <param name="target"></param>
/// <param name="methods"></param>
void RegisterScriptInvocation(Type target, string[] methods);
/// <summary>
/// Returns an array of all registered script calls
/// </summary>

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