Compare commits

...

470 Commits

Author SHA1 Message Date
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
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
Justin Clark-Casey (justincc)
374ebab574 Strip experimental tag from --publish option of "save oar" region console command 2012-08-03 23:54:17 +01:00
Justin Clark-Casey (justincc)
fb91ca6f1d Fix old regression that stopped saving parcel owner data in OARs.
This was working in 0.7.2 but was accidentally removed from 0.7.3.
The --publish option for "save oar" will now save oars stripped of parcel owner information as well as scene object info.
Please use the --publish option if you want to publish oars that may be later loaded by others to the same grid from which they were saved.
2012-08-03 23:49:34 +01:00
Justin Clark-Casey (justincc)
2724cf685e Fix build break. 2012-08-03 23:13:19 +01:00
Robert Adams
8730dc9d6a Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-03 15:10:55 -07:00
Robert Adams
d5cd60131f BulletSim: update DLLs and SOs 2012-08-03 15:10:00 -07:00
Robert Adams
e7ad6ed3a3 BulletSim: pass collision subscription information to the C++ code so collisions on objects that don't care are not reported up. 2012-08-03 15:09:56 -07:00
Robert Adams
ea36d4a4cf BulletSim: Add AddObjectForce to BulletSim API.
Add interface 2 enhancements to BSCharacter.
Modify AddForce and SetForce to use the new Bullet interface.
More DetailLog statements for character.
2012-08-03 15:09:52 -07:00
Justin Clark-Casey (justincc)
0e3b08fa5b Update settings loading in AvatarFactoryModule which should have been in last commit 205f2326 2012-08-03 23:09:47 +01:00
Justin Clark-Casey (justincc)
205f2326dc Consolidate PersistBakedTextures, DelayBeforeAppearanceSend and DelayBeforeAppearanceSave into [Appearance] section from [Startup] config section so that all appearance settings are in the same place and not in the startup bucket.
All these settings are in OpenSimDefaults.ini only.  If you are using them then please adjust your OpenSim.ini
2012-08-03 23:02:39 +01:00
Justin Clark-Casey (justincc)
5914270ff1 Restore SOG constructor chaining removed in recent 513b77b. This is not a functional change. 2012-08-03 22:15:06 +01:00
Justin Clark-Casey (justincc)
faffe2f2f9 Fix the recent windows compile error by putting newFont for case "R" in VectorRenderModule inside its own context, rather than disposing of the old font before using it as a prototype for the new. 2012-08-03 22:03:04 +01:00
Justin Clark-Casey (justincc)
8327e048b9 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-03 21:56:48 +01:00
Justin Clark-Casey (justincc)
789e88d8bd Move previously unadvertised SendPeriodicAppearanceUpdates setting from [Startup] to [Appearance] config section.
Add description and default of false (as before) to OpenSimDefaults.ini
If set to true, this config switch will resend avatar appearance information (a small amount of UUID data, not the baked textures themselves) to other avatars in the sim every 60 seconds.
For me, this has helped with situations where avatars appear persistently grey - the LL viewer sometimes did not appear to request assets the first time the appearance data was sent.
However, this switch will not help with other appearance failure situations (e.g. failure to bake assets).
This setting is experimental but will not have any significant impact on the simulator if turned to true.
2012-08-03 21:36:00 +01:00
SignpostMarv
5181bdae0a attempting to fix a build issue
Signed-off-by: BlueWall <jamesh@bluewallgroup.com>
2012-08-03 16:14:01 -04:00
Justin Clark-Casey (justincc)
513b77b78d refactor: rename SOG.RezzingObjectID to SOG.FromPartID to match FromFolderID, FromItemID and to reflect that it's a SOP ID rather than a SOG ID. 2012-08-03 02:26:54 +01:00
Justin Clark-Casey (justincc)
08ec18f8a3 Don't bothre setting RezzingObjectID to UUID.Zero in SOG constructor - this is already its default value as it's a struct. 2012-08-03 02:08:04 +01:00
SignpostMarv
cd9fd77e2c ImprovedTerseObjectUpdate packet does not support shape updates, thus scheduling terse updates will not (and does not) update shape information in the viewer 2012-08-03 01:55:46 +01:00
Oren Hurvitz
0588f27d18 Fixed a rare bug that caused Save OAR to fail because it thought it had timed-out
The bug manifested as follows: a large world was saved. All the assets were found. But for some unknown reason, the timeout timer was restarted. So after 1 minute it closed the Archive Writer, because it didn't receive any more assets during that minute. That caused the OAR to become corrupted because ArchiveWriteRequestExecution.Save() was still running.
2012-08-03 01:12:46 +01:00
Kevin Cozens
72075e68c7 Save membership fee to the database when a group is created. 2012-08-03 00:44:03 +01:00
Robert Adams
8b04e8a297 BulletSim: Debugging log statements added. Reduced size of updata buffer trying to find a corrupted memory problem. Update DLL and SO. 2012-08-02 16:30:23 -07:00
Justin Clark-Casey (justincc)
293d0cc629 minor: Comment out "Deleting asset" log messages for now 2012-08-03 00:25:22 +01:00
Justin Clark-Casey (justincc)
0cd698d82b Delete old blank SOGSpamTest 2012-08-03 00:23:03 +01:00
Justin Clark-Casey (justincc)
eeef9d7e99 Properly dispose of all GDI+ entities used in VectorRenderModule for dynamic textures.
The convention is that if an object implements IDiposable() the code must explicitly call Dispose() or call it via the using statement.
This may be particularly important for GDI+ objects since they encapsulate native code entities.
2012-08-03 00:00:54 +01:00
Justin Clark-Casey (justincc)
0dfccfc1d9 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-02 23:54:32 +01:00
Melanie
68406ab8f9 Initialize the Rezzing object to UUID.Zero 2012-08-02 22:34:46 +01:00
Justin Clark-Casey (justincc)
86b005de1d Add simple draw test for the VectorRenderModule 2012-08-02 22:14:09 +01:00
SignpostMarv
cd2c5843a8 reduced-complexity implementation of function to get rezzing object key
Signed-off-by: Melanie <melanie@t-data.com>
2012-08-02 22:12:36 +01:00
Melanie
e36bc0d754 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-08-01 22:39:40 +01:00
Melanie
cf16ca9bda Create the ability for physics modules to request assets on demand by
themselves. For that, the physics module simply calls RequestAssetMethod, which
in turn points to Scene.PhysicsRequestAsset. This gives physics access to
the asset system without introducing unwanted knowledge of the scene class.
2012-08-01 22:37:38 +01:00
Justin Clark-Casey (justincc)
5f500c89ce Fix a bug in pCampbot grabbing behaviour where an exception would be thrown if the bot was not yet aware of any objects. 2012-08-01 22:30:34 +01:00
Justin Clark-Casey (justincc)
69a5beeabc Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-01 00:40:31 +01:00
Justin Clark-Casey (justincc)
794363421d Look up the NPC module when the SensorRepeat class is created, rather than on every single sensor sweep. 2012-08-01 00:39:37 +01:00
Robert Adams
c51ef38e2d BulletSim: fix problem where resizing a primary shape (cube or sphere) would not rebuild the physics mesh. Update the DLLs and SOs to latest version. 2012-07-31 16:23:52 -07:00
Robert Adams
e38d26a2dc BulletSim: change boolean parameters in the shape data from int's to float's to be consistant with parameter data structure 2012-07-31 16:23:48 -07:00
Justin Clark-Casey (justincc)
04d8c6b4fe Change exception log messages in XInventoryService connector to error rather than debug, since these signal real problems.
Also outputs full exception instead of just the message to aid diagnostics.
2012-08-01 00:11:21 +01:00
Justin Clark-Casey (justincc)
7609daca38 Resolve a deadlock between INPCModule and SensorRepeat by replacing the SensorRepeat list with a new list on add/removes rather than locking it for the duration of the sensor sweep.
A deadlock was observed today where NPC removal on a script thread would lock the NPC list and then try to lock the sensor list via scripted attachment removal.
Concurrently, the sensor sweep thread would lock the sensor list and then try to lock the NPC list to check NPC status.
This commit resolves the deadlock by replacing the sensor list on update rather than locking it for the duration of the sweep.
2012-07-31 23:57:57 +01:00
Justin Clark-Casey (justincc)
d89faa3c16 Fix bug in SoundModule.TriggerSound() 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 was making sound attenuate oddly when there were NPCs in the region, though it could also happen with ordinary avatars.
2012-07-31 22:52:17 +01:00
Mic Bowman
a76a289d11 Adds support to ScriptModuleComms for region modules to export
constants to the script engine.
2012-07-31 10:45:37 -07:00
Robert Adams
f9a8915cca BulletSim: update the DLLs and SOs. This fixes the exception on shutdown 2012-07-31 09:44:32 -07:00
Robert Adams
50dbb9ffe4 BulletSim: add parameters and API calls for setting ERP and CFM.
Set ERP and CFM in linkset constraints.
Reorder rebuilding of object bodies so they are not rebuilt everytime
   something is linked and unlinked.
2012-07-31 09:23:05 -07:00
Justin Clark-Casey (justincc)
6b1d12edcb Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-07-30 23:25:54 +01:00
Justin Clark-Casey (justincc)
b899d64dc1 If we're fetching active gestures via the XInventoryServiceConnector, then properly look at the ITEMS dictionary already returned rather than the level above this. 2012-07-30 23:14:20 +01:00
Melanie
3f6dfa92ab Return world rotation on llGetObjectDetails()'s OBJECT_ROT 2012-07-29 16:05:35 +01:00
SignpostMarv
72d29bdb40 LSL/OSSL lacks Math.Min & Math.Max implementations. 2012-07-28 00:09:11 +01:00
Justin Clark-Casey (justincc)
7e89b99e6a Avoid a race condition between the scene shutdown thread and the update thread since commit c150320 (Thu Jul 26 15:27:18 2012)
c150320 started explicitly disposing of the physics scene and nulling it out on region shutdown.
However, the update loop may not have yet checked Scene.ShuttingDown, particularly if avatars were not in the scene, causing failure when it tried to lookup time dilation.
This commit moves the setting of m_shuttingDown above the existing 500ms pause to notify avatars that they are being kicked.
This should not affect the few other places that use this flag.
2012-07-27 23:58:53 +01:00
SignpostMarv
adbdb220df making first run more resilient to bad input (loop until good input, rather than crash) 2012-07-27 23:40:19 +01:00
SignpostMarv
b23ab3ea85 adding asset cache and map tile directories to .gitignore 2012-07-27 23:37:24 +01:00
Justin Clark-Casey (justincc)
d4f476c7ce Remove the LandGeom checks in OdeScene - these are pointless since LandGeom is always IntPtr.Zero and contacts returned always have a valid geometry.
Possibly this was for a feature that was never implemented or was otherwise removed.
Thanks to SignpostMarv for the spot of the warning that shows this parameter was never changed.
2012-07-27 23:31:19 +01:00
justincc
134c6d181f Update OpenMetaverse libraries at commit 6212cbd, this time built on Windows
This is to try and resolve a strange Initialization exception for the AppearanceManager type that only occurs on Windows 64 bit (not Windows 32 bit or Linux!)
2012-07-27 23:05:17 +01:00
Justin Clark-Casey (justincc)
f3c5ce1bbd minor: Comment out unused MemoryWatchdog.m_churnRatePerMillisecond - this is currently calculated dynamically 2012-07-27 22:20:43 +01:00
Justin Clark-Casey (justincc)
0d9afad3fe Remove duplicated IScenePresence.PresenceType. This is already in ISceneAgent.PresenceType from which IScenePresence inherits.
No other code changes required.
2012-07-27 22:15:25 +01:00
Justin Clark-Casey (justincc)
cd44c3b90a Replace libopenmetaverse commit 6212cbd with the same libraries but this time built with xbuild rather than nant.
This may fix Windows and some mono version builds.
2012-07-27 21:50:18 +01:00
Justin Clark-Casey (justincc)
1133f81dce Remove a couple of compiler warnings pointed out by SignpostMarv 2012-07-27 20:40:25 +01:00
Justin Clark-Casey (justincc)
811dc95105 Update libopenmetaverse to commit 6212cbd (Wed Jul 25 20:11:47 2012)
Built from https://github.com/openmetaversefoundation/libopenmetaverse/commits/master
This update incorporates a fix by Melanie in libomv where textures would sometimes rotate slightly when other properties were changed.
Hence addresses http://opensimulator.org/mantis/view.php?id=6100
This update also incorporates libomv bot code updates that significantly reduce the warning spam for pCampbot.
The change rate of libomv is low and many changes refer to bot or code not used by OpenSimulator, so I think it is sufficiently stable to use evne though it's not a release.
2012-07-27 20:16:29 +01:00
BlueWall
6ee17f5b36 Add autoclean for scripted use
./runprebuild.sh autoclean - cleans projects w/o prompting
2012-07-26 21:39:53 -04:00
BlueWall
f4bae34283 Add target switches
./runprebuild.sh vs2008/vs2010 to set the target
2012-07-26 21:34:33 -04:00
BlueWall
faf250df2d add clean task to reuprebuild.sh
./runprebuild.sh clean to clean up the project files
2012-07-26 21:28:20 -04:00
Justin Clark-Casey (justincc)
5f741143fd Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-07-27 00:30:04 +01:00
Justin Clark-Casey (justincc)
21b1fec32d Fix issue where RegionCombinerModule was not removing regions from its dictionary on RemoveRegion(), causing a later issue if regions were restarted (removed then readded). 2012-07-27 00:28:23 +01:00
Robert Adams
ce812c88cc BulletSim: fix a recursive loop when fetching the mass of the root of a linkset. 2012-07-26 16:06:00 -07:00
Robert Adams
7d30637d51 BulletSim: refactor all the linkset logic out of the prim class
and into its own class. The BulletSim data structures track
individual prims as linksets of 1 so most of the prim code is not
different between a linked and unlinked object.
2012-07-26 16:05:57 -07:00
Robert Adams
d4a667a918 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-07-26 16:04:11 -07:00
Robert Adams
9e914f5c32 Add check so Ode does not try to simulate after it has been Dispose()'ed. Fixes exception that happens when shutting down region (improvements from last patch) 2012-07-26 16:03:15 -07:00
Justin Clark-Casey (justincc)
0aaf52fca4 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-07-26 23:46:54 +01:00
Justin Clark-Casey (justincc)
66824dd18c When copying items, copy the item description field instead of the asset description field.
If we copy the asset description then we will only ever replicate the very first description, if there was one, not any subsequent changes.
Thanks to Oren Hurvitz of Kitely for this patch from http://opensimulator.org/mantis/view.php?id=6107
I have adapted it slightly to change the order of arguments (name before description rather than vice-versa) and slightly improve some method doc.
2012-07-26 23:44:29 +01:00
Robert Adams
c1503205c0 Add a Dispose() of the physics engine when a scene is being shutdown. 2012-07-26 15:27:18 -07:00
Robert Adams
c6d02801db BulletSim: update BulletSim DLLs and SOs 2012-07-25 16:31:22 -07:00
Robert Adams
9ca1075e7e BulletSim: remove unused, commented out code in BSConstraint 2012-07-25 16:31:17 -07:00
Robert Adams
0a4c080e63 BulletSim: fix line endings in newly added files (Is it DOS or is it UNIX? Only it's hairdresser knows for sure) 2012-07-25 16:31:12 -07:00
Robert Adams
d7add2940a BulletSim: add parameters for setting linkset constraint factors 2012-07-25 16:31:08 -07:00
Robert Adams
75f7721b0c BulletSim: small change to use the pointer to the bullet object for zeroing forces. 2012-07-25 16:31:04 -07:00
Robert Adams
bf6529db32 BulletSim: Redo parameter specification so only one place has
to change to have a parameter show up in the ini file and
command line. Will make it much easier for the next person.
2012-07-25 16:30:59 -07:00
Robert Adams
2d05e16f7e BulletSim: Add C# classes for storing and tracking constraints. 2012-07-25 16:30:55 -07:00
Robert Adams
5707e171f4 BulletSim: Move constraint tracking from C++ code to C# code
for more flexibility.
2012-07-25 16:30:50 -07:00
Justin Clark-Casey (justincc)
5aec0ff207 Move Watchdog and MemoryWatchdog classes into OpenSim.Framework.Monitoring with other monitoring code from OpenSim.Framework 2012-07-25 23:27:00 +01:00
Justin Clark-Casey (justincc)
35efa88c26 Rename OpenSim.Framework.Statistics to OpenSim.Framework.Monitoring.
This better reflects the long-term purpose of that project and matches Monitoring modules.
2012-07-25 23:11:50 +01:00
Justin Clark-Casey (justincc)
227126adb7 Add MemoryWatchdog class missing from git master a1e9964 2012-07-25 22:38:28 +01:00
Justin Clark-Casey (justincc)
22aa436648 Correct churn stat from MB/s from KB/s 2012-07-25 22:33:24 +01:00
Justin Clark-Casey (justincc)
a1e99642c1 Add experimental "OpenSim object memory churn" statistics to output of region console "show stats" command
This aims to capture the amount of memory that OpenSim turns over whilst operating a region.
This memory is not lost - apart from leaks it is reclaimed by the garbage collector.
However, the more memory that gets turned over the more work the GC has to do to reclaim it.
2012-07-25 22:29:40 +01:00
Justin Clark-Casey (justincc)
31304c222d Make SceneManager.OnRegionsReadyStatusChange event available.
This is fired when all regions are ready or when at least one region becomes not ready.
Recently added EventManager.OnRegionReady becomes OnRegionReadyStatusChange to match OnLoginsEnabledStatusChange
2012-07-25 21:00:59 +01:00
Justin Clark-Casey (justincc)
3cf8edfd68 Rename "image queues clear" console command to "clear image queues"
There is less justification for this word arrangement (verb after noun) now that command help is categorized.
Also removes "image queues show" in favour of existing alias "show image queues".
2012-07-24 23:51:04 +01:00
Justin Clark-Casey (justincc)
1427430b7b Add information about each column to "show queues" region console command help. 2012-07-24 23:48:53 +01:00
Justin Clark-Casey (justincc)
ef8570f789 Extend region console "show queues" command to show already collected time since last packeted received by the simulator from a viewer. 2012-07-24 23:39:31 +01:00
Justin Clark-Casey (justincc)
c846a5461c Remove bad using statement in AttachmentsModuleTests.
It seems that the mono 2.10.8.1 doesn't choke on this but for some reason 2.4.3 fails.
2012-07-24 22:46:22 +01:00
Justin Clark-Casey (justincc)
c992629576 extend regression TestRezScriptedAttachmentFromInventory() to check actual start of script rather than just the script status reported by SOG.ContainsScripts() 2012-07-24 22:40:06 +01:00
Justin Clark-Casey (justincc)
bc13c52c98 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-07-24 22:38:26 +01:00
Justin Clark-Casey (justincc)
2858b1b1f4 extend regression TestDetachScriptedAttachementToInventory() to check correct running status on a re-rezzed attachment 2012-07-24 22:33:54 +01:00
Robert Adams
892dd59b13 BulletSim: update BulletSim.dlls and so's 2012-07-23 16:38:31 -07:00
Robert Adams
bf6547be01 BulletSim: change how prim mass is saved so it is always calculated but zero is given if not physical. 2012-07-23 16:32:47 -07:00
Robert Adams
dda681515b BulletSim: small optimizations for link and unlink code 2012-07-23 16:32:41 -07:00
Robert Adams
8a574395c7 BulletSim: add Dispose() code to free up resources and close log files. 2012-07-23 16:32:36 -07:00
Robert Adams
85c6eb7c50 BulletSim: add all the new functions to BulletSimAPI.
Modify ZeroMotion() to not make tainting calls and to use new API calls.
2012-07-23 16:32:30 -07:00
Robert Adams
73f9e14b43 BulletSim: improve linking to add each link individually rather than rebuilding the object each time. Makes it an O(n) operation rather than O(n\!). 2012-07-23 16:32:24 -07:00
Melanie
e126915bc1 Change attachment handling to remove object from the scene first as per
justincc's original work. Sample scripts before doing so. Also refactor some
crucial common code and eliminate parameters that were only ever used with
the same constant value.
2012-07-23 21:39:26 +01:00
Melanie
fc77bca936 Committing Avination's memleak fix-a-thon, installment #3
When linking, detach the no longer used SOG's from backup so they can be
collected. Since their Children collection is never emptied, they prevent
their former SOPs from being collected as well.
2012-07-23 19:53:26 +01:00
Melanie
55c1c10c0d Committing Avination's memleak fix-a-thon, installment #2
Ensure items coming off the lockless queue are released. Also ensure this
is done when the queue is cleared.
2012-07-23 19:26:21 +01:00
Melanie
7d16d0664e Commiting Avination's memleak fix-a-thon, installment #1
As the MinHeap shrinks, free object references that have been sent. Also,
free the last item when it empties.
2012-07-23 19:21:59 +01:00
Robert Adams
ac612e2105 Update BulletSim DLLs and SOs 2012-07-20 16:12:54 -07:00
Justin Clark-Casey (justincc)
1b1418e1de Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-07-20 23:47:25 +01:00
Robert Adams
b537bbc410 Reorder BulletSim in prebuild.xml so OpenSim.Region.CoreModules is compiled before BulletSim is 2012-07-20 15:44:53 -07:00
Robert Adams
b25d874afa BulletSim: add reference to OpenSim.Region.CoreModules in BSScene.cs attempting to fix a mono compile error. 2012-07-20 15:34:19 -07:00
Justin Clark-Casey (justincc)
ef14232e64 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-07-20 23:20:40 +01:00
Justin Clark-Casey (justincc)
13929613b1 Move RegionConfig.ini.example into bin/Regions/Regions.ini.example - all other example files are in the same directory as their real files.
Only files ending in .ini and .xml are actually loaded.
Also improves the help at the top of Regions.ini.example to mention that OpenSimulator would generate Regions.ini anyway on first startup.
2012-07-20 23:18:41 +01:00
Robert Adams
ca3b6b1f90 BulletSim: more detail logging for vehicle and general physics debugging.
Physical linksets are fully functional.
Tweeking of the vehicle code to make it semi-work.
Utilize the new API2 for some setting operations.
Add GetOrientation() API call for proper reporting of children of linksets.
Changes the interface between C# and C++ code so old DLLs won't work!
2012-07-20 14:08:29 -07:00
Robert Adams
24dfb5bcb3 Remove an added but unnecessary dependency in prebuild.xml 2012-07-20 14:07:35 -07:00
Robert Adams
7451bb1613 BulletSim: fix compile errors from last commit. Clean up passing of physics scene into vehicle dynamics code. 2012-07-20 14:02:29 -07:00
Robert Adams
cda67a68de BulletSim: Add very detailed logging to BSDynamics for vehicle debugging 2012-07-20 14:02:27 -07:00
Robert Adams
e9c437ed0e Correct namespace of BinaryLoggingModule (a cut-and-paste error). Add a simple, high performance logger for high frequency logging (physics sub-operations, for instance). 2012-07-20 14:02:26 -07:00
Robert Adams
c400918c84 BulletSim: Add PID variables to physical scene. Not PIDing yet, but soon.
Cleaned up code and got rid of compile warnings.
2012-07-20 14:02:24 -07:00
Robert Adams
f9913b6ef7 BulletSim: Add detailed and voluminous debug logging that is enabled
with an ini configuration parameter.
Correct computation of relative offsets of children in a linkset.
Remove a prim from any link relationship before deleting it.
Minor code flow cleanups.
2012-07-20 14:02:22 -07:00
Justin Clark-Casey (justincc)
ecf7bb268c As per opensim-dev mailing list discussion, extend llGetDetectedType() to return OS_NPC if an OS npc is detected.
The detection will also return agent is the NPC has been created with the OS_NPC_SENSE_AS_AGENT option.
2012-07-20 21:36:33 +01:00
Justin Clark-Casey (justincc)
bcfc392edf As per opensim-dev mailing list conversation, introduce OS_NPC constant for use with llSensor()
This same constant will later be used with llGetDetectedType().
This constant has a different name from NPC to avoid possible conflict with future LSL changes.
This constant has a different value to try and avoid unnecessary conflict with future constants that may use the same value.
Using the 'NPC' constant with llSensor() will remain valid but is deprecated.
2012-07-20 21:08:04 +01:00
Mic Bowman
a4281ca014 Enables support for UUIDs to be returned in lists from
modInvoke commands.

Thanks SignpostMarv!!!
2012-07-20 10:48:51 -07:00
Mic Bowman
644fb6b013 Implements a very useful OSSL function to test a string to see
if it is a UUID. The function is osIsUUID().

Thanks SignpostMarv!
2012-07-20 10:25:50 -07:00
Melanie
fe99948c58 Fix the order of operations on detach. The object must always be serialized
while still in the scene to avoid losing important script state.
DeleteSceneObject can not be called before doing this!
2012-07-20 11:54:59 +02:00
Justin Clark-Casey (justincc)
be39f03caa minor: switch around mixed up circuit code and endpoint data in "show connections" region console command 2012-07-19 23:35:56 +01:00
Justin Clark-Casey (justincc)
d1d331a4c0 Make LLClientView instant message handling asynchronous rather than synchronous to prevent long operations from holding up all inbound packet processing.
Giving a large folder from one avatar to another was causing a long delay when handled synchronously, since it took some time to retrieve the necessary data from the inventory service.
Handling this asynchronously instead stops this delay from disrupting all avatars in the scene.  This has been shown in OSGrid.
I see no reason for not handling all IM messages asynchronously, just as incoming chat is handled asynchronously, so this has been switched for all instant messages.
Thanks to Nebadon for testing this change out.
2012-07-19 23:20:03 +01:00
Justin Clark-Casey (justincc)
c4533e755b Comment out OnIncomingInstantMessage and OnInstantMessage handlers in GroupsModule, since these led to a private blank method 2012-07-19 23:13:08 +01:00
Justin Clark-Casey (justincc)
e94831ddab Stop explicitly closing and nulling out Animator in order to prevent NREs in various places due to race conditions.
Even where checks are being made they aren't enough since they all assume that the Animator they just checked is still there in the next line, which is not necessarily the case without locking.
The memory used is small and these should be GC'd anyway when the SP is released.  If this is not happening then the wider problem of old SPs being retained needs to be resolved.
2012-07-19 22:59:28 +01:00
Justin Clark-Casey (justincc)
ccc7e75ce4 minor: remove some mono compiler warnings 2012-07-19 22:37:48 +01:00
Justin Clark-Casey (justincc)
ba80f137b5 Prevent race conditions between two threads that call LLClientView.Close() simultaneously (e.g. ack timeout and an attempt to reconnect) 2012-07-19 22:32:27 +01:00
Justin Clark-Casey (justincc)
e9a121e1b2 Add TestCreateDuplicateRootScenePresence() regression test. 2012-07-19 21:54:50 +01:00
Justin Clark-Casey (justincc)
c0ab406e2e Add basic TestCreateRootScenePresence() regression test 2012-07-19 21:41:13 +01:00
Justin Clark-Casey (justincc)
6dda7c65ae Add EventManager.OnRegionLoginsStatusChange fired whenever logins are enabled or disabled at any point, not just during initial startup.
This replaces EventManager.OnLoginsEnabled which only fired when logins were first enabled
and was affected by a bug where it would never fire if the region started with logins disabled.
2012-07-19 00:09:22 +01:00
Justin Clark-Casey (justincc)
64db0bcbd2 Add back notification to neighbouring regions when RegionReadyModule is not active accidentally just removed in 528004d 2012-07-18 23:40:00 +01:00
Justin Clark-Casey (justincc)
528004d349 Perform other region ready actions even if simulator is configured to leave logins disabled on startup. 2012-07-18 23:35:05 +01:00
Justin Clark-Casey (justincc)
1971b6bb4f Stop the 15 second initial script compile wait if a script is being rezzed on a previously empty region. 2012-07-18 22:24:52 +01:00
Justin Clark-Casey (justincc)
d97e27434c Fix bug where region ready would be triggered a second time if a script was rezzed on a previously script-free region.
There is no need to listen for OnRezScript in RegionReadyModule since OnEmptyScriptCompileQueue will only fire if scripts were compiled.
2012-07-18 22:17:39 +01:00
Justin Clark-Casey (justincc)
58b72933c8 Fix bug where region ready was being triggered twice in quick succession if a region contained no scripts. 2012-07-18 22:09:20 +01:00
Justin Clark-Casey (justincc)
4973fddc51 Establish EventManager.OnRegionReady event. This will only be triggerred once when the region is ready.
Switch MapImageServiceModule to use this.
2012-07-18 21:52:07 +01:00
Justin Clark-Casey (justincc)
6460e587c4 Pass entire scene object in OnLoginsEnabled event rather than just the region name.
This saves listeners from having to re-retrieve the scene from their own lists, which won't work anyway if multiple regions with the same name have been allowed
2012-07-18 21:29:12 +01:00
Justin Clark-Casey (justincc)
742ad5eb93 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-07-18 21:26:28 +01:00
Dan Lake
dd85d7d981 Merge branch 'master' of git://opensimulator.org/git/opensim 2012-07-18 13:07:07 -07:00
Dan Lake
0dd14ca0a3 Missing parameter in log error message was throwing exception 2012-07-18 13:05:48 -07:00
Justin Clark-Casey (justincc)
cd6d7429f8 Only listen to LoginsEnabled event in RegionReadyModule if it has been asked to disable logins until all scripts have been compiled 2012-07-18 21:03:35 +01:00
Justin Clark-Casey (justincc)
eb590becf0 Close() the ScenePresence after we've removed it from the scene graph, to cut down race conditions when another thread manages the grab the presence after some SP structures have been reset. 2012-07-18 00:14:02 +01:00
Justin Clark-Casey (justincc)
b9749d5aaf Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-07-17 23:48:53 +01:00
Justin Clark-Casey (justincc)
48a5f10be1 Revert "Revert "refactor: make llGiveInventory() use existing GetInventoryItem() method rather than iterate through TaskInventory itself.""
This reverts commit 59a29f5f22.
The original revert was committed by mistake - it turns out this was not the cause of Mantis 6089

Conflicts:

	OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
2012-07-17 23:48:09 +01:00
Justin Clark-Casey (justincc)
56870d9609 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-07-17 23:34:50 +01:00
Justin Clark-Casey (justincc)
ecb759c1e5 Fix regression where llGiveInventory() had stopped asking non-owner receivers to accept/decline.
This appears to be a regression from back in commit db91044 (Mon Aug 22 2011) where we started to send TaskInventoryOffered msg dialog rather than InventoryOffered dialog.
This is probably correct, but failed because the bucket was too large and because we wouldn't have handled the TaskInventoryDeclined option anyway.
This patch handles both of these and make llGiveInventoryList() use TaskInventoryOffered as well
Fixes http://opensimulator.org/mantis/view.php?id=6089
2012-07-17 23:31:38 +01:00
Justin Clark-Casey (justincc)
59a29f5f22 Revert "refactor: make llGiveInventory() use existing GetInventoryItem() method rather than iterate through TaskInventory itself."
This reverts commit 58b13d51a7.
2012-07-17 22:56:21 +01:00
Melanie
c489bc1cd2 Make the scrpt running flag work properly 2012-07-17 15:00:42 +02:00
Justin Clark-Casey (justincc)
356d597296 Restore update of inventory item on derez/logout. This is necessary to update the name if this has been changed whilst attached.
Note, this behaviour appears to be at variance with the ll grid as of Tues 17 July 2012, testing with viewer 3.2.1.
The item name in inventory does not change either at the point of detach or after a relog.
2012-07-17 00:17:51 +01:00
Justin Clark-Casey (justincc)
b0facd147a Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-07-17 00:02:45 +01:00
Justin Clark-Casey (justincc)
b6476eaac3 Stop sending the viewer an inventory create message if a known attachment item is updated.
This doesn't seem to make any sense and probably stems from a period when this code was directly involved in attaching objects directly from the scene.
This message is already being sent by InventoryAccessModule code instead.
2012-07-17 00:00:26 +01:00
Melanie
2a85372169 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-07-16 23:33:33 +01:00
Melanie
1c3b0da74a Revert "Fix script "Running" behavior"
A better solution using the already present flags must be found.

This reverts commit 6d3ee8bb39.
2012-07-16 23:31:55 +01:00
Justin Clark-Casey (justincc)
c1667d39a6 refactor: factor out common code in WebStatsModule.OnMakeRootAgent() 2012-07-16 23:15:02 +01:00
Justin Clark-Casey (justincc)
217f47b0d5 In WebStatsModule.OnMakeRootAgent(), get region ID directly from SP.Scene.RegionInfo.RegionID instead of manually looking it up from the stored scene list. 2012-07-16 23:09:48 +01:00
Justin Clark-Casey (justincc)
ed14dac0a3 Stop warning about no session from ViewerStats if user teleports to another region in the same simulator that was not next to the source region.
This was because teleporting to the new region invoked the new session setup code before the agent was removed from the old region, which then invoked the session teardown code.
Now, we only invoke the teardown code if the region ID occupied by the agent being removed is the same as the one registered for the current session.
2012-07-16 23:03:23 +01:00
SignpostMarv
ee7478fa16 sending more user-friendly messages to the script error window rather than the thrown exceptions.
Signed-off-by: Melanie <melanie@t-data.com>
2012-07-16 21:32:38 +01:00
dahlia
5d3723a47f update PrimMesher.cs to dll version r72 which fixes some path errors in sliced linear prims. Addresses Mantis #6085 2012-07-13 21:22:15 -07:00
SignpostMarv
84b7ae2573 acting on feedback from justincc 2012-07-14 01:45:34 +01:00
SignpostMarv
423101b425 acting on feedback from justincc 2012-07-14 01:45:34 +01:00
SignpostMarv
e3453dd9ca added in some extra variables, it sometimes thinks it is on the same parcel :(
Signed-off-by: SignpostMarv <github@signpostmarv.name>
2012-07-14 01:45:34 +01:00
SignpostMarv
b6cd3b625e adding workaround for silent failure if position is outside the bounds of a region, implementing parcel prim count check.
Signed-off-by: SignpostMarv <github@signpostmarv.name>
2012-07-14 01:45:34 +01:00
SignpostMarv
8d59385eea Implementation of llSetRegionPos(). Does not implement failure on object entry/prim limit/access restrictions.
Signed-off-by: SignpostMarv <github@signpostmarv.name>
2012-07-14 01:45:34 +01:00
Justin Clark-Casey (justincc)
ec6a195e40 When generating a Warp3D texture, set the detailTexture[i] variable on resize from the JPEG2000 original rather than only saving it to disk.
This appears to be the cause of the warp 3d exception seen when starting a new region for the first time.
Subsequent starts were okay because resized saved bitmap was correctly retrieved from disk.
Should fix http://opensimulator.org/mantis/view.php?id=5204 and http://opensimulator.org/mantis/view.php?id=5272
2012-07-14 01:11:30 +01:00
Justin Clark-Casey (justincc)
2954ceccae Remove a callstack print out I accidentally left in 2 commits ago in 9ccb578 2012-07-13 01:08:49 +01:00
Justin Clark-Casey (justincc)
884d603cac Rather than instantiating a UTF8 encoding everywhere when we want to supress the BOM, use a single Util.UTF8NoBomEncoding.
This class is thread-safe (as evidenced by the provision of the system-wide Encoding.UTF8 which does not suppress BOM on output).
2012-07-13 01:03:28 +01:00
Justin Clark-Casey (justincc)
9ccb578721 Don't cache regions data on the other unused LocalGridServiceConnector that the module code still sets up even if we're using one directly instantiated from the RemoteGridServiceConnector.
Also improves log messages to indicate which regions are sending/receiving various neighbour protocol messages.
2012-07-13 00:44:00 +01:00
Justin Clark-Casey (justincc)
d6f54b25cd Stop redundantly passing in the endpoint to the LLClientView constructor.
This can always be retrieved via the LLUDPClient and is so done in various places already.
2012-07-12 23:48:42 +01:00
Justin Clark-Casey (justincc)
dda999a22c Remove IClientIPEndpoint client interface for now.
This may well come back in the future when this subinterface is actually used but it currently isn't and I feel the name was poor.
Everything uses IClientAPI.RemoveEndPoint which also returned the full endpoint rather than just the ip address.
2012-07-12 23:43:02 +01:00
Justin Clark-Casey (justincc)
3b3d9967b1 Remove IClientAPI.GetClientEP() in favour of existing identical IClientAPI.RemoteEndpoint. 2012-07-12 23:29:57 +01:00
Justin Clark-Casey (justincc)
75ab9b4b88 Change very recent AllowedViewerList and BannedViewerList config setting names in OpenSim.ini.example to AllowedClients and BannedClients to match long-existing settings in [LoginService]
Also changes separator from comma to bar to match existing [LoginService] config features.
Divergence of config names for identical facilities in different places makes for an unnecessarily confusing user experience.
2012-07-12 23:18:30 +01:00
Justin Clark-Casey (justincc)
15283d35f1 Extend "show circuits" to show circuit code, ip and viewer name.
Also change to use standard table formatting
"show circuits" and "show connections" console commands are very similar but access different data structures.
2012-07-12 23:09:36 +01:00
Justin Clark-Casey (justincc)
6a0de355e0 Add active status to "show connections" 2012-07-12 22:37:48 +01:00
Justin Clark-Casey (justincc)
65a25ee510 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-07-12 22:35:38 +01:00
Justin Clark-Casey (justincc)
ca412032e8 Put output for "show connections" command into standard table format.
Also moves into own method.
2012-07-12 21:36:33 +01:00
Robert Adams
743437262e Many explanitory comments added to the link and delink code in
SOG and SOP. Should have no functionality changes.
2012-07-11 16:12:38 -07:00
Justin Clark-Casey (justincc)
916e3bf886 Where possible, use the system Encoding.ASCII and Encoding.UTF8 rather than constructing fresh copies.
The encodings are thread-safe and already used in such a manner in other places.
This isn't done where Byte Order Mark output is suppressed, since Encoding.UTF8 is constructed to output the BOM.
2012-07-11 22:54:22 +01:00
Justin Clark-Casey (justincc)
9c89ad9154 Fix build break for windows with missing package for IScriptEngine in prebuild.xml for OpenSim.Region.CoreModules.Tests.dll 2012-07-11 22:15:53 +01:00
Justin Clark-Casey (justincc)
33cff9b9d7 Allow XEngine StartDelay to be configured in the [XEngine] config section.
This is only currently meant for use by regression tests that don't have any issues if XEngine is started up quickly, since no other operations will be occuring simultaneously.
Therefore, this is not yet documented externally.
2012-07-11 21:55:18 +01:00
Justin Clark-Casey (justincc)
0e611c47d3 Remove WorldComm module from the regression TestCompileAndStartScript() since the infrastructure no longer fails if this module isn't present, at least on the tested codepaths 2012-07-11 21:46:46 +01:00
Justin Clark-Casey (justincc)
fc24563206 Add regression TestDetachScriptedAttachmentToInventory()
This currently only does a relatively crude check for a ScriptState node in the serialized xml
2012-07-11 21:43:35 +01:00
Justin Clark-Casey (justincc)
14d05dc2a9 Add regression TestRezScriptedAttachmentsFromInventory() though this currently only checks for the presence of script items, not for started scripts 2012-07-11 19:54:40 +01:00
Justin Clark-Casey (justincc)
337ea019bd If a part has a sit target and an avatar is already sitting, allow another avatar to sit in the position given if no sit target was set.
Previous behave was that the second avatar could not sit.
This matches behaviour observed on the LL grid.
2012-07-10 23:55:22 +01:00
Justin Clark-Casey (justincc)
cdea572d2e refactor: move management of SOP.SitTargetAvatar into SOP.AddSittingAvatar() and SOP.RemoveSittingAvatar() 2012-07-10 23:50:04 +01:00
Justin Clark-Casey (justincc)
11e0ad6dc8 Revert "refactor: Add SOP.IsSitTargetOccupied to improve readability"
This reverts commit c8f0d476d2.
On reconsideration, I think this is less readable since immediately following code still sets SitTargetAvatar directly
2012-07-10 23:39:05 +01:00
Justin Clark-Casey (justincc)
c8f0d476d2 refactor: Add SOP.IsSitTargetOccupied to improve readability 2012-07-10 23:34:40 +01:00
Justin Clark-Casey (justincc)
69a6f6e3cd refactor: use sit orientation argument passed in to SP.SendSitResponse() rather than creating a new copy
There are no issues with side-effects since this is a struct.
2012-07-10 23:26:40 +01:00
Justin Clark-Casey (justincc)
e8347b7095 Move common code to detect whether a part has a valid sit target into a SOP property rather than being repeated in SP.
This also makes the detection in SP.FindNextAvailableSitTarget() and SendSitResponse() identical.
Previously they varied slightly (SendSitResponse didn't check for an older type of invalid quaternion) but the practical effect is most probably zero.
2012-07-10 23:21:39 +01:00
Justin Clark-Casey (justincc)
506437b684 Remove log line accidentally left in SP.SendSitResponse() 2012-07-10 23:06:34 +01:00
Justin Clark-Casey (justincc)
9f01c3d408 Disable logging in regression test in OSSL_ApiAttachmentTests 2012-07-10 23:04:44 +01:00
Justin Clark-Casey (justincc)
58869e5aa0 Fix recent SOP.GetSittingAvatars() to return null if there are no sitting avatars rather than throwing an exception.
Extends sitting avatar regression tests to test new sitters information
2012-07-10 23:03:52 +01:00
Justin Clark-Casey (justincc)
f3134b5cf6 When an attachment is detached to inv or derezzed, stop the scripts, update the known item with script state still in the script engine and then remove the scripts.
This is to fix a regression starting from 5301648 where attachments had to start being deleted before persistence in order to avoid race conditions with hud update threads.
2012-07-10 22:41:11 +01:00
Justin Clark-Casey (justincc)
eb5ec4a786 If a script is being stopped manually, then give the scriptpool thread 1 second to finish normally before forcibly aborting.
This is to avoid the worst of the problems in mono 2.6, 2.10 where an aborted thread does not always release all its locks.
This very short grace period is identical to the existing behaviour when a script is removed from the scene.
2012-07-10 21:42:51 +01:00
Justin Clark-Casey (justincc)
c8af20f966 This script allows an object to be attached directly from prim inventory to another avatar in the scene.
Very useful in serious game/environment scenarios where its only allowed for trusted creators.
Threat level Severe
2012-07-09 23:08:41 +01:00
Justin Clark-Casey (justincc)
d6f563794e Don't allow a prim to be sat upon if its part of an attachment 2012-07-09 21:43:44 +01:00
Justin Clark-Casey (justincc)
2eaa6d5ace Do not allow a script to attach a prim if its being sat upon.
This prevents a stack overflow where a get position on the avatar will refer to the attachment which will in turn refer back to the avatar.
This required recording of all sitting avatars on a prim which is done separately from recording the sit target avatar.
Recording HashSet is null if there are no sitting avatars in order to save memory.
2012-07-09 21:24:32 +01:00
BlueWall
1a2ab7bc69 More keys for automated ini processing 2012-07-08 22:50:56 -04:00
BlueWall
a96ac73302 Add more keys for OpenSim.ini.defaults automation 2012-07-08 13:45:17 -04:00
BlueWall
57094bd017 Add more automation keys to OpenSim.ini.example 2012-07-08 13:03:37 -04:00
Justin Clark-Casey (justincc)
112cddc9ca minor: rearrange INITIALIZATION COMPLETE log message so that it's clear init is only complete for a particular region at a time 2012-07-07 00:53:17 +01:00
Justin Clark-Casey (justincc)
16d5b79d57 minor: remove some recent mono compiler warnings 2012-07-07 00:36:01 +01:00
Justin Clark-Casey (justincc)
1201307c73 Remove duplicate Warp3DImageModule entry in CoreModulePlugin.addin.xml
This was causing 2 copies of the module to be created for each scene.
Probably no bad consequences other than a small waste of memory (both for the module and for the warp3D renderer it loaded)
2012-07-07 00:26:25 +01:00
Justin Clark-Casey (justincc)
a85741ac37 minor: Make WORLD MAP category log lines consistent 2012-07-07 00:14:16 +01:00
Justin Clark-Casey (justincc)
3bd134474b minor: Get RegionReady module to shout initialization complete status to draw the eye 2012-07-07 00:09:33 +01:00
Justin Clark-Casey (justincc)
b19ead5f9e Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-07-07 00:05:16 +01:00
Justin Clark-Casey (justincc)
7ff4eec79c Remove redundant SetScene() function in Scene.AddSceneObject()
This is always done later on in SceneGraph.AddSceneObject() if the call hasn't failed due to sanity checks.
There's no other purpose for this method to exist and it's dangerous/pointless to call in other conditions.
2012-07-07 00:02:45 +01:00
Robert Adams
7aff238eee Merge branch 'bulletsim2'
Cleanup preceeding major work. No major functional changes.
Collisions reported to simulator more efficiently.
BulletSim binaries updated using a more recent version of Bullet (v2.80-r2527).
2012-07-06 15:59:09 -07:00
Robert Adams
af9d8de515 BulletSim: update the binaries to the current sources 2012-07-06 15:56:35 -07:00
Justin Clark-Casey (justincc)
f1f390cfdf Remove now duplicate interregion object check that should have been removed a few commits ago in 43a2da9 2012-07-06 23:22:40 +01:00
Justin Clark-Casey (justincc)
74014a3854 minor: Remove some wrong comments in attachments regression tests 2012-07-06 23:13:00 +01:00
Robert Adams
e4a6611865 Clean up collision reporting code so they are properly passed to
the simulator in batches.
More comments.
2012-07-06 15:09:19 -07:00
Justin Clark-Casey (justincc)
056c9a59b2 Add assert to attachment regression tests to check that number of objects in the scene graph 2012-07-06 23:07:50 +01:00
Talun
ae1f2114f5 Mantis 6077 trim NPC chat on channel zero.
This patch trims leading and trailing spaces from NPC chat and
suppresses the sending of empty chat strings on open chat channel 0.
2012-07-06 22:49:18 +01:00
Talun
1b1f841c6a Mantis 6063 osNpcTouch.
Allow NPCS to touch obects.
2012-07-06 22:37:19 +01:00
Justin Clark-Casey (justincc)
43a2da9edb Pull prim crossing/teleport checks up into Scene.IncomingCreateObject() from Scene.AddObject()
Only IncomingCreateObject() needs these checks.  General object adding does not need to perform crossing perm checks
2012-07-06 22:33:16 +01:00
Justin Clark-Casey (justincc)
f6e5791ecd refactor: extract method UpdateUserInventoryWithAttachment() from AttachObject() for better code comprehension 2012-07-06 22:07:19 +01:00
Justin Clark-Casey (justincc)
843112340e Log MONO_THREADS_PER_CPU value on simulator startup, or "unset" if it is not set 2012-07-06 00:37:45 +01:00
Justin Clark-Casey (justincc)
7e73f609e5 Log warning if time between invocations of the watchdog thread is twice the timer setting.
This is to help detect situations where thread timeout warnings are being generated because of general machine issues rather than deadlock, network or other problems.
2012-07-05 23:15:59 +01:00
Justin Clark-Casey (justincc)
db9616f7ba minor: add client name to various login service log messages to disambiguate messages from concurrent logins. Also adds destination resolution debug log message showing region endpoint.
Adding endpoint to the log helps to find issues where the region external host information has been wrongly configured
2012-07-05 21:30:20 +01:00
Justin Clark-Casey (justincc)
8674604ff5 regrade osFormatString, osMatchString and osReplaceString to VeryLow.
I can't see that these present any real hazard to sim functioning.
2012-07-05 21:10:59 +01:00
Justin Clark-Casey (justincc)
462f7bccf9 minor: Add more information to OSFunctionThreatLevel and clarify some text in using PARCEL_OWNER, PARCEL_GROUP_MEMBER, ESTATE_MANAGER, ESTATE_OWNER permission categories 2012-07-05 20:58:20 +01:00
SignpostMarv
510e809aba porting console commands from raw2sculpt 3.2 2012-07-05 00:16:31 +01:00
Justin Clark-Casey (justincc)
951b45b80f Add OSSL function osForceAttachToAvatarFromInventory()
This works like osForceAttachToAvatar() but allows an object to be directly specified from the script object's inventory rather than forcing it to be rezzed in the scene first.
Still only attaches objects to the owner of the script.
This allows one to bypass the complicated co-ordination of first rezzing objects in the scene before attaching them.
Threat level high.
2012-07-05 00:05:06 +01:00
Justin Clark-Casey (justincc)
7b327848d0 Use GetInventoryItem() in llRezAtRoot rather than iterating through a cloned dictionary 2012-07-04 22:21:47 +01:00
Justin Clark-Casey (justincc)
2f998fce1f refactor: In llGetNotecardLine() use existing GetInventoryItem() rather than inspecting a clone of the TaskInventory dictionary that was not cloned thread-safe 2012-07-04 22:00:39 +01:00
Justin Clark-Casey (justincc)
1816ecb747 refactor: In llGetNumberOfNotecardLines() use existing GetInventoryItem() rather than inspecting a clone of the TaskInventory dictionary that was not cloned thread-safe 2012-07-04 21:57:57 +01:00
Justin Clark-Casey (justincc)
eacba4fc0b refactor: use existing GetInventoryItem() in GetScriptByName(), itself renamed from ScriptByName() 2012-07-04 21:54:30 +01:00
Justin Clark-Casey (justincc)
9fac7fd932 refactor: In llGetInventoryType() use existing GetInventoryItem() 2012-07-04 21:50:52 +01:00
Justin Clark-Casey (justincc)
f2b0377c28 refactor: In llGetInventoryCreator() use existing GetInventoryItem() 2012-07-04 21:49:21 +01:00
Justin Clark-Casey (justincc)
d933bdbd59 refactor: In llGetInventoryPermMask() use existing GetInventoryItem() 2012-07-04 21:47:20 +01:00
Justin Clark-Casey (justincc)
f9fa34408d refactor: in llGetInventoryPermMask use existing GetInventoryItem() 2012-07-04 21:42:04 +01:00
Justin Clark-Casey (justincc)
857494f6bd refactor: In llRemoteLoadScriptPin() use existing GetInventoryItem() 2012-07-04 21:36:44 +01:00
Justin Clark-Casey (justincc)
dff7cae2ee refactor: replace use of LSL_Api.GetTaskInventoryItem() with existing GetInventoryItem() 2012-07-04 21:33:35 +01:00
Justin Clark-Casey (justincc)
0e3fce9b5c refactor: In llGetInventoryKey() use existing GetInventoryItem() 2012-07-04 21:25:58 +01:00
Justin Clark-Casey (justincc)
4b2b14dad1 In llMessageLinked() use GetInventoryItems() rather than cloning TaskInventory directory
GetInventoryItems() returns a new list and so is equivalent, and creates this list under lock whereas Clone() is not thread-safe
2012-07-04 21:22:43 +01:00
Justin Clark-Casey (justincc)
3769739ca7 In llRequestInventoryData() use GetInventoryItems() rather than cloning TaskInventory directory
GetInventoryItems() returns a new list and so is equivalent, and creates this list under lock whereas Clone() is not thread-safe
2012-07-04 21:19:16 +01:00
Justin Clark-Casey (justincc)
3717812ce0 refactor: In llCollisionSound() use existing GetInventoryItem() method rather than have it iterate through TaskInventory itself. 2012-07-04 21:15:00 +01:00
Justin Clark-Casey (justincc)
ae64d089c6 refactor: In llRemoveInventory() use existing GetInventoryItem() method rather than have it iterate through TaskInventory itself. 2012-07-04 21:05:51 +01:00
Justin Clark-Casey (justincc)
58b13d51a7 refactor: make llGiveInventory() use existing GetInventoryItem() method rather than iterate through TaskInventory itself. 2012-07-04 20:57:48 +01:00
Justin Clark-Casey (justincc)
5691a8b860 refactor: rename Watchdog.WATCHDOG_TIMEOUT_MS to DEFAULT_WATCHDOG_TIMEOUT_MS to reflect what it actually is 2012-07-04 00:15:03 +01:00
Justin Clark-Casey (justincc)
f7b4802577 Correct spelling mistake m_BanedViewers to m_BannedViewers 2012-07-03 23:26:02 +01:00
Justin Clark-Casey (justincc)
8183c2926d minor: Add some method doc to HasGroupChanged and Schedule GroupForFull/PartUpdate() to indicate when region modules need to invoke them 2012-07-03 23:19:11 +01:00
Justin Clark-Casey (justincc)
3c9b9a848f Fix issue in database tests where sogs being stored are not in a scene.
This puts an extra m_part.ParentGroup.Scene == null check at the top of SceneObjectPartInventory.QueryScriptStates()
2012-07-03 22:58:58 +01:00
Michelle Argus
3399596e0e Adds a list of viewers that are allowed or banned from the region.
Signed-off-by: Melanie <melanie@t-data.com>
2012-07-02 18:45:11 +01:00
Melanie
d32cf21576 Add preservation of running state of scripts when drag-copying. 2012-07-01 18:30:59 +01:00
Justin Clark-Casey (justincc)
1926de5a05 Remove some mono compiler warnings 2012-06-30 01:25:39 +01:00
Justin Clark-Casey (justincc)
a4551b027b Removing unused handling of incoming create object by userID and itemID only.
It appears this was never actually used since attachments were rezzed in other code.
This was never available on remote simulator comms, only local.
2012-06-30 01:14:49 +01:00
Justin Clark-Casey (justincc)
56c776066c Remove code listed for removal in 0.7.3 that handled script restart for incoming attachments from pre-fatpack regions (versions of OpenSimulator more than a year old) 2012-06-30 01:06:37 +01:00
Justin Clark-Casey (justincc)
0229e90dcc Move update of the final optional ODE total frame stat inside the OdeLock rather than outside to avoid a very occasional race condition with the stat collection thread 2012-06-29 01:02:35 +01:00
Justin Clark-Casey (justincc)
e420f815dc refactor: rename _collisionEventPrim to m_collisionEventActors and _collisionEventPrimChanges to m_collisionEventActorsChanges to reflect their actual contents.
These dictionaries handle all actor types, not just physical prims.
2012-06-29 00:54:40 +01:00
Justin Clark-Casey (justincc)
1a7be7b00e Fix a regression where we stopped removing avatars from collision event reporting on logout, rather than stopping clearing their collision events.
This occurred in b18c8c8 (Thu May 17 2012).
This was a cause of very occasional race conditions and likely memory leakage as clients came and went from the region.
2012-06-29 00:36:50 +01:00
Justin Clark-Casey (justincc)
0f6b7b6a41 If a link points to a non-existing item in FetchInventory caps, then don't try to add it to the return data rather than suffering an exception later on 2012-06-29 00:11:44 +01:00
Justin Clark-Casey (justincc)
f202c36106 Add IScene.Name for code clarity to replace the RegionInfo.RegionName used in many, many log messages. 2012-06-29 00:03:22 +01:00
Justin Clark-Casey (justincc)
bfa6896678 Change AttachmentsModule.DetachSingleAttachmentToInv() to accept a SOG directly instead of an item ID to then shuffle through attachments, saving CPU busywork.
Almost all callers already had the sog to hand.
Still checking that it's really an attachment, but now by inspecting SOG.AttachedAvatar
2012-06-28 23:31:23 +01:00
Justin Clark-Casey (justincc)
571fd966cb Rather than iterating through all SOGs in the scene looking for the one that matches out fromItemID on detach, go through the agent's attachment sog list instead. 2012-06-28 23:01:12 +01:00
Justin Clark-Casey (justincc)
f263d6a910 Remove code that tried to delete an attachment back to inventory if RezSingleAttachmentFromInventoryInternal() returned null.
null would only ever be returned if the item couldn't be located within inventory and this would happen immediately.
In this case, derezzing wouldn't work anyway since there is no item to derez.
2012-06-28 22:48:49 +01:00
Justin Clark-Casey (justincc)
972b0b52f9 If rest of first line after colon is blank then still warn about running in XEngine if engine specified does not exist.
This is to take account of situations where the user was intending to specify a script engine using colon using its default language.
This probably generates few false positive as scripts are less likely to end a first line colon with a comment for other purposes.
2012-06-28 21:30:36 +01:00
Justin Clark-Casey (justincc)
25baa2d894 Avoid reporting false positives when a colon is in a comment in the first line of a script where the user was not trying to select a different script engine.
This works by only posting the "Selected engine unavailable" message if we're falling back on XEngine and the language is one handled by XEngine.
In cases where the language is not handled or not allowed, the user will still be notified by the later compiler error.
This avoids the overwhelming majority of false positives where the first line contains a : for other reasons (e.g. source control systems, vim settings, etc.)
Ultimately, I think it would be better to detect script language/engine with a mechanism that didn't just rely on : detection (e.g like #! in unix scripts).
2012-06-28 01:01:18 +01:00
Justin Clark-Casey (justincc)
f9769a9fcb minor: reuse colon index calculation in XEngine.OnRezScript. The index if a colon is found on the first line will always be the same as for the whole script. 2012-06-28 00:37:23 +01:00
Justin Clark-Casey (justincc)
bb48060b44 Fix issue in InventoryArchiveTestCase where it didn't call down to OpenSimTestCase.SetUp() 2012-06-27 00:50:36 +01:00
Justin Clark-Casey (justincc)
d043213317 refactor: Move ScenePresence <-> AgentData attachments copying code into AttachmentsModule. 2012-06-27 00:41:46 +01:00
Justin Clark-Casey (justincc)
5bec5bcf71 Automatically disable log4net before each regression test so that logging is confined to a single test if it's turned on.
This involves making test classes inherit from a common OpenSimTestCase.
This will be applied to more classes as required.
2012-06-27 00:01:51 +01:00
Justin Clark-Casey (justincc)
87ca820f9b Replace "kill uuid" console command with the more consistent "delete object uuid", which was present in the last opensim release. 2012-06-26 23:28:48 +01:00
Justin Clark-Casey (justincc)
0b29877790 Fix output for help on some object region console commands 2012-06-26 23:15:15 +01:00
Justin Clark-Casey (justincc)
97437feb06 Show region positions in "show regions" robust console command 2012-06-26 23:05:10 +01:00
Justin Clark-Casey (justincc)
2524517986 minor: correct GridService "show regions" cibsike cinnabd usage statement 2012-06-26 22:54:41 +01:00
Justin Clark-Casey (justincc)
99954c1498 refactor: Remove unnecessary AttachmentModuleTests.m_userId in favour of local variables 2012-06-26 22:53:08 +01:00
Justin Clark-Casey (justincc)
2b82c421ad refactor: Use local attachment module variables instead of global m_attMod.
This also avoids confusion between tests where one sets up m_attMod and another accidentally uses it after failing to set one up itself.
2012-06-26 22:31:25 +01:00
Justin Clark-Casey (justincc)
4329cc7b8a refactor: make m_presence a local variable in all AttachmentsModuleTests since it doesn't need to be global and some tests set up more than one sp 2012-06-26 22:21:54 +01:00
Justin Clark-Casey (justincc)
32a4ce94f0 Add regression test to check that attachments in source region are deleting when an agent teleports to a neighbouring region 2012-06-26 22:16:44 +01:00
Justin Clark-Casey (justincc)
340005c5bf Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-06-26 22:12:39 +01:00
Justin Clark-Casey (justincc)
4b6c3fd4bb If crossing attachments into another region pre-fatpack, clone objects before changing properties to avoid hud display race condition with update threads.
This matches behaviour in fatpack crossing, where attachments are cloned before their properties are changed.
This only applies to crossings to simulators running code released before April 2011.
2012-06-26 21:06:47 +01:00
BlueWall
988112d446 Add stub for llCastRay 2012-06-26 15:15:25 -04:00
Justin Clark-Casey (justincc)
1f22b29ca3 Add much easier ConsoleDisplayTable AddColumn() and AddRow() methods.
Use these for new "show regions" command rather than old cumbersome stuff.
2012-06-26 00:40:46 +01:00
Justin Clark-Casey (justincc)
5292b8b8be Add "show regions" console command to ROBUST to show all regions currently registered.
Command is not added in standalone, which has its own version of "show regions" that can also show estate name
2012-06-26 00:34:37 +01:00
Justin Clark-Casey (justincc)
854f2a913c Add "show region at" command to grid service to get the details of a region at a specific location. "show region" command becomes "show region name" to disambiguate
This is the same format as used by "show object name", etc.
"deregister region" also becomes "deregister region id"
2012-06-25 23:55:14 +01:00
Justin Clark-Casey (justincc)
f5316984ab minor: update currently commented out log message at top of AvatarFactoryModule.SetAppearance() for future use 2012-06-25 23:31:22 +01:00
Justin Clark-Casey (justincc)
e5b739aaeb When attachments are being saved and deleted for a closing root agent, delete first to avoid a hud race condition with update threads.
If delete doesn't occur first then the update thread can outrace the IsAttachment = false necessary to save attachments and send hud artifacts to other viewers.
2012-06-25 22:48:13 +01:00
Justin Clark-Casey (justincc)
5301648cff In AttachmentsModule.DetachSingleAttachmentToInvInternal(), remove attachment before changing properties for correct inventory serialization.
Serialization of attachments requires IsAttachment = false so that correct positions are serialized instead of avatar position.
However, doing this when a hud is still attached allows race conditions with update threads, resulting in hud artifacts on other viewers.
This change sets SOG.IsDeleted before serialization changes take place (IsDeleted itself is not a serialized property).
LLClientView then screens out any deleted SOGs before sending updates to viewers.
2012-06-25 21:08:19 +01:00
BlueWall
6d3ee8bb39 Fix script "Running" behavior
Unchecking "Running" box in script editor now persists. This fixes http://opensimulator.org/mantis/view.php?id=6057
2012-06-23 04:15:14 -04:00
Justin Clark-Casey (justincc)
78143769bf Resolve various race conditions between accessing and removing external script URLs by more consistently locking on m_UrlMap 2012-06-22 23:49:52 +01:00
Justin Clark-Casey (justincc)
dca04c7b61 Avoid a race condition where an incoming request to a script external URL can trigger an exception is the URL was being removed at the same time.
This involves three steps
1) Return gracefully in UrlModule.HttpRequestHandler() instead of throwing an exception when the url cannot be found in its index
2) Return true instead of false in HasEvents() if no matching request is found in the map.  This call will only happen in the first place for raced requests.
3) Return a 404 in GetEvents() if the request is not in the index, rather than a blank 200 OK.

Many thanks to Tom Haines in http://opensimulator.org/mantis/view.php?id=6051 for doing some of the work on this.
2012-06-22 23:16:18 +01:00
Justin Clark-Casey (justincc)
80a41e670d Avoid race condition between m_PrimObjects iteration in XEngine.PostObjectEvent and places where the list is modified by extending the m_PrimObjects lock. 2012-06-22 02:23:25 +01:00
Justin Clark-Casey (justincc)
9f3feeff8d If starting scripts on initial sim start, provide INFO level log feedback each time 50 scripts have been started.
This is to provide an indication of what's happening now that the default isn't to report every single script start.
Changes XEngine logging level in OpenSim.exe.config from WARN to INFO.
2012-06-22 02:10:27 +01:00
Justin Clark-Casey (justincc)
f907182ab2 Eliminate unnecessary extra call to TriggerEmptyScriptCompileQueue in XEngine.DoOnRezScriptQueue()
The later invocation of this function will happen on an empty compile queue.
2012-06-22 01:57:14 +01:00
Justin Clark-Casey (justincc)
4cf49369b5 Stop flicking IsAttachment false and then true in AttachmentsModule.UpdateAttachmentPosition() in order to avoid a hud update race condition.
Previously, setting IsAttachment to false then true was necessary to serialize the updated attachment object information.
However, UpdateAttachmentPosition no longer does this update.
Whilst IsAttachment is set to false there is a race condition where the update thread can wrongly send hud object updates to clients that do not own the hud, resulting in screen artifacts.
2012-06-22 01:43:26 +01:00
Justin Clark-Casey (justincc)
fda39c11bf Fix bug where attachments would not retain position if just rotated and not moved.
This was because we were not setting AttachedPos in SOG.UpdateGroupPositionPR, unlike UpdateGroupPosition
2012-06-22 01:33:27 +01:00
Justin Clark-Casey (justincc)
798846c5b6 refactor AttachmentsModule tests to use a common method for standard attachment item setup 2012-06-22 00:40:04 +01:00
Justin Clark-Casey (justincc)
06617ffd06 Add regression test for updating attachment position 2012-06-22 00:18:30 +01:00
Justin Clark-Casey (justincc)
d24122b706 Add item id, name, prim name and id to log message when state exists but loading fails.
Drop logging about memory limit exceeded to warn from error
2012-06-21 02:24:44 +01:00
Justin Clark-Casey (justincc)
afcabf5244 Retrigger build - last jenkins run was glitched 2012-06-21 02:13:03 +01:00
Justin Clark-Casey (justincc)
5709bed548 Add state file location to errors logged when there's some issue with retrieving state (e.g. exceeds memory limit) 2012-06-21 02:09:14 +01:00
Justin Clark-Casey (justincc)
68ea096f1b Use HasPrivateAttachmentPoint properties in SOG.DeleteGroupFromScene() instead of magic numbers 2012-06-20 23:25:07 +01:00
Justin Clark-Casey (justincc)
714db90832 refactor: use SOG.HasPrivateAttachmentPoint in SOP.SendTerseUpdateToClient() instead of attachmentpoint magic numbers. 2012-06-20 22:46:01 +01:00
Justin Clark-Casey (justincc)
b23425c7c4 As with LLSDInventoryItem from commit 01a2b0b, send type values in LLSDInventoryFolder for inventory CAPs as integers rather than strings.
Should also resolve some issues with exceptions being thrown in some inventory fetches.
2012-06-20 02:28:00 +01:00
Justin Clark-Casey (justincc)
9ec9dafae6 Lower warn logging on not having friends/group module on permissions to debug.
It's a valid configuration not to have these modules, but I think it's still worth logging the fact that certain permissions won't work (always return true)
2012-06-20 01:33:25 +01:00
Justin Clark-Casey (justincc)
6c312bce7f minor: Lower flotsam asset cache warning about not having a FlotsamCache.ini to debug
It's perfectly okay not to have this section.
2012-06-20 01:30:20 +01:00
Justin Clark-Casey (justincc)
7b6c0232a5 Change default logging level for XEngine to WARN instead of DEBUG.
This is to reduce log spam from script loading, which is especially spammy for avatar movements with scripted attachments.
All important messages are at warn or above.
If you still want/need to see these messages, set <level value="DEBUG"/> in the <logger name="OpenSim.Region.ScriptEngine.XEngine"> section of OpenSim.exe.config.
This affects no other package logs, which still output at the root configured level (currently DEBUG by default).
2012-06-20 01:10:18 +01:00
Justin Clark-Casey (justincc)
4cfaa01c0a Remove STARTUP COMPLETE message from the startuplogo.txt file and into main logging 2012-06-20 01:06:55 +01:00
Justin Clark-Casey (justincc)
6b3f9fcde0 Comment out the neighbour and land in connectors from info logging that they are starting up 2012-06-20 00:42:54 +01:00
Justin Clark-Casey (justincc)
625e5e913a Comment out recently added log message detailing number of scripts started when compile queue empties for now 2012-06-20 00:25:18 +01:00
Justin Clark-Casey (justincc)
881e92a726 Raise some IO associated Exception logging in XEngine to error level, in line with other similar cases.
Remove more unnecessary Close() calls - these are being triggered by the Dispose() called when exiting the using statement for these sdk io objects.
2012-06-20 00:19:50 +01:00
Justin Clark-Casey (justincc)
0fa303b1cf Log how many scripts are candidates for starting and how many are actually started.
Adds DebugLevel infrastructure to XEngine though currently commented out and unused.
2012-06-20 00:10:19 +01:00
Justin Clark-Casey (justincc)
9737e6d52e If RegionReady is active, don't falsely say that logins are enabled in the main scene loop before RegionReady is signalled when initial script compilation finishes.
Also raises this logging level to Info from Debug since this information is of high importance.  This matches the behaviour of the RegionReady module
2012-06-20 00:07:03 +01:00
Justin Clark-Casey (justincc)
e23d7ff9c0 minor: If logging because mesh/sculpt data isn't present for an object, log object UUID rather than local id, since UUID doesn't potentially vary between simulator starts. 2012-06-20 00:05:48 +01:00
Justin Clark-Casey (justincc)
ef686ead37 Like the assembly and text files, only write the c#-lsl linemap in XEngine.SetXMLState() if the trust binaries flag is set.
This doesn't affect other locations where the map is written, such as on script compilation.
2012-06-19 02:11:46 +01:00
Justin Clark-Casey (justincc)
bc06f3dcaf Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-06-19 01:55:31 +01:00
Justin Clark-Casey (justincc)
8e7032ece8 minor: Add a little more detail to IOException logging in XEngine.SetXMLState()
Also removes superflous Close() commands for statements taking place within using() constructs
Also adds some comment out debug log messages for future use.
2012-06-19 01:53:50 +01:00
BlueWall
5c5b359bcb Oops! putting back the entry for map urls 2012-06-16 07:26:16 -04:00
BlueWall
fc1522ab60 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-06-16 06:29:49 -04:00
BlueWall
2ed768cbf5 Adjust Robust*.ini.examples V3 webprofile entries 2012-06-16 06:29:15 -04:00
Justin Clark-Casey (justincc)
7119de56ff Change read config paramter from max_urls_per_simulator to max_external_urls_per_simulator, which is what it was meant to be 2012-06-16 04:12:53 +01:00
Justin Clark-Casey (justincc)
ed513fc7be Fix bug introduced in commit c6e3752 (13 Jun 2012) where poll responses would always return OK even if some other status code had been set 2012-06-16 03:43:45 +01:00
Justin Clark-Casey (justincc)
22f25dfcab Implement max_external_urls_per_simulator setting in [LL-Functions] to allow configuration of how many urls can be set up by llRequestURL()
Defaults remains as 100.
This setting is per simulator instead of per region due to how the url script module is structured.
2012-06-16 03:32:47 +01:00
Justin Clark-Casey (justincc)
aaa30dcebc Add region name to UseCircuitCode log messages 2012-06-15 05:01:36 +01:00
Justin Clark-Casey (justincc)
c935f03467 Put all debug console commands into a single Debug section rather than scattering them over other categories 2012-06-15 03:32:43 +01:00
Justin Clark-Casey (justincc)
94517c8d5c Make the "debug http" command available for robust as well as the simulator. This allows one to see incoming requests as they happen.
This required making everything use the common MainServer class for registering and retrieving http servers, rather than duplicate structures.
2012-06-15 02:51:52 +01:00
Justin Clark-Casey (justincc)
257b1b517d Add main instance to internal MainServer.m_Servers list to simplify internal logic.
This does require the server to be added before it is set as the main Instance
2012-06-15 02:03:50 +01:00
Justin Clark-Casey (justincc)
aeed4d3041 minor: Tell user the current debug http level if "debug http" console command is executed without a level parameter 2012-06-15 01:27:29 +01:00
Justin Clark-Casey (justincc)
478acfff34 When setting debug http level, do this for all known http servers, not just the main instance. 2012-06-15 01:24:36 +01:00
Justin Clark-Casey (justincc)
10e87f9cdc Make XMLRPCModule use an existing HTTP server if one already exists on the desired port. 2012-06-15 00:59:53 +01:00
Justin Clark-Casey (justincc)
6993a26ba5 Get rid of some unnecessary null checks in RegionApplicationBase.StartupSpecific() - a constructor can never return null.
Also adds some method doc to MainServer
2012-06-15 00:40:12 +01:00
Justin Clark-Casey (justincc)
93ba0332c4 minor: Extend 'debug http' usage statement to 0..3 from 0..2 2012-06-14 23:54:12 +01:00
Justin Clark-Casey (justincc)
9825861f4a Shuffle "debug http" levels so that 1 and 2 now cause different levels of warn to be logged if we receive invalid xml for xmlrpc. 2012-06-14 23:46:09 +01:00
Justin Clark-Casey (justincc)
f4b02f8e39 Fix a regression in BaseHttpServer.HandleXmlRpcRequests() from recent c6e3752
Accidentally make responseString null by default instead of String.Empty.
It needs to be something in case the XmlRpcRequest deserialize throws an exception due to bad xml (a failure which we silently swallow!)
2012-06-14 04:29:15 +01:00
Justin Clark-Casey (justincc)
2c6555021f Fix very recent regression in 917d753 where I put the ++updatesThisCall outside the batching part of ProcessEntityUpdates()
This stopped any batching happening and since this method is called periodically updates were sent very slowly
2012-06-14 03:49:54 +01:00
Justin Clark-Casey (justincc)
3888b9a670 If we're going to discard a terse update block because it's now someone else's hud, then don't still add it to the list of blocks for the update message. 2012-06-14 03:32:44 +01:00
Justin Clark-Casey (justincc)
1aa7469253 correct wrong incomplete comment from previous commit 3c3ea19 in AttachmentsModule 2012-06-14 02:30:40 +01:00
Justin Clark-Casey (justincc)
3c3ea19620 Fix a bug where scene objects attached as HUDs through scripts would not disappear for other avatars.
We do this by sending a kill message for that object to all other avatars apart from the one that has the hud.
2012-06-14 02:26:38 +01:00
272 changed files with 12196 additions and 5116 deletions

7
.gitignore vendored
View File

@@ -26,9 +26,14 @@
bin/Debug/*.dll
bin/*.dll.mdb
bin/*.db
bin/*.db-journal
bin/addin-db-*
bin/*.dll
bin/OpenSim.vshost.exe.config
bin/OpenSim.32BitLaunch.vshost.exe.config
bin/OpenSim.32BitLaunch.log
UpgradeLog.XML
_UpgradeReport_Files/
bin/ScriptEngines/*-*-*-*-*
bin/ScriptEngines/*.dll
bin/ScriptEngines/*/*.dll
@@ -41,6 +46,8 @@ bin/Physics*
bin/Terrain*
bin/Regions/*
bin/UserAssets
bin/assetcache
bin/maptiles
bin/estate_settings.xml
bin/config-include/CenomeCache.ini
bin/config-include/FlotsamCache.ini

View File

@@ -135,14 +135,25 @@
<delete dir="%temp%"/>
</target>
<target name="torture" depends="build, find-nunit">
<target name="test-stress" depends="build, find-nunit">
<setenv name="MONO_THREADS_PER_CPU" value="100" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.torture">
<arg value="./bin/OpenSim.Tests.Torture.dll" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.stress">
<arg value="./bin/OpenSim.Tests.Stress.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.torture)==0}" />
<fail message="Failures reported in stress tests." unless="${int::parse(testresult.opensim.tests.stress)==0}" />
<delete dir="%temp%"/>
</target>
<target name="test-perf" depends="build, find-nunit">
<setenv name="MONO_THREADS_PER_CPU" value="100" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.performance">
<arg value="./bin/OpenSim.Tests.Performance.dll" />
</exec>
<fail message="Failures reported in performance tests." unless="${int::parse(testresult.opensim.tests.performance)==0}" />
<delete dir="%temp%"/>
</target>

View File

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

View File

@@ -301,7 +301,8 @@ namespace OpenSim.Capabilities.Handlers
InventoryItemBase linkedItem
= m_InventoryService.GetItem(new InventoryItemBase(link.AssetID));
itemsToReturn.Insert(0, linkedItem);
if (linkedItem != null)
itemsToReturn.Insert(0, linkedItem);
}
}
}
@@ -393,12 +394,8 @@ namespace OpenSim.Capabilities.Handlers
llsdFolder.folder_id = invFolder.ID;
llsdFolder.parent_id = invFolder.ParentID;
llsdFolder.name = invFolder.Name;
if (invFolder.Type == (short)AssetType.Unknown || !Enum.IsDefined(typeof(AssetType), (sbyte)invFolder.Type))
llsdFolder.type = "-1";
else
llsdFolder.type = Utils.AssetTypeToString((AssetType)invFolder.Type);
llsdFolder.preferred_type = "-1";
llsdFolder.type = invFolder.Type;
llsdFolder.preferred_type = -1;
return llsdFolder;
}

View File

@@ -35,7 +35,7 @@ namespace OpenSim.Framework.Capabilities
public UUID folder_id;
public UUID parent_id;
public string name;
public string type;
public string preferred_type;
public int type;
public int preferred_type;
}
}

View File

@@ -66,9 +66,7 @@ namespace OpenSim.Framework.Capabilities
TResponse response = m_method(llsdRequest);
Encoding encoding = new UTF8Encoding(false);
return encoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response));
return Util.UTF8NoBomEncoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response));
}
}
}

View File

@@ -50,7 +50,7 @@ namespace OpenSim.ConsoleClient
request.ContentType = "application/x-www-form-urlencoded";
byte[] buffer = new System.Text.ASCIIEncoding().GetBytes(data);
byte[] buffer = Encoding.ASCII.GetBytes(data);
int length = (int) buffer.Length;
request.ContentLength = length;

View File

@@ -40,6 +40,11 @@ namespace OpenSim.Data
public UUID folderID;
public UUID agentID;
public UUID parentFolderID;
public XInventoryFolder Clone()
{
return (XInventoryFolder)MemberwiseClone();
}
}
public class XInventoryItem
@@ -64,6 +69,11 @@ namespace OpenSim.Data
public UUID avatarID;
public UUID parentFolderID;
public int inventoryGroupPermissions;
public XInventoryItem Clone()
{
return (XInventoryItem)MemberwiseClone();
}
}
public interface IXInventoryData

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

@@ -719,95 +719,99 @@ namespace OpenSim.Data.MySQL
RegionLightShareData nWP = new RegionLightShareData();
nWP.OnSave += StoreRegionWindlightSettings;
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
lock (m_dbLock)
{
dbcon.Open();
string command = "select * from `regionwindlight` where region_id = ?regionID";
using (MySqlCommand cmd = new MySqlCommand(command))
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
cmd.Connection = dbcon;
cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
IDataReader result = ExecuteReader(cmd);
if (!result.Read())
dbcon.Open();
string command = "select * from `regionwindlight` where region_id = ?regionID";
using (MySqlCommand cmd = new MySqlCommand(command))
{
//No result, so store our default windlight profile and return it
nWP.regionID = regionUUID;
StoreRegionWindlightSettings(nWP);
return nWP;
}
else
{
nWP.regionID = DBGuid.FromDB(result["region_id"]);
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
nWP.valid = true;
cmd.Connection = dbcon;
cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
IDataReader result = ExecuteReader(cmd);
if (!result.Read())
{
//No result, so store our default windlight profile and return it
nWP.regionID = regionUUID;
StoreRegionWindlightSettings(nWP);
return nWP;
}
else
{
nWP.regionID = DBGuid.FromDB(result["region_id"]);
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
nWP.valid = true;
}
}
}
}
return nWP;
}
@@ -853,118 +857,124 @@ namespace OpenSim.Data.MySQL
public void StoreRegionWindlightSettings(RegionLightShareData wl)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
lock (m_dbLock)
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, ";
cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, ";
cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, ";
cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, ";
cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, ";
cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, ";
cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, ";
cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, ";
cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, ";
cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, ";
cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, ";
cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, ";
cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, ";
cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, ";
cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, ";
cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, ";
cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, ";
cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, ";
cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, ";
cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, ";
cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, ";
cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, ";
cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, ";
cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, ";
cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)";
cmd.Parameters.AddWithValue("region_id", wl.regionID);
cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
ExecuteNonQuery(cmd);
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, ";
cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, ";
cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, ";
cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, ";
cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, ";
cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, ";
cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, ";
cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, ";
cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, ";
cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, ";
cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, ";
cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, ";
cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, ";
cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, ";
cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, ";
cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, ";
cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, ";
cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, ";
cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, ";
cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, ";
cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, ";
cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, ";
cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, ";
cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, ";
cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)";
cmd.Parameters.AddWithValue("region_id", wl.regionID);
cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
ExecuteNonQuery(cmd);
}
}
}
}
public void RemoveRegionWindlightSettings(UUID regionID)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
lock (m_dbLock)
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID";
cmd.Parameters.AddWithValue("?regionID", regionID.ToString());
ExecuteNonQuery(cmd);
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID";
cmd.Parameters.AddWithValue("?regionID", regionID.ToString());
ExecuteNonQuery(cmd);
}
}
}
}
@@ -972,26 +982,29 @@ namespace OpenSim.Data.MySQL
#region RegionEnvironmentSettings
public string LoadRegionEnvironmentSettings(UUID regionUUID)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
lock (m_dbLock)
{
dbcon.Open();
string command = "select * from `regionenvironment` where region_id = ?region_id";
using (MySqlCommand cmd = new MySqlCommand(command))
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
cmd.Connection = dbcon;
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
IDataReader result = ExecuteReader(cmd);
if (!result.Read())
dbcon.Open();
string command = "select * from `regionenvironment` where region_id = ?region_id";
using (MySqlCommand cmd = new MySqlCommand(command))
{
return String.Empty;
}
else
{
return Convert.ToString(result["llsd_settings"]);
cmd.Connection = dbcon;
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
IDataReader result = ExecuteReader(cmd);
if (!result.Read())
{
return String.Empty;
}
else
{
return Convert.ToString(result["llsd_settings"]);
}
}
}
}
@@ -999,33 +1012,39 @@ namespace OpenSim.Data.MySQL
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
lock (m_dbLock)
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)";
cmd.Parameters.AddWithValue("region_id", regionUUID);
cmd.Parameters.AddWithValue("llsd_settings", settings);
ExecuteNonQuery(cmd);
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)";
cmd.Parameters.AddWithValue("region_id", regionUUID);
cmd.Parameters.AddWithValue("llsd_settings", settings);
ExecuteNonQuery(cmd);
}
}
}
}
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
lock (m_dbLock)
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id";
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
ExecuteNonQuery(cmd);
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id";
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
ExecuteNonQuery(cmd);
}
}
}
}
@@ -1966,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

@@ -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

@@ -2890,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

@@ -1069,8 +1069,6 @@ namespace OpenSim.Data.Tests
regionInfo.RegionLocX = 0;
regionInfo.RegionLocY = 0;
Scene scene = new Scene(regionInfo);
SceneObjectPart sop = new SceneObjectPart();
sop.Name = name;
sop.Description = name;
@@ -1081,7 +1079,7 @@ namespace OpenSim.Data.Tests
sop.Shape = PrimitiveBaseShape.Default;
SceneObjectGroup sog = new SceneObjectGroup(sop);
sog.SetScene(scene);
// sog.SetScene(scene);
return sog;
}

View File

@@ -98,6 +98,11 @@ namespace OpenSim.Framework
/// </summary>
public string lastname;
/// <summary>
/// Agent's full name.
/// </summary>
public string Name { get { return string.Format("{0} {1}", firstname, lastname); } }
/// <summary>
/// Random Unique GUID for this session. Client gets this at login and it's
/// only supposed to be disclosed over secure channels

View File

@@ -199,7 +199,14 @@ namespace OpenSim.Framework
//
public class Cache
{
/// <summary>
/// Must only be accessed under lock.
/// </summary>
private List<CacheItemBase> m_Index = new List<CacheItemBase>();
/// <summary>
/// Must only be accessed under m_Index lock.
/// </summary>
private Dictionary<string, CacheItemBase> m_Lookup =
new Dictionary<string, CacheItemBase>();
@@ -320,19 +327,19 @@ namespace OpenSim.Framework
{
if (m_Lookup.ContainsKey(index))
item = m_Lookup[index];
}
if (item == null)
{
if (item == null)
{
Expire(true);
return null;
}
item.hits++;
item.lastUsed = DateTime.Now;
Expire(true);
return null;
}
item.hits++;
item.lastUsed = DateTime.Now;
Expire(true);
return item;
}
@@ -385,7 +392,10 @@ namespace OpenSim.Framework
//
public Object Find(Predicate<CacheItemBase> d)
{
CacheItemBase item = m_Index.Find(d);
CacheItemBase item;
lock (m_Index)
item = m_Index.Find(d);
if (item == null)
return null;
@@ -419,12 +429,12 @@ namespace OpenSim.Framework
public virtual void Store(string index, Object data, Type container,
Object[] parameters)
{
Expire(false);
CacheItemBase item;
lock (m_Index)
{
Expire(false);
if (m_Index.Contains(new CacheItemBase(index)))
{
if ((m_Flags & CacheFlags.AllowUpdate) != 0)
@@ -450,9 +460,17 @@ namespace OpenSim.Framework
m_Index.Add(item);
m_Lookup[index] = item;
}
item.Store(data);
}
/// <summary>
/// Expire items as appropriate.
/// </summary>
/// <remarks>
/// Callers must lock m_Index.
/// </remarks>
/// <param name='getting'></param>
protected virtual void Expire(bool getting)
{
if (getting && (m_Strategy == CacheStrategy.Aggressive))
@@ -475,12 +493,10 @@ namespace OpenSim.Framework
switch (m_Strategy)
{
case CacheStrategy.Aggressive:
if (Count < Size)
return;
case CacheStrategy.Aggressive:
if (Count < Size)
return;
lock (m_Index)
{
m_Index.Sort(new SortLRU());
m_Index.Reverse();
@@ -490,7 +506,7 @@ namespace OpenSim.Framework
ExpireDelegate doExpire = OnExpire;
if (doExpire != null)
if (doExpire != null)
{
List<CacheItemBase> candidates =
m_Index.GetRange(target, Count - target);
@@ -513,27 +529,34 @@ namespace OpenSim.Framework
foreach (CacheItemBase item in m_Index)
m_Lookup[item.uuid] = item;
}
}
break;
default:
break;
break;
default:
break;
}
}
public void Invalidate(string uuid)
{
if (!m_Lookup.ContainsKey(uuid))
return;
lock (m_Index)
{
if (!m_Lookup.ContainsKey(uuid))
return;
CacheItemBase item = m_Lookup[uuid];
m_Lookup.Remove(uuid);
m_Index.Remove(item);
CacheItemBase item = m_Lookup[uuid];
m_Lookup.Remove(uuid);
m_Index.Remove(item);
}
}
public void Clear()
{
m_Index.Clear();
m_Lookup.Clear();
lock (m_Index)
{
m_Index.Clear();
m_Lookup.Clear();
}
}
}
}
}

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

@@ -79,6 +79,16 @@ namespace OpenSim.Framework.Console
return sb.ToString();
}
public void AddColumn(string name, int width)
{
Columns.Add(new ConsoleDisplayTableColumn(name, width));
}
public void AddRow(params string[] cells)
{
Rows.Add(new ConsoleDisplayTableRow(cells));
}
public void AddToStringBuilder(StringBuilder sb)
{
string formatString = GetFormatString();
@@ -135,5 +145,10 @@ namespace OpenSim.Framework.Console
{
Cells = cells;
}
public ConsoleDisplayTableRow(params string[] cells) : this()
{
Cells = new List<string>(cells);
}
}
}

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

@@ -1033,7 +1033,21 @@ namespace OpenSim.Framework
void InPacket(object NewPack);
void ProcessInPacket(Packet NewPack);
/// <summary>
/// Close this client
/// </summary>
void Close();
/// <summary>
/// Close this client
/// </summary>
/// <param name='force'>
/// If true, attempts the close without checking active status. You do not want to try this except as a last
/// ditch attempt where Active == false but the ScenePresence still exists.
/// </param>
void Close(bool force);
void Kick(string message);
/// <summary>
@@ -1353,7 +1367,6 @@ namespace OpenSim.Framework
void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message);
void SendLogoutPacket();
EndPoint GetClientEP();
// WARNING WARNING WARNING
//

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

@@ -56,11 +56,29 @@ namespace OpenSim.Framework
public interface IScene
{
/// <summary>
/// The name of this scene.
/// </summary>
string Name { get; }
RegionInfo RegionInfo { get; }
RegionStatus RegionStatus { get; set; }
IConfigSource Config { get; }
/// <summary>
/// Are logins enabled on this simulator?
/// </summary>
bool LoginsEnabled { get; set; }
/// <summary>
/// Is this region ready for use?
/// </summary>
/// <remarks>
/// This does not mean that logins are enabled, merely that they can be.
/// </remarks>
bool Ready { get; set; }
float TimeDilation { get; }
bool AllowScriptCrossings { get; }

View File

@@ -73,33 +73,27 @@ namespace OpenSim.Framework
{
}
public InventoryFolderBase(UUID id)
public InventoryFolderBase(UUID id) : this()
{
ID = id;
}
public InventoryFolderBase(UUID id, UUID owner)
public InventoryFolderBase(UUID id, UUID owner) : this(id)
{
ID = id;
Owner = owner;
}
public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent)
public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent) : this(id, owner)
{
ID = id;
Name = name;
Owner = owner;
ParentID = parent;
}
public InventoryFolderBase(UUID id, string name, UUID owner, short type, UUID parent, ushort version)
public InventoryFolderBase(
UUID id, string name, UUID owner, short type, UUID parent, ushort version) : this(id, name, owner, parent)
{
ID = id;
Name = name;
Owner = owner;
Type = type;
ParentID = parent;
Version = version;
}
}
}
}

View File

@@ -99,8 +99,13 @@ namespace OpenSim.Framework
}
else
{
item = oldHeadNext.Item;
item = oldHeadNext.Item;
haveAdvancedHead = CAS(ref head, oldHead, oldHeadNext);
if (haveAdvancedHead)
{
oldHeadNext.Item = default(T);
oldHead.Next = null;
}
}
}
}
@@ -111,6 +116,10 @@ namespace OpenSim.Framework
public void Clear()
{
// ugly
T item;
while(count > 0)
Dequeue(out item);
Init();
}

View File

@@ -63,12 +63,15 @@ namespace OpenSim.Framework
internal void Clear()
{
this.value = default(T);
if (this.handle != null)
{
this.handle.Clear();
this.handle = null;
}
ClearRef();
}
internal void ClearRef()
{
this.value = default(T);
this.handle = null;
}
}
@@ -285,6 +288,7 @@ namespace OpenSim.Framework
if (--this.size > 0 && index != this.size)
{
Set(this.items[this.size], index);
this.items[this.size].ClearRef();
if (!BubbleUp(index))
BubbleDown(index);
}

View File

@@ -28,7 +28,7 @@
using System;
using System.Timers;
namespace OpenSim.Framework.Statistics
namespace OpenSim.Framework.Monitoring
{
/// <summary>
/// Asset service statistics collection

View File

@@ -31,8 +31,7 @@ using System.Text;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Framework.Statistics
namespace OpenSim.Framework.Monitoring
{
/// <summary>
/// Statistics which all collectors are interested in reporting
@@ -44,14 +43,18 @@ namespace OpenSim.Framework.Statistics
StringBuilder sb = new StringBuilder(Environment.NewLine);
sb.Append("MEMORY STATISTICS");
sb.Append(Environment.NewLine);
sb.Append(
string.Format(
"Allocated to OpenSim objects: {0} MB\n",
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)));
sb.Append(
string.Format(
"Process memory : {0} MB\n",
Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0)));
sb.AppendFormat(
"Allocated to OpenSim objects: {0} MB\n",
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0));
sb.AppendFormat(
"OpenSim object memory churn : {0} MB/s\n",
Math.Round((MemoryWatchdog.AverageMemoryChurn * 1000) / 1024.0 / 1024, 3));
sb.AppendFormat(
"Process memory : {0} MB\n",
Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0));
return sb.ToString();
}

View File

@@ -25,7 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace OpenSim.Framework.Statistics.Interfaces
namespace OpenSim.Framework.Monitoring.Interfaces
{
/// <summary>
/// Implemented by objects which allow statistical information to be pulled from them.

View File

@@ -25,7 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace OpenSim.Framework.Statistics
namespace OpenSim.Framework.Monitoring
{
/// <summary>
/// Implemented by classes which collect up non-viewer statistical information

View File

@@ -0,0 +1,129 @@
/*
* 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 System.Threading;
using log4net;
namespace OpenSim.Framework.Monitoring
{
/// <summary>
/// Experimental watchdog for memory usage.
/// </summary>
public static class MemoryWatchdog
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Is this watchdog active?
/// </summary>
public static bool Enabled
{
get { return m_enabled; }
set
{
// m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value);
if (value && !m_enabled)
UpdateLastRecord(GC.GetTotalMemory(false), Util.EnvironmentTickCount());
m_enabled = value;
}
}
private static bool m_enabled;
/// <summary>
/// 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>
/// Maximum number of statistical samples.
/// </summary>
/// <remarks>
/// At the moment this corresponds to 1 minute since the sampling rate is every 2.5 seconds as triggered from
/// the main Watchdog.
/// </remarks>
private static int m_maxSamples = 24;
/// <summary>
/// Time when the watchdog was last updated.
/// </summary>
private static int m_lastUpdateTick;
/// <summary>
/// Memory used at time of last watchdog update.
/// </summary>
private static long m_lastUpdateMemory;
/// <summary>
/// Memory churn rate per millisecond.
/// </summary>
// private static double m_churnRatePerMillisecond;
/// <summary>
/// Historical samples for calculating moving average.
/// </summary>
private static Queue<double> m_samples = new Queue<double>(m_maxSamples);
public static void Update()
{
int now = Util.EnvironmentTickCount();
long memoryNow = GC.GetTotalMemory(false);
long memoryDiff = memoryNow - m_lastUpdateMemory;
if (memoryDiff >= 0)
{
if (m_samples.Count >= m_maxSamples)
m_samples.Dequeue();
double elapsed = Util.EnvironmentTickCountSubtract(now, m_lastUpdateTick);
// This should never happen since it's not useful for updates to occur with no time elapsed, but
// protect ourselves from a divide-by-zero just in case.
if (elapsed == 0)
return;
m_samples.Enqueue(memoryDiff / (double)elapsed);
}
UpdateLastRecord(memoryNow, now);
}
private static void UpdateLastRecord(long memoryNow, int timeNow)
{
m_lastUpdateMemory = memoryNow;
m_lastUpdateTick = timeNow;
}
}
}

View File

@@ -28,12 +28,11 @@
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
using OpenSim.Framework.Statistics.Interfaces;
using OpenMetaverse.StructuredData;
using OpenSim.Framework.Monitoring.Interfaces;
namespace OpenSim.Framework.Statistics
namespace OpenSim.Framework.Monitoring
{
/// <summary>
/// Collects sim statistics which aren't already being collected for the linden viewer's statistics pane

View File

@@ -25,7 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace OpenSim.Framework.Statistics
namespace OpenSim.Framework.Monitoring
{
/// <summary>
/// Singleton used to provide access to statistics reporters

View File

@@ -27,7 +27,7 @@
using System.Timers;
namespace OpenSim.Framework.Statistics
namespace OpenSim.Framework.Monitoring
{
/// <summary>
/// Collects user service statistics

View File

@@ -31,7 +31,7 @@ using System.Linq;
using System.Threading;
using log4net;
namespace OpenSim.Framework
namespace OpenSim.Framework.Monitoring
{
/// <summary>
/// Manages launching threads and keeping watch over them for timeouts
@@ -41,8 +41,8 @@ namespace OpenSim.Framework
/// <summary>Timer interval in milliseconds for the watchdog timer</summary>
const double WATCHDOG_INTERVAL_MS = 2500.0d;
/// <summary>Maximum timeout in milliseconds before a thread is considered dead</summary>
public const int WATCHDOG_TIMEOUT_MS = 5000;
/// <summary>Default timeout in milliseconds before a thread is considered dead</summary>
public const int DEFAULT_WATCHDOG_TIMEOUT_MS = 5000;
[System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
public class ThreadWatchdogInfo
@@ -89,6 +89,17 @@ namespace OpenSim.Framework
FirstTick = Environment.TickCount & Int32.MaxValue;
LastTick = FirstTick;
}
public ThreadWatchdogInfo(ThreadWatchdogInfo previousTwi)
{
Thread = previousTwi.Thread;
FirstTick = previousTwi.FirstTick;
LastTick = previousTwi.LastTick;
Timeout = previousTwi.Timeout;
IsTimedOut = previousTwi.IsTimedOut;
AlarmIfTimeout = previousTwi.AlarmIfTimeout;
AlarmMethod = previousTwi.AlarmMethod;
}
}
/// <summary>
@@ -97,17 +108,50 @@ namespace OpenSim.Framework
/// /summary>
public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout;
/// <summary>
/// Is this watchdog active?
/// </summary>
public static bool Enabled
{
get { return m_enabled; }
set
{
// m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value);
if (value == m_enabled)
return;
m_enabled = value;
if (m_enabled)
{
// Set now so we don't get alerted on the first run
LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
}
m_watchdogTimer.Enabled = m_enabled;
}
}
private static bool m_enabled;
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static Dictionary<int, ThreadWatchdogInfo> m_threads;
private static System.Timers.Timer m_watchdogTimer;
/// <summary>
/// Last time the watchdog thread ran.
/// </summary>
/// <remarks>
/// Should run every WATCHDOG_INTERVAL_MS
/// </remarks>
public static int LastWatchdogThreadTick { get; private set; }
static Watchdog()
{
m_threads = new Dictionary<int, ThreadWatchdogInfo>();
m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
m_watchdogTimer.AutoReset = false;
m_watchdogTimer.Elapsed += WatchdogTimerElapsed;
m_watchdogTimer.Start();
}
/// <summary>
@@ -122,7 +166,7 @@ namespace OpenSim.Framework
public static Thread StartThread(
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout)
{
return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, WATCHDOG_TIMEOUT_MS);
return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS);
}
/// <summary>
@@ -264,6 +308,16 @@ namespace OpenSim.Framework
/// <param name="e"></param>
private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
int now = Environment.TickCount & Int32.MaxValue;
int msElapsed = now - LastWatchdogThreadTick;
if (msElapsed > WATCHDOG_INTERVAL_MS * 2)
m_log.WarnFormat(
"[WATCHDOG]: {0} ms since Watchdog last ran. Interval should be approximately {1} ms",
msElapsed, WATCHDOG_INTERVAL_MS);
LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
Action<ThreadWatchdogInfo> callback = OnWatchdogTimeout;
if (callback != null)
@@ -272,8 +326,6 @@ namespace OpenSim.Framework
lock (m_threads)
{
int now = Environment.TickCount & Int32.MaxValue;
foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
{
if (threadInfo.Thread.ThreadState == ThreadState.Stopped)
@@ -294,7 +346,9 @@ namespace OpenSim.Framework
if (callbackInfos == null)
callbackInfos = new List<ThreadWatchdogInfo>();
callbackInfos.Add(threadInfo);
// Send a copy of the watchdog info to prevent race conditions where the watchdog
// thread updates the monitoring info after an alarm has been sent out.
callbackInfos.Add(new ThreadWatchdogInfo(threadInfo));
}
}
}
@@ -305,6 +359,9 @@ namespace OpenSim.Framework
callback(callbackInfo);
}
if (MemoryWatchdog.Enabled)
MemoryWatchdog.Update();
m_watchdogTimer.Start();
}
}

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; }
@@ -480,9 +492,16 @@ namespace OpenSim.Framework
MainConsole.Instance.Output("=====================================\n");
if (name == String.Empty)
name = MainConsole.Instance.CmdPrompt("New region name", name);
if (name == String.Empty)
throw new Exception("Cannot interactively create region with no name");
{
while (name.Trim() == string.Empty)
{
name = MainConsole.Instance.CmdPrompt("New region name", name);
if (name.Trim() == string.Empty)
{
MainConsole.Instance.Output("Cannot interactively create region with no name");
}
}
}
source.AddConfig(name);
@@ -513,15 +532,20 @@ namespace OpenSim.Framework
//
allKeys.Remove("RegionUUID");
string regionUUID = config.GetString("RegionUUID", string.Empty);
if (regionUUID == String.Empty)
if (!UUID.TryParse(regionUUID.Trim(), out RegionID))
{
UUID newID = UUID.Random();
regionUUID = MainConsole.Instance.CmdPrompt("RegionUUID", newID.ToString());
while (RegionID == UUID.Zero)
{
regionUUID = MainConsole.Instance.CmdPrompt("RegionUUID", newID.ToString());
if (!UUID.TryParse(regionUUID.Trim(), out RegionID))
{
MainConsole.Instance.Output("RegionUUID must be a valid UUID");
}
}
config.Set("RegionUUID", regionUUID);
}
RegionID = new UUID(regionUUID);
originRegionID = RegionID; // What IS this?! (Needed for RegionCombinerModule?)
// Location
@@ -611,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");
@@ -656,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)
@@ -742,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

@@ -42,9 +42,7 @@ namespace OpenSim.Framework.Serialization.External
/// </summary>
public class LandDataSerializer
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected static UTF8Encoding m_utf8Encoding = new UTF8Encoding();
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static Dictionary<string, Action<LandData, XmlTextReader>> m_ldProcessors
= new Dictionary<string, Action<LandData, XmlTextReader>>();
@@ -95,6 +93,8 @@ namespace OpenSim.Framework.Serialization.External
"MediaURL", (ld, xtr) => ld.MediaURL = xtr.ReadElementString("MediaURL"));
m_ldProcessors.Add(
"MusicURL", (ld, xtr) => ld.MusicURL = xtr.ReadElementString("MusicURL"));
m_ldProcessors.Add(
"OwnerID", (ld, xtr) => ld.OwnerID = UUID.Parse(xtr.ReadElementString("OwnerID")));
m_ldProcessors.Add(
"ParcelAccessList", ProcessParcelAccessList);
@@ -163,7 +163,7 @@ namespace OpenSim.Framework.Serialization.External
/// <exception cref="System.Xml.XmlException"></exception>
public static LandData Deserialize(byte[] serializedLandData)
{
return Deserialize(m_utf8Encoding.GetString(serializedLandData, 0, serializedLandData.Length));
return Deserialize(Encoding.UTF8.GetString(serializedLandData, 0, serializedLandData.Length));
}
/// <summary>
@@ -188,7 +188,16 @@ namespace OpenSim.Framework.Serialization.External
return landData;
}
public static string Serialize(LandData landData)
/// <summary>
/// Serialize land data
/// </summary>
/// <param name='landData'></param>
/// <param name='options'>
/// Serialization options.
/// Can be null if there are no options.
/// "wipe-owners" will write UUID.Zero rather than the ownerID so that a later reload loads all parcels with the estate owner as the owner
/// </param>
public static string Serialize(LandData landData, Dictionary<string, object> options)
{
StringWriter sw = new StringWriter();
XmlTextWriter xtw = new XmlTextWriter(sw);
@@ -217,7 +226,14 @@ namespace OpenSim.Framework.Serialization.External
xtw.WriteElementString("MediaID", landData.MediaID.ToString());
xtw.WriteElementString("MediaURL", landData.MediaURL);
xtw.WriteElementString("MusicURL", landData.MusicURL);
xtw.WriteElementString("OwnerID", landData.OwnerID.ToString());
UUID ownerIdToWrite;
if (options != null && options.ContainsKey("wipe-owners"))
ownerIdToWrite = UUID.Zero;
else
ownerIdToWrite = landData.OwnerID;
xtw.WriteElementString("OwnerID", ownerIdToWrite.ToString());
xtw.WriteStartElement("ParcelAccessList");
foreach (LandAccessEntry pal in landData.ParcelAccessList)

View File

@@ -65,9 +65,14 @@ namespace OpenSim.Framework.Serialization
UserAccount account = userService.GetUserAccount(UUID.Zero, userId);
if (account != null)
{
return MakeOspa(account.FirstName, account.LastName);
}
// else
// {
// m_log.WarnFormat("[OSP RESOLVER]: No user account for {0}", userId);
// System.Console.WriteLine("[OSP RESOLVER]: No user account for {0}", userId);
// }
return null;
}
@@ -79,10 +84,13 @@ namespace OpenSim.Framework.Serialization
/// <returns></returns>
public static string MakeOspa(string firstName, string lastName)
{
// m_log.DebugFormat("[OSP RESOLVER]: Making OSPA for {0} {1}", firstName, lastName);
string ospa
= OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName;
// m_log.DebugFormat("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName);
// System.Console.WriteLine("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName);
return
OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName;
return ospa;
}
/// <summary>

View File

@@ -40,8 +40,6 @@ namespace OpenSim.Framework.Serialization.External
/// </summary>
public class RegionSettingsSerializer
{
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
/// <summary>
/// Deserialize settings
/// </summary>
@@ -50,7 +48,7 @@ namespace OpenSim.Framework.Serialization.External
/// <exception cref="System.Xml.XmlException"></exception>
public static RegionSettings Deserialize(byte[] serializedSettings)
{
return Deserialize(m_asciiEncoding.GetString(serializedSettings, 0, serializedSettings.Length));
return Deserialize(Encoding.ASCII.GetString(serializedSettings, 0, serializedSettings.Length));
}
/// <summary>

View File

@@ -44,7 +44,7 @@ namespace OpenSim.Framework.Serialization.External
/// </summary>
public class UserInventoryItemSerializer
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static Dictionary<string, Action<InventoryItemBase, XmlTextReader>> m_InventoryItemXmlProcessors
= new Dictionary<string, Action<InventoryItemBase, XmlTextReader>>();

View File

@@ -53,8 +53,6 @@ namespace OpenSim.Framework.Serialization
TYPE_CONTIGUOUS_FILE = 8,
}
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
/// <summary>
/// Binary reader for the underlying stream
/// </summary>
@@ -120,13 +118,13 @@ namespace OpenSim.Framework.Serialization
if (header[156] == (byte)'L')
{
int longNameLength = ConvertOctalBytesToDecimal(header, 124, 11);
tarHeader.FilePath = m_asciiEncoding.GetString(ReadData(longNameLength));
tarHeader.FilePath = Encoding.ASCII.GetString(ReadData(longNameLength));
//m_log.DebugFormat("[TAR ARCHIVE READER]: Got long file name {0}", tarHeader.FilePath);
header = m_br.ReadBytes(512);
}
else
{
tarHeader.FilePath = m_asciiEncoding.GetString(header, 0, 100);
tarHeader.FilePath = Encoding.ASCII.GetString(header, 0, 100);
tarHeader.FilePath = tarHeader.FilePath.Trim(m_nullCharArray);
//m_log.DebugFormat("[TAR ARCHIVE READER]: Got short file name {0}", tarHeader.FilePath);
}
@@ -205,7 +203,7 @@ namespace OpenSim.Framework.Serialization
{
// Trim leading white space: ancient tars do that instead
// of leading 0s :-( don't ask. really.
string oString = m_asciiEncoding.GetString(bytes, startIndex, count).TrimStart(m_spaceCharArray);
string oString = Encoding.ASCII.GetString(bytes, startIndex, count).TrimStart(m_spaceCharArray);
int d = 0;

View File

@@ -41,9 +41,6 @@ namespace OpenSim.Framework.Serialization
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
protected static UTF8Encoding m_utf8Encoding = new UTF8Encoding();
/// <summary>
/// Binary writer for the underlying stream
/// </summary>
@@ -74,7 +71,7 @@ namespace OpenSim.Framework.Serialization
/// <param name="data"></param>
public void WriteFile(string filePath, string data)
{
WriteFile(filePath, m_utf8Encoding.GetBytes(data));
WriteFile(filePath, Util.UTF8NoBomEncoding.GetBytes(data));
}
/// <summary>
@@ -85,7 +82,7 @@ namespace OpenSim.Framework.Serialization
public void WriteFile(string filePath, byte[] data)
{
if (filePath.Length > 100)
WriteEntry("././@LongLink", m_asciiEncoding.GetBytes(filePath), 'L');
WriteEntry("././@LongLink", Encoding.ASCII.GetBytes(filePath), 'L');
char fileType;
@@ -137,7 +134,7 @@ namespace OpenSim.Framework.Serialization
oString = "0" + oString;
}
byte[] oBytes = m_asciiEncoding.GetBytes(oString);
byte[] oBytes = Encoding.ASCII.GetBytes(oString);
return oBytes;
}
@@ -156,20 +153,20 @@ namespace OpenSim.Framework.Serialization
byte[] header = new byte[512];
// file path field (100)
byte[] nameBytes = m_asciiEncoding.GetBytes(filePath);
byte[] nameBytes = Encoding.ASCII.GetBytes(filePath);
int nameSize = (nameBytes.Length >= 100) ? 100 : nameBytes.Length;
Array.Copy(nameBytes, header, nameSize);
// file mode (8)
byte[] modeBytes = m_asciiEncoding.GetBytes("0000777");
byte[] modeBytes = Encoding.ASCII.GetBytes("0000777");
Array.Copy(modeBytes, 0, header, 100, 7);
// owner user id (8)
byte[] ownerIdBytes = m_asciiEncoding.GetBytes("0000764");
byte[] ownerIdBytes = Encoding.ASCII.GetBytes("0000764");
Array.Copy(ownerIdBytes, 0, header, 108, 7);
// group user id (8)
byte[] groupIdBytes = m_asciiEncoding.GetBytes("0000764");
byte[] groupIdBytes = Encoding.ASCII.GetBytes("0000764");
Array.Copy(groupIdBytes, 0, header, 116, 7);
// file size in bytes (12)
@@ -181,17 +178,17 @@ namespace OpenSim.Framework.Serialization
Array.Copy(fileSizeBytes, 0, header, 124, 11);
// last modification time (12)
byte[] lastModTimeBytes = m_asciiEncoding.GetBytes("11017037332");
byte[] lastModTimeBytes = Encoding.ASCII.GetBytes("11017037332");
Array.Copy(lastModTimeBytes, 0, header, 136, 11);
// entry type indicator (1)
header[156] = m_asciiEncoding.GetBytes(new char[] { fileType })[0];
header[156] = Encoding.ASCII.GetBytes(new char[] { fileType })[0];
Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 329, 7);
Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 337, 7);
Array.Copy(Encoding.ASCII.GetBytes("0000000"), 0, header, 329, 7);
Array.Copy(Encoding.ASCII.GetBytes("0000000"), 0, header, 337, 7);
// check sum for header block (8) [calculated last]
Array.Copy(m_asciiEncoding.GetBytes(" "), 0, header, 148, 8);
Array.Copy(Encoding.ASCII.GetBytes(" "), 0, header, 148, 8);
int checksum = 0;
foreach (byte b in header)

View File

@@ -42,22 +42,23 @@ namespace OpenSim.Framework.Serialization.Tests
private LandData land;
private LandData landWithParcelAccessList;
private static string preSerialized = "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<LandData>\n <Area>128</Area>\n <AuctionID>0</AuctionID>\n <AuthBuyerID>00000000-0000-0000-0000-000000000000</AuthBuyerID>\n <Category>10</Category>\n <ClaimDate>0</ClaimDate>\n <ClaimPrice>0</ClaimPrice>\n <GlobalID>54ff9641-dd40-4a2c-b1f1-47dd3af24e50</GlobalID>\n <GroupID>d740204e-bbbf-44aa-949d-02c7d739f6a5</GroupID>\n <IsGroupOwned>False</IsGroupOwned>\n <Bitmap>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Bitmap>\n <Description>land data to test LandDataSerializer</Description>\n <Flags>536870944</Flags>\n <LandingType>2</LandingType>\n <Name>LandDataSerializerTest Land</Name>\n <Status>0</Status>\n <LocalID>0</LocalID>\n <MediaAutoScale>1</MediaAutoScale>\n <MediaID>d4452578-2f25-4b97-a81b-819af559cfd7</MediaID>\n <MediaURL>http://videos.opensimulator.org/bumblebee.mp4</MediaURL>\n <MusicURL />\n <OwnerID>1b8eedf9-6d15-448b-8015-24286f1756bf</OwnerID>\n <ParcelAccessList />\n <PassHours>0</PassHours>\n <PassPrice>0</PassPrice>\n <SalePrice>0</SalePrice>\n <SnapshotID>00000000-0000-0000-0000-000000000000</SnapshotID>\n <UserLocation>&lt;0, 0, 0&gt;</UserLocation>\n <UserLookAt>&lt;0, 0, 0&gt;</UserLookAt>\n <Dwell>0</Dwell>\n <OtherCleanTime>0</OtherCleanTime>\n</LandData>";
private static string preSerializedWithParcelAccessList = "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<LandData>\n <Area>128</Area>\n <AuctionID>0</AuctionID>\n <AuthBuyerID>00000000-0000-0000-0000-000000000000</AuthBuyerID>\n <Category>10</Category>\n <ClaimDate>0</ClaimDate>\n <ClaimPrice>0</ClaimPrice>\n <GlobalID>54ff9641-dd40-4a2c-b1f1-47dd3af24e50</GlobalID>\n <GroupID>d740204e-bbbf-44aa-949d-02c7d739f6a5</GroupID>\n <IsGroupOwned>False</IsGroupOwned>\n <Bitmap>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Bitmap>\n <Description>land data to test LandDataSerializer</Description>\n <Flags>536870944</Flags>\n <LandingType>2</LandingType>\n <Name>LandDataSerializerTest Land</Name>\n <Status>0</Status>\n <LocalID>0</LocalID>\n <MediaAutoScale>1</MediaAutoScale>\n <MediaID>d4452578-2f25-4b97-a81b-819af559cfd7</MediaID>\n <MediaURL>http://videos.opensimulator.org/bumblebee.mp4</MediaURL>\n <MusicURL />\n <OwnerID>1b8eedf9-6d15-448b-8015-24286f1756bf</OwnerID>\n <ParcelAccessList>\n <ParcelAccessEntry>\n <AgentID>62d65d45-c91a-4f77-862c-46557d978b6c</AgentID>\n <Time>0</Time>\n <AccessList>2</AccessList>\n </ParcelAccessEntry>\n <ParcelAccessEntry>\n <AgentID>ec2a8d18-2378-4fe0-8b68-2a31b57c481e</AgentID>\n <Time>0</Time>\n <AccessList>1</AccessList>\n </ParcelAccessEntry>\n </ParcelAccessList>\n <PassHours>0</PassHours>\n <PassPrice>0</PassPrice>\n <SalePrice>0</SalePrice>\n <SnapshotID>00000000-0000-0000-0000-000000000000</SnapshotID>\n <UserLocation>&lt;0, 0, 0&gt;</UserLocation>\n <UserLookAt>&lt;0, 0, 0&gt;</UserLookAt>\n <Dwell>0</Dwell>\n <OtherCleanTime>0</OtherCleanTime>\n</LandData>";
// private static string preSerialized = "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<LandData>\n <Area>128</Area>\n <AuctionID>0</AuctionID>\n <AuthBuyerID>00000000-0000-0000-0000-000000000000</AuthBuyerID>\n <Category>10</Category>\n <ClaimDate>0</ClaimDate>\n <ClaimPrice>0</ClaimPrice>\n <GlobalID>54ff9641-dd40-4a2c-b1f1-47dd3af24e50</GlobalID>\n <GroupID>d740204e-bbbf-44aa-949d-02c7d739f6a5</GroupID>\n <IsGroupOwned>False</IsGroupOwned>\n <Bitmap>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Bitmap>\n <Description>land data to test LandDataSerializer</Description>\n <Flags>536870944</Flags>\n <LandingType>2</LandingType>\n <Name>LandDataSerializerTest Land</Name>\n <Status>0</Status>\n <LocalID>0</LocalID>\n <MediaAutoScale>1</MediaAutoScale>\n <MediaID>d4452578-2f25-4b97-a81b-819af559cfd7</MediaID>\n <MediaURL>http://videos.opensimulator.org/bumblebee.mp4</MediaURL>\n <MusicURL />\n <OwnerID>1b8eedf9-6d15-448b-8015-24286f1756bf</OwnerID>\n <ParcelAccessList />\n <PassHours>0</PassHours>\n <PassPrice>0</PassPrice>\n <SalePrice>0</SalePrice>\n <SnapshotID>00000000-0000-0000-0000-000000000000</SnapshotID>\n <UserLocation>&lt;0, 0, 0&gt;</UserLocation>\n <UserLookAt>&lt;0, 0, 0&gt;</UserLookAt>\n <Dwell>0</Dwell>\n <OtherCleanTime>0</OtherCleanTime>\n</LandData>";
private static string preSerializedWithParcelAccessList
= "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<LandData>\n <Area>128</Area>\n <AuctionID>0</AuctionID>\n <AuthBuyerID>00000000-0000-0000-0000-000000000000</AuthBuyerID>\n <Category>10</Category>\n <ClaimDate>0</ClaimDate>\n <ClaimPrice>0</ClaimPrice>\n <GlobalID>54ff9641-dd40-4a2c-b1f1-47dd3af24e50</GlobalID>\n <GroupID>d740204e-bbbf-44aa-949d-02c7d739f6a5</GroupID>\n <IsGroupOwned>False</IsGroupOwned>\n <Bitmap>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Bitmap>\n <Description>land data to test LandDataSerializer</Description>\n <Flags>536870944</Flags>\n <LandingType>2</LandingType>\n <Name>LandDataSerializerTest Land</Name>\n <Status>0</Status>\n <LocalID>0</LocalID>\n <MediaAutoScale>1</MediaAutoScale>\n <MediaID>d4452578-2f25-4b97-a81b-819af559cfd7</MediaID>\n <MediaURL>http://videos.opensimulator.org/bumblebee.mp4</MediaURL>\n <MusicURL />\n <OwnerID>1b8eedf9-6d15-448b-8015-24286f1756bf</OwnerID>\n <ParcelAccessList>\n <ParcelAccessEntry>\n <AgentID>62d65d45-c91a-4f77-862c-46557d978b6c</AgentID>\n <Time>0</Time>\n <AccessList>2</AccessList>\n </ParcelAccessEntry>\n <ParcelAccessEntry>\n <AgentID>ec2a8d18-2378-4fe0-8b68-2a31b57c481e</AgentID>\n <Time>0</Time>\n <AccessList>1</AccessList>\n </ParcelAccessEntry>\n </ParcelAccessList>\n <PassHours>0</PassHours>\n <PassPrice>0</PassPrice>\n <SalePrice>0</SalePrice>\n <SnapshotID>00000000-0000-0000-0000-000000000000</SnapshotID>\n <UserLocation>&lt;0, 0, 0&gt;</UserLocation>\n <UserLookAt>&lt;0, 0, 0&gt;</UserLookAt>\n <Dwell>0</Dwell>\n <OtherCleanTime>0</OtherCleanTime>\n</LandData>";
[SetUp]
public void setup()
{
// setup LandData object
this.land = new LandData();
this.land.AABBMax = new Vector3(0, 0, 0);
this.land.AABBMin = new Vector3(128, 128, 128);
this.land.AABBMax = new Vector3(1, 2, 3);
this.land.AABBMin = new Vector3(129, 130, 131);
this.land.Area = 128;
this.land.AuctionID = 0;
this.land.AuthBuyerID = new UUID();
this.land.AuctionID = 4;
this.land.AuthBuyerID = new UUID("7176df0c-6c50-45db-8a37-5e78be56a0cd");
this.land.Category = ParcelCategory.Residential;
this.land.ClaimDate = 0;
this.land.ClaimPrice = 0;
this.land.ClaimDate = 1;
this.land.ClaimPrice = 2;
this.land.GlobalID = new UUID("54ff9641-dd40-4a2c-b1f1-47dd3af24e50");
this.land.GroupID = new UUID("d740204e-bbbf-44aa-949d-02c7d739f6a5");
this.land.Description = "land data to test LandDataSerializer";
@@ -65,7 +66,7 @@ namespace OpenSim.Framework.Serialization.Tests
this.land.LandingType = (byte)LandingType.Direct;
this.land.Name = "LandDataSerializerTest Land";
this.land.Status = ParcelStatus.Leased;
this.land.LocalID = 0;
this.land.LocalID = 1;
this.land.MediaAutoScale = (byte)0x01;
this.land.MediaID = new UUID("d4452578-2f25-4b97-a81b-819af559cfd7");
this.land.MediaURL = "http://videos.opensimulator.org/bumblebee.mp4";
@@ -90,26 +91,26 @@ namespace OpenSim.Framework.Serialization.Tests
/// <summary>
/// Test the LandDataSerializer.Serialize() method
/// </summary>
[Test]
public void LandDataSerializerSerializeTest()
{
TestHelpers.InMethod();
string serialized = LandDataSerializer.Serialize(this.land).Replace("\r\n", "\n");
Assert.That(serialized.Length > 0, "Serialize(LandData) returned empty string");
// adding a simple boolean variable because resharper nUnit integration doesn't like this
// XML data in the Assert.That statement. Not sure why.
bool result = (serialized == preSerialized);
Assert.That(result, "result of Serialize LandData does not match expected result");
string serializedWithParcelAccessList = LandDataSerializer.Serialize(this.landWithParcelAccessList).Replace("\r\n", "\n");
Assert.That(serializedWithParcelAccessList.Length > 0,
"Serialize(LandData) returned empty string for LandData object with ParcelAccessList");
result = (serializedWithParcelAccessList == preSerializedWithParcelAccessList);
Assert.That(result,
"result of Serialize(LandData) does not match expected result (pre-serialized with parcel access list");
}
// [Test]
// public void LandDataSerializerSerializeTest()
// {
// TestHelpers.InMethod();
//
// string serialized = LandDataSerializer.Serialize(this.land).Replace("\r\n", "\n");
// Assert.That(serialized.Length > 0, "Serialize(LandData) returned empty string");
//
// // adding a simple boolean variable because resharper nUnit integration doesn't like this
// // XML data in the Assert.That statement. Not sure why.
// bool result = (serialized == preSerialized);
// Assert.That(result, "result of Serialize LandData does not match expected result");
//
// string serializedWithParcelAccessList = LandDataSerializer.Serialize(this.landWithParcelAccessList).Replace("\r\n", "\n");
// Assert.That(serializedWithParcelAccessList.Length > 0,
// "Serialize(LandData) returned empty string for LandData object with ParcelAccessList");
// result = (serializedWithParcelAccessList == preSerializedWithParcelAccessList);
// Assert.That(result,
// "result of Serialize(LandData) does not match expected result (pre-serialized with parcel access list");
// }
/// <summary>
/// Test the LandDataSerializer.Deserialize() method
@@ -120,10 +121,28 @@ namespace OpenSim.Framework.Serialization.Tests
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
LandData ld = LandDataSerializer.Deserialize(LandDataSerializerTest.preSerialized);
Assert.That(ld != null, "Deserialize(string) returned null");
Assert.That(ld.GlobalID == this.land.GlobalID, "Reified LandData.GlobalID != original LandData.GlobalID");
Assert.That(ld.Name == this.land.Name, "Reified LandData.Name != original LandData.Name");
LandData ld = LandDataSerializer.Deserialize(LandDataSerializer.Serialize(this.land, null));
Assert.That(ld, Is.Not.Null, "Deserialize(string) returned null");
// Assert.That(ld.AABBMax, Is.EqualTo(land.AABBMax));
// Assert.That(ld.AABBMin, Is.EqualTo(land.AABBMin));
Assert.That(ld.Area, Is.EqualTo(land.Area));
Assert.That(ld.AuctionID, Is.EqualTo(land.AuctionID));
Assert.That(ld.AuthBuyerID, Is.EqualTo(land.AuthBuyerID));
Assert.That(ld.Category, Is.EqualTo(land.Category));
Assert.That(ld.ClaimDate, Is.EqualTo(land.ClaimDate));
Assert.That(ld.ClaimPrice, Is.EqualTo(land.ClaimPrice));
Assert.That(ld.GlobalID, Is.EqualTo(land.GlobalID), "Reified LandData.GlobalID != original LandData.GlobalID");
Assert.That(ld.GroupID, Is.EqualTo(land.GroupID));
Assert.That(ld.Description, Is.EqualTo(land.Description));
Assert.That(ld.Flags, Is.EqualTo(land.Flags));
Assert.That(ld.LandingType, Is.EqualTo(land.LandingType));
Assert.That(ld.Name, Is.EqualTo(land.Name), "Reified LandData.Name != original LandData.Name");
Assert.That(ld.Status, Is.EqualTo(land.Status));
Assert.That(ld.LocalID, Is.EqualTo(land.LocalID));
Assert.That(ld.MediaAutoScale, Is.EqualTo(land.MediaAutoScale));
Assert.That(ld.MediaID, Is.EqualTo(land.MediaID));
Assert.That(ld.MediaURL, Is.EqualTo(land.MediaURL));
Assert.That(ld.OwnerID, Is.EqualTo(land.OwnerID));
}
[Test]

View File

@@ -40,9 +40,9 @@ using log4net.Core;
using log4net.Repository;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Framework.Statistics;
using Timer=System.Timers.Timer;
using OpenMetaverse;
@@ -320,7 +320,9 @@ namespace OpenSim.Framework.Servers
TimeSpan timeTaken = DateTime.Now - m_startuptime;
m_log.InfoFormat("[STARTUP]: Startup took {0}m {1}s", timeTaken.Minutes, timeTaken.Seconds);
m_log.InfoFormat(
"[STARTUP]: Non-script portion of startup took {0}m {1}s. PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED.",
timeTaken.Minutes, timeTaken.Seconds);
}
/// <summary>
@@ -589,8 +591,8 @@ namespace OpenSim.Framework.Servers
{
string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
FileStream fs = File.Create(path);
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
Byte[] buf = enc.GetBytes(pidstring);
Byte[] buf = Encoding.ASCII.GetBytes(pidstring);
fs.Write(buf, 0, buf.Length);
fs.Close();
m_pidFile = path;

View File

@@ -45,6 +45,7 @@ using OpenMetaverse.StructuredData;
using CoolHTTPListener = HttpServer.HttpListener;
using HttpListener=System.Net.HttpListener;
using LogPrio=HttpServer.LogPrio;
using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers.HttpServer
{
@@ -53,6 +54,8 @@ namespace OpenSim.Framework.Servers.HttpServer
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private HttpServerLogWriter httpserverlog = new HttpServerLogWriter();
public int DebugLevel { get; set; }
private volatile int NotSocketErrors = 0;
public volatile bool HTTPDRunning = false;
@@ -79,11 +82,6 @@ namespace OpenSim.Framework.Servers.HttpServer
private PollServiceRequestManager m_PollServiceManager;
/// <summary>
/// Control the printing of certain debug messages.
/// </summary>
public int DebugLevel { get; set; }
public uint SSLPort
{
get { return m_sslport; }
@@ -450,7 +448,7 @@ namespace OpenSim.Framework.Servers.HttpServer
if (TryGetStreamHandler(handlerKey, out requestHandler))
{
if (DebugLevel >= 1)
if (DebugLevel >= 3)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}",
request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description);
@@ -531,7 +529,7 @@ namespace OpenSim.Framework.Servers.HttpServer
case null:
case "text/html":
if (DebugLevel >= 1)
if (DebugLevel >= 3)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
@@ -543,7 +541,7 @@ namespace OpenSim.Framework.Servers.HttpServer
case "application/xml+llsd":
case "application/llsd+json":
if (DebugLevel >= 1)
if (DebugLevel >= 3)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
@@ -564,7 +562,7 @@ namespace OpenSim.Framework.Servers.HttpServer
//m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler");
if (DoWeHaveALLSDHandler(request.RawUrl))
{
if (DebugLevel >= 1)
if (DebugLevel >= 3)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
@@ -574,7 +572,7 @@ namespace OpenSim.Framework.Servers.HttpServer
// m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl);
else if (DoWeHaveAHTTPHandler(request.RawUrl))
{
if (DebugLevel >= 1)
if (DebugLevel >= 3)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
@@ -583,8 +581,7 @@ namespace OpenSim.Framework.Servers.HttpServer
}
else
{
if (DebugLevel >= 1)
if (DebugLevel >= 3)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
request.HttpMethod, request.Url.PathAndQuery);
@@ -786,15 +783,30 @@ namespace OpenSim.Framework.Servers.HttpServer
requestStream.Close();
//m_log.Debug(requestBody);
requestBody = requestBody.Replace("<base64></base64>", "");
string responseString = null;
string responseString = String.Empty;
XmlRpcRequest xmlRprcRequest = null;
try
{
xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody);
}
catch (XmlException)
catch (XmlException e)
{
if (DebugLevel >= 1)
{
if (DebugLevel >= 2)
m_log.Warn(
string.Format(
"[BASE HTTP SERVER]: Got XMLRPC request with invalid XML from {0}. XML was '{1}'. Sending blank response. Exception ",
request.RemoteIPEndPoint, requestBody),
e);
else
{
m_log.WarnFormat(
"[BASE HTTP SERVER]: Got XMLRPC request with invalid XML from {0}, length {1}. Sending blank response.",
request.RemoteIPEndPoint, requestBody.Length);
}
}
}
if (xmlRprcRequest != null)
@@ -1546,6 +1558,9 @@ namespace OpenSim.Framework.Servers.HttpServer
private void StartHTTP()
{
m_log.InfoFormat(
"[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port);
try
{
//m_httpListener = new HttpListener();

View File

@@ -28,6 +28,7 @@
using System;
using System.Collections;
using OpenMetaverse;
namespace OpenSim.Framework.Servers.HttpServer
{
public delegate void RequestMethod(UUID requestID, Hashtable request);
@@ -44,7 +45,11 @@ namespace OpenSim.Framework.Servers.HttpServer
public NoEventsMethod NoEvents;
public RequestMethod Request;
public UUID Id;
public PollServiceEventArgs(RequestMethod pRequest, HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,UUID pId)
public PollServiceEventArgs(
RequestMethod pRequest,
HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,
UUID pId)
{
Request = pRequest;
HasEvents = pHasEvents;
@@ -53,4 +58,4 @@ namespace OpenSim.Framework.Servers.HttpServer
Id = pId;
}
}
}
}

View File

@@ -31,7 +31,6 @@ using OpenMetaverse;
namespace OpenSim.Framework.Servers.HttpServer
{
public class PollServiceHttpRequest
{
public readonly PollServiceEventArgs PollServiceArgs;
@@ -39,7 +38,9 @@ namespace OpenSim.Framework.Servers.HttpServer
public readonly IHttpRequest Request;
public readonly int RequestTime;
public readonly UUID RequestID;
public PollServiceHttpRequest(PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
public PollServiceHttpRequest(
PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
{
PollServiceArgs = pPollServiceArgs;
HttpContext = pHttpContext;
@@ -48,4 +49,4 @@ namespace OpenSim.Framework.Servers.HttpServer
RequestID = UUID.Random();
}
}
}
}

View File

@@ -32,6 +32,7 @@ using System.Reflection;
using log4net;
using HttpServer;
using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers.HttpServer
{

View File

@@ -34,6 +34,7 @@ using HttpServer;
using OpenMetaverse;
using System.Reflection;
using log4net;
using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers.HttpServer
{
@@ -129,9 +130,7 @@ namespace OpenSim.Framework.Servers.HttpServer
OSHttpResponse response
= new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext);
byte[] buffer
= server.DoHTTPGruntWork(
responsedata, new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext));
byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
response.SendChunked = false;
response.ContentLength64 = buffer.Length;

View File

@@ -25,57 +25,209 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Net;
using log4net;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers.HttpServer;
namespace OpenSim.Framework.Servers
{
public class MainServer
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static BaseHttpServer instance = null;
private static Dictionary<uint, BaseHttpServer> m_Servers =
new Dictionary<uint, BaseHttpServer>();
private static Dictionary<uint, BaseHttpServer> m_Servers = new Dictionary<uint, BaseHttpServer>();
/// <summary>
/// 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.
/// </remarks>
public static int DebugLevel
{
get { return s_debugLevel; }
set
{
s_debugLevel = value;
lock (m_Servers)
foreach (BaseHttpServer server in m_Servers.Values)
server.DebugLevel = s_debugLevel;
}
}
private static int s_debugLevel;
/// <summary>
/// Set the main HTTP server instance.
/// </summary>
/// <remarks>
/// This will be used to register all handlers that listen to the default port.
/// </remarks>
/// <exception cref='Exception'>
/// Thrown if the HTTP server has not already been registered via AddHttpServer()
/// </exception>
public static BaseHttpServer Instance
{
get { return instance; }
set { instance = value; }
set
{
lock (m_Servers)
if (!m_Servers.ContainsValue(value))
throw new Exception("HTTP server must already have been registered to be set as the main instance");
instance = value;
}
}
public static IHttpServer GetHttpServer(uint port)
/// <summary>
/// Get all the registered servers.
/// </summary>
/// <remarks>
/// Returns a copy of the dictionary so this can be iterated through without locking.
/// </remarks>
/// <value></value>
public static Dictionary<uint, BaseHttpServer> Servers
{
return GetHttpServer(port,null);
get { return new Dictionary<uint, BaseHttpServer>(m_Servers); }
}
public static void RegisterHttpConsoleCommands(ICommandConsole console)
{
console.Commands.AddCommand(
"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);
}
/// <summary>
/// Turn on some debugging values for OpenSim.
/// </summary>
/// <param name="args"></param>
private static void HandleDebugHttpCommand(string module, string[] args)
{
if (args.Length == 3)
{
int newDebug;
if (int.TryParse(args[2], out newDebug))
{
MainServer.DebugLevel = 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
{
MainConsole.Instance.Output("Usage: debug http 0..3");
}
}
/// <summary>
/// Register an already started HTTP server to the collection of known servers.
/// </summary>
/// <param name='server'></param>
public static void AddHttpServer(BaseHttpServer server)
{
m_Servers.Add(server.Port, server);
lock (m_Servers)
{
if (m_Servers.ContainsKey(server.Port))
throw new Exception(string.Format("HTTP server for port {0} already exists.", server.Port));
m_Servers.Add(server.Port, server);
}
}
/// <summary>
/// Removes the http server listening on the given port.
/// </summary>
/// <remarks>
/// It is the responsibility of the caller to do clean up.
/// </remarks>
/// <param name='port'></param>
/// <returns></returns>
public static bool RemoveHttpServer(uint port)
{
lock (m_Servers)
return m_Servers.Remove(port);
}
/// <summary>
/// Does this collection of servers contain one with the given port?
/// </summary>
/// <remarks>
/// Unlike GetHttpServer, this will not instantiate a server if one does not exist on that port.
/// </remarks>
/// <param name='port'></param>
/// <returns>true if a server with the given port is registered, false otherwise.</returns>
public static bool ContainsHttpServer(uint port)
{
lock (m_Servers)
return m_Servers.ContainsKey(port);
}
/// <summary>
/// Get the default http server or an http server for a specific port.
/// </summary>
/// <remarks>
/// If the requested HTTP server doesn't already exist then a new one is instantiated and started.
/// </remarks>
/// <returns></returns>
/// <param name='port'>If 0 then the default HTTP server is returned.</param>
public static IHttpServer GetHttpServer(uint port)
{
return GetHttpServer(port, null);
}
/// <summary>
/// Get the default http server, an http server for a specific port
/// and/or an http server bound to a specific address
/// </summary>
/// <remarks>
/// If the requested HTTP server doesn't already exist then a new one is instantiated and started.
/// </remarks>
/// <returns></returns>
/// <param name='port'>If 0 then the default HTTP server is returned.</param>
/// <param name='ipaddr'>A specific IP address to bind to. If null then the default IP address is used.</param>
public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr)
{
if (port == 0)
return Instance;
if (instance != null && port == Instance.Port)
return Instance;
if (m_Servers.ContainsKey(port))
lock (m_Servers)
{
if (m_Servers.ContainsKey(port))
return m_Servers[port];
m_Servers[port] = new BaseHttpServer(port);
if (ipaddr != null)
m_Servers[port].ListenIPAddress = ipaddr;
m_Servers[port].Start();
return m_Servers[port];
m_Servers[port] = new BaseHttpServer(port);
if (ipaddr != null)
m_Servers[port].ListenIPAddress = ipaddr;
m_log.InfoFormat("[MAIN HTTP SERVER]: Starting main http server on port {0}", port);
m_Servers[port].Start();
return m_Servers[port];
}
}
}
}
}

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,6 +353,15 @@ namespace OpenSim.Framework
}
}
public bool ScriptRunning {
get {
return _scriptRunning;
}
set {
_scriptRunning = value;
}
}
// See ICloneable
#region ICloneable Members

View File

@@ -148,6 +148,7 @@ namespace OpenSim.Framework
}
public static Encoding UTF8 = Encoding.UTF8;
public static Encoding UTF8NoBomEncoding = new UTF8Encoding(false);
/// <value>
/// Well known UUID for the blank texture used in the Linden SL viewer version 1.20 (and hopefully onwards)
@@ -849,6 +850,12 @@ namespace OpenSim.Framework
return Math.Min(Math.Max(x, min), max);
}
public static Vector3 Clip(Vector3 vec, float min, float max)
{
return new Vector3(Clip(vec.X, min, max), Clip(vec.Y, min, max),
Clip(vec.Z, min, max));
}
/// <summary>
/// Convert an UUID to a raw uuid string. Right now this is a string without hyphens.
/// </summary>
@@ -1236,8 +1243,7 @@ namespace OpenSim.Framework
public static string Base64ToString(string str)
{
UTF8Encoding encoder = new UTF8Encoding();
Decoder utf8Decode = encoder.GetDecoder();
Decoder utf8Decode = Encoding.UTF8.GetDecoder();
byte[] todecode_byte = Convert.FromBase64String(str);
int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);

View File

@@ -92,9 +92,14 @@ namespace OpenSim
m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config");
}
m_log.DebugFormat(
m_log.InfoFormat(
"[OPENSIM MAIN]: System Locale is {0}", System.Threading.Thread.CurrentThread.CurrentCulture);
string monoThreadsPerCpu = System.Environment.GetEnvironmentVariable("MONO_THREADS_PER_CPU");
m_log.InfoFormat(
"[OPENSIM MAIN]: Environment variable MONO_THREADS_PER_CPU is {0}", monoThreadsPerCpu ?? "unset");
// Increase the number of IOCP threads available. Mono defaults to a tragically low number
int workerThreads, iocpThreads;
System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
@@ -109,7 +114,6 @@ namespace OpenSim
// Check if the system is compatible with OpenSimulator.
// Ensures that the minimum system requirements are met
m_log.Info("Performing compatibility checks... \n");
string supported = String.Empty;
if (Util.IsEnvironmentSupported(ref supported))
{

View File

@@ -35,12 +35,13 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Timers;
using log4net;
using NDesk.Options;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Statistics;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
@@ -200,9 +201,9 @@ namespace OpenSim
PrintFileToConsole("startuplogo.txt");
// For now, start at the 'root' level by default
if (m_sceneManager.Scenes.Count == 1) // If there is only one region, select it
if (SceneManager.Scenes.Count == 1) // If there is only one region, select it
ChangeSelectedRegion("region",
new string[] {"change", "region", m_sceneManager.Scenes[0].RegionInfo.RegionName});
new string[] {"change", "region", SceneManager.Scenes[0].RegionInfo.RegionName});
else
ChangeSelectedRegion("region", new string[] {"change", "region", "root"});
@@ -231,12 +232,14 @@ namespace OpenSim
/// </summary>
private void RegisterConsoleCommands()
{
MainServer.RegisterHttpConsoleCommands(m_console);
m_console.Commands.AddCommand("Objects", false, "force update",
"force update",
"Force the update of all objects on clients",
HandleForceUpdate);
m_console.Commands.AddCommand("Comms", false, "debug packet",
m_console.Commands.AddCommand("Debug", false, "debug packet",
"debug packet <level> [<avatar-first-name> <avatar-last-name>]",
"Turn on packet debugging",
"If level > 255 then all incoming and outgoing packets are logged.\n"
@@ -248,17 +251,9 @@ namespace OpenSim
+ "If an avatar name is given then only packets from that avatar are logged",
Debug);
m_console.Commands.AddCommand("Comms", false, "debug http",
"debug http <level>",
"Turn on inbound http request debugging for everything except the event queue (see debug eq).",
"If level >= 2 then the handler used to service the request is logged.\n"
+ "If level >= 1 then incoming HTTP requests are logged.\n"
+ "If level <= 0 then no extra http logging is done.\n",
Debug);
m_console.Commands.AddCommand("Debug", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
m_console.Commands.AddCommand("Comms", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
m_console.Commands.AddCommand("Regions", false, "debug scene",
m_console.Commands.AddCommand("Debug", false, "debug scene",
"debug scene <scripting> <collisions> <physics>",
"Turn on scene debugging", Debug);
@@ -300,14 +295,13 @@ namespace OpenSim
"save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]",
"Save a region's data to an OAR archive.",
// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
"-h|--home=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
+ "--noassets stops assets being saved to the OAR." + Environment.NewLine
+ "--publish saves an OAR stripped of owner and last owner information." + Environment.NewLine
+ " on reload, the estate owner will be the owner of all objects" + Environment.NewLine
+ " this is useful if you're making oars generally available that might be reloaded to the same grid from which you published" + Environment.NewLine
+ " this option is EXPERIMENTAL" + Environment.NewLine
+ "--perm=<permissions> stops objects with insufficient permissions from being saved to the OAR." + Environment.NewLine
+ " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer" + Environment.NewLine
"-h|--home=<url> adds the url of the profile service to the saved user information.\n"
+ "--noassets stops assets being saved to the OAR.\n"
+ "--publish saves an OAR stripped of owner and last owner information.\n"
+ " on reload, the estate owner will be the owner of all objects\n"
+ " this is useful if you're making oars generally available that might be reloaded to the same grid from which you published\n"
+ "--perm=<permissions> stops objects with insufficient permissions from being saved to the OAR.\n"
+ " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer\n"
+ "The OAR path must be a filesystem path."
+ " If this is not given then the oar is saved to region.oar in the current directory.",
SaveOar);
@@ -317,8 +311,11 @@ namespace OpenSim
"Change the scale of a named prim", HandleEditScale);
m_console.Commands.AddCommand("Users", false, "kick user",
"kick user <first> <last> [message]",
"Kick a user off the simulator", KickUserCommand);
"kick user <first> <last> [--force] [message]",
"Kick a user off the simulator",
"The --force option will kick the user without any checks to see whether it's already in the process of closing\n"
+ "Only use this option if you are sure the avatar is inactive and a normal kick user operation does not removed them",
KickUserCommand);
m_console.Commands.AddCommand("Users", false, "show users",
"show users [full]",
@@ -415,10 +412,6 @@ namespace OpenSim
m_console.Commands.AddCommand("General", false, "modules unload",
"modules unload <name>",
"Unload a module", HandleModules);
m_console.Commands.AddCommand("Objects", false, "kill uuid",
"kill uuid <UUID>",
"Kill an object by UUID", KillUUID);
}
public override void ShutdownSpecific()
@@ -427,6 +420,7 @@ namespace OpenSim
{
RunCommandScript(m_shutdownCommandsFile);
}
base.ShutdownSpecific();
}
@@ -464,21 +458,27 @@ namespace OpenSim
/// <param name="cmdparams">name of avatar to kick</param>
private void KickUserCommand(string module, string[] cmdparams)
{
if (cmdparams.Length < 4)
bool force = false;
OptionSet options = new OptionSet().Add("f|force", delegate (string v) { force = v != null; });
List<string> mainParams = options.Parse(cmdparams);
if (mainParams.Count < 4)
return;
string alert = null;
if (cmdparams.Length > 4)
if (mainParams.Count > 4)
alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4));
IList agents = m_sceneManager.GetCurrentSceneAvatars();
IList agents = SceneManager.GetCurrentSceneAvatars();
foreach (ScenePresence presence in agents)
{
RegionInfo regionInfo = presence.Scene.RegionInfo;
if (presence.Firstname.ToLower().Contains(cmdparams[2].ToLower()) &&
presence.Lastname.ToLower().Contains(cmdparams[3].ToLower()))
if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) &&
presence.Lastname.ToLower().Contains(mainParams[3].ToLower()))
{
MainConsole.Instance.Output(
String.Format(
@@ -491,7 +491,7 @@ namespace OpenSim
else
presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n");
presence.Scene.IncomingCloseAgent(presence.UUID);
presence.Scene.IncomingCloseAgent(presence.UUID, force);
}
}
@@ -552,7 +552,7 @@ namespace OpenSim
private void HandleForceUpdate(string module, string[] args)
{
MainConsole.Instance.Output("Updating all clients");
m_sceneManager.ForceCurrentSceneClientUpdate();
SceneManager.ForceCurrentSceneClientUpdate();
}
/// <summary>
@@ -564,7 +564,7 @@ namespace OpenSim
{
if (args.Length == 6)
{
m_sceneManager.HandleEditCommandOnCurrentScene(args);
SceneManager.HandleEditCommandOnCurrentScene(args);
}
else
{
@@ -775,7 +775,7 @@ namespace OpenSim
case "load":
if (cmdparams.Length > 1)
{
foreach (Scene s in new ArrayList(m_sceneManager.Scenes))
foreach (Scene s in new ArrayList(SceneManager.Scenes))
{
MainConsole.Instance.Output(String.Format("Loading module: {0}", cmdparams[1]));
m_moduleLoader.LoadRegionModules(cmdparams[1], s);
@@ -813,14 +813,14 @@ namespace OpenSim
case "backup":
MainConsole.Instance.Output("Triggering save of pending object updates to persistent store");
m_sceneManager.BackupCurrentScene();
SceneManager.BackupCurrentScene();
break;
case "remove-region":
string regRemoveName = CombineParams(cmdparams, 0);
Scene removeScene;
if (m_sceneManager.TryGetScene(regRemoveName, out removeScene))
if (SceneManager.TryGetScene(regRemoveName, out removeScene))
RemoveRegion(removeScene, false);
else
MainConsole.Instance.Output("No region with that name");
@@ -830,14 +830,14 @@ namespace OpenSim
string regDeleteName = CombineParams(cmdparams, 0);
Scene killScene;
if (m_sceneManager.TryGetScene(regDeleteName, out killScene))
if (SceneManager.TryGetScene(regDeleteName, out killScene))
RemoveRegion(killScene, true);
else
MainConsole.Instance.Output("no region with that name");
break;
case "restart":
m_sceneManager.RestartCurrentScene();
SceneManager.RestartCurrentScene();
break;
}
}
@@ -852,7 +852,7 @@ namespace OpenSim
{
string newRegionName = CombineParams(cmdparams, 2);
if (!m_sceneManager.TrySetCurrentScene(newRegionName))
if (!SceneManager.TrySetCurrentScene(newRegionName))
MainConsole.Instance.Output(String.Format("Couldn't select region {0}", newRegionName));
}
else
@@ -860,7 +860,7 @@ namespace OpenSim
MainConsole.Instance.Output("Usage: change region <region name>");
}
string regionName = (m_sceneManager.CurrentScene == null ? "root" : m_sceneManager.CurrentScene.RegionInfo.RegionName);
string regionName = (SceneManager.CurrentScene == null ? "root" : SceneManager.CurrentScene.RegionInfo.RegionName);
MainConsole.Instance.Output(String.Format("Currently selected region is {0}", regionName));
// m_log.DebugFormat("Original prompt is {0}", m_consolePrompt);
@@ -878,7 +878,7 @@ namespace OpenSim
});
m_console.DefaultPrompt = prompt;
m_console.ConsoleScene = m_sceneManager.CurrentScene;
m_console.ConsoleScene = SceneManager.CurrentScene;
}
/// <summary>
@@ -902,7 +902,7 @@ namespace OpenSim
int newDebug;
if (int.TryParse(args[2], out newDebug))
{
m_sceneManager.SetDebugPacketLevelOnCurrentScene(newDebug, name);
SceneManager.SetDebugPacketLevelOnCurrentScene(newDebug, name);
// We provide user information elsewhere if any clients had their debug level set.
// MainConsole.Instance.OutputFormat("Debug packet level set to {0}", newDebug);
}
@@ -914,25 +914,10 @@ namespace OpenSim
break;
case "http":
if (args.Length == 3)
{
int newDebug;
if (int.TryParse(args[2], out newDebug))
{
MainServer.Instance.DebugLevel = newDebug;
MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug);
break;
}
}
MainConsole.Instance.Output("Usage: debug http 0..2");
break;
case "scene":
if (args.Length == 4)
{
if (m_sceneManager.CurrentScene == null)
if (SceneManager.CurrentScene == null)
{
MainConsole.Instance.Output("Please use 'change region <regioname>' first");
}
@@ -940,7 +925,7 @@ namespace OpenSim
{
string key = args[2];
string value = args[3];
m_sceneManager.CurrentScene.SetSceneCoreDebug(
SceneManager.CurrentScene.SetSceneCoreDebug(
new Dictionary<string, string>() { { key, value } });
MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value);
@@ -979,10 +964,10 @@ namespace OpenSim
IList agents;
if (showParams.Length > 1 && showParams[1] == "full")
{
agents = m_sceneManager.GetCurrentScenePresences();
agents = SceneManager.GetCurrentScenePresences();
} else
{
agents = m_sceneManager.GetCurrentSceneAvatars();
agents = SceneManager.GetCurrentSceneAvatars();
}
MainConsole.Instance.Output(String.Format("\nAgents connected: {0}\n", agents.Count));
@@ -1021,44 +1006,11 @@ namespace OpenSim
break;
case "connections":
System.Text.StringBuilder connections = new System.Text.StringBuilder("Connections:\n");
m_sceneManager.ForEachScene(
delegate(Scene scene) {
scene.ForEachClient(
delegate(IClientAPI client) {
connections.AppendFormat(
"{0}: {1} ({2}) from {3} on circuit {4}\n",
scene.RegionInfo.RegionName,
client.Name,
client.AgentId,
client.RemoteEndPoint,
client.CircuitCode
);
}
);
}
);
MainConsole.Instance.Output(connections.ToString());
HandleShowConnections();
break;
case "circuits":
System.Text.StringBuilder acd = new System.Text.StringBuilder("Agent Circuits:\n");
m_sceneManager.ForEachScene(
delegate(Scene scene) {
//this.HttpServer.
acd.AppendFormat("{0}:\n", scene.RegionInfo.RegionName);
foreach (AgentCircuitData aCircuit in scene.AuthenticateHandler.GetAgentCircuits().Values)
acd.AppendFormat(
"\t{0} {1} ({2})\n",
aCircuit.firstname,
aCircuit.lastname,
(aCircuit.child ? "Child" : "Root")
);
}
);
MainConsole.Instance.Output(acd.ToString());
HandleShowCircuits();
break;
case "http-handlers":
@@ -1095,7 +1047,7 @@ namespace OpenSim
MainConsole.Instance.Output("Shared Module: " + module.Name);
}
m_sceneManager.ForEachScene(
SceneManager.ForEachScene(
delegate(Scene scene) {
m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:");
foreach (IRegionModule module in scene.Modules.Values)
@@ -1108,7 +1060,7 @@ namespace OpenSim
}
);
m_sceneManager.ForEachScene(
SceneManager.ForEachScene(
delegate(Scene scene) {
MainConsole.Instance.Output("Loaded new region modules in" + scene.RegionInfo.RegionName + " are:");
foreach (IRegionModuleBase module in scene.RegionModules.Values)
@@ -1124,7 +1076,7 @@ namespace OpenSim
break;
case "regions":
m_sceneManager.ForEachScene(
SceneManager.ForEachScene(
delegate(Scene scene)
{
MainConsole.Instance.Output(String.Format(
@@ -1138,7 +1090,7 @@ namespace OpenSim
break;
case "ratings":
m_sceneManager.ForEachScene(
SceneManager.ForEachScene(
delegate(Scene scene)
{
string rating = "";
@@ -1163,6 +1115,53 @@ namespace OpenSim
}
}
private void HandleShowCircuits()
{
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
cdt.AddColumn("Region", 20);
cdt.AddColumn("Avatar name", 24);
cdt.AddColumn("Type", 5);
cdt.AddColumn("Code", 10);
cdt.AddColumn("IP", 16);
cdt.AddColumn("Viewer Name", 24);
SceneManager.ForEachScene(
s =>
{
foreach (AgentCircuitData aCircuit in s.AuthenticateHandler.GetAgentCircuits().Values)
cdt.AddRow(
s.Name,
aCircuit.Name,
aCircuit.child ? "child" : "root",
aCircuit.circuitcode.ToString(),
aCircuit.IPAddress.ToString(),
aCircuit.Viewer);
});
MainConsole.Instance.Output(cdt.ToString());
}
private void HandleShowConnections()
{
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
cdt.AddColumn("Region", 20);
cdt.AddColumn("Avatar name", 24);
cdt.AddColumn("Circuit code", 12);
cdt.AddColumn("Endpoint", 23);
cdt.AddColumn("Active?", 7);
SceneManager.ForEachScene(
s => s.ForEachClient(
c => cdt.AddRow(
s.Name,
c.Name,
c.CircuitCode.ToString(),
c.RemoteEndPoint.ToString(),
c.IsActive.ToString())));
MainConsole.Instance.Output(cdt.ToString());
}
/// <summary>
/// Use XML2 format to serialize data to a file
/// </summary>
@@ -1172,11 +1171,11 @@ namespace OpenSim
{
if (cmdparams.Length > 5)
{
m_sceneManager.SaveNamedPrimsToXml2(cmdparams[3], cmdparams[4]);
SceneManager.SaveNamedPrimsToXml2(cmdparams[3], cmdparams[4]);
}
else
{
m_sceneManager.SaveNamedPrimsToXml2("Primitive", DEFAULT_PRIM_BACKUP_FILENAME);
SceneManager.SaveNamedPrimsToXml2("Primitive", DEFAULT_PRIM_BACKUP_FILENAME);
}
}
@@ -1191,11 +1190,11 @@ namespace OpenSim
if (cmdparams.Length > 0)
{
m_sceneManager.SaveCurrentSceneToXml(cmdparams[2]);
SceneManager.SaveCurrentSceneToXml(cmdparams[2]);
}
else
{
m_sceneManager.SaveCurrentSceneToXml(DEFAULT_PRIM_BACKUP_FILENAME);
SceneManager.SaveCurrentSceneToXml(DEFAULT_PRIM_BACKUP_FILENAME);
}
}
@@ -1232,13 +1231,13 @@ namespace OpenSim
MainConsole.Instance.Output(String.Format("loadOffsets <X,Y,Z> = <{0},{1},{2}>",loadOffset.X,loadOffset.Y,loadOffset.Z));
}
}
m_sceneManager.LoadCurrentSceneFromXml(cmdparams[2], generateNewIDS, loadOffset);
SceneManager.LoadCurrentSceneFromXml(cmdparams[2], generateNewIDS, loadOffset);
}
else
{
try
{
m_sceneManager.LoadCurrentSceneFromXml(DEFAULT_PRIM_BACKUP_FILENAME, false, loadOffset);
SceneManager.LoadCurrentSceneFromXml(DEFAULT_PRIM_BACKUP_FILENAME, false, loadOffset);
}
catch (FileNotFoundException)
{
@@ -1255,11 +1254,11 @@ namespace OpenSim
{
if (cmdparams.Length > 2)
{
m_sceneManager.SaveCurrentSceneToXml2(cmdparams[2]);
SceneManager.SaveCurrentSceneToXml2(cmdparams[2]);
}
else
{
m_sceneManager.SaveCurrentSceneToXml2(DEFAULT_PRIM_BACKUP_FILENAME);
SceneManager.SaveCurrentSceneToXml2(DEFAULT_PRIM_BACKUP_FILENAME);
}
}
@@ -1274,7 +1273,7 @@ namespace OpenSim
{
try
{
m_sceneManager.LoadCurrentSceneFromXml2(cmdparams[2]);
SceneManager.LoadCurrentSceneFromXml2(cmdparams[2]);
}
catch (FileNotFoundException)
{
@@ -1285,7 +1284,7 @@ namespace OpenSim
{
try
{
m_sceneManager.LoadCurrentSceneFromXml2(DEFAULT_PRIM_BACKUP_FILENAME);
SceneManager.LoadCurrentSceneFromXml2(DEFAULT_PRIM_BACKUP_FILENAME);
}
catch (FileNotFoundException)
{
@@ -1302,7 +1301,7 @@ namespace OpenSim
{
try
{
m_sceneManager.LoadArchiveToCurrentScene(cmdparams);
SceneManager.LoadArchiveToCurrentScene(cmdparams);
}
catch (Exception e)
{
@@ -1316,7 +1315,7 @@ namespace OpenSim
/// <param name="cmdparams"></param>
protected void SaveOar(string module, string[] cmdparams)
{
m_sceneManager.SaveCurrentSceneToArchive(cmdparams);
SceneManager.SaveCurrentSceneToArchive(cmdparams);
}
private static string CombineParams(string[] commandParams, int pos)
@@ -1330,58 +1329,6 @@ namespace OpenSim
return result;
}
/// <summary>
/// Kill an object given its UUID.
/// </summary>
/// <param name="cmdparams"></param>
protected void KillUUID(string module, string[] cmdparams)
{
if (cmdparams.Length > 2)
{
UUID id = UUID.Zero;
SceneObjectGroup grp = null;
Scene sc = null;
if (!UUID.TryParse(cmdparams[2], out id))
{
MainConsole.Instance.Output("[KillUUID]: Error bad UUID format!");
return;
}
m_sceneManager.ForEachScene(
delegate(Scene scene)
{
SceneObjectPart part = scene.GetSceneObjectPart(id);
if (part == null)
return;
grp = part.ParentGroup;
sc = scene;
});
if (grp == null)
{
MainConsole.Instance.Output(String.Format("[KillUUID]: Given UUID {0} not found!", id));
}
else
{
MainConsole.Instance.Output(String.Format("[KillUUID]: Found UUID {0} in scene {1}", id, sc.RegionInfo.RegionName));
try
{
sc.DeleteSceneObject(grp, false);
}
catch (Exception e)
{
m_log.ErrorFormat("[KillUUID]: Error while removing objects from scene: " + e);
}
}
}
else
{
MainConsole.Instance.Output("[KillUUID]: Usage: kill uuid <UUID>");
}
}
#endregion
}
}

View File

@@ -40,7 +40,7 @@ using OpenSim.Framework.Communications;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Framework.Statistics;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.ClientStack;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts;
using OpenSim.Region.Framework;
@@ -285,7 +285,7 @@ namespace OpenSim
private void HandleCommanderCommand(string module, string[] cmd)
{
m_sceneManager.SendCommandToPluginModules(cmd);
SceneManager.SendCommandToPluginModules(cmd);
}
private void HandleCommanderHelp(string module, string[] cmd)
@@ -303,7 +303,15 @@ namespace OpenSim
// Called from base.StartUp()
m_httpServerPort = m_networkServersInfo.HttpListenerPort;
m_sceneManager.OnRestartSim += handleRestartRegion;
SceneManager.OnRestartSim += handleRestartRegion;
// Only enable the watchdogs when all regions are ready. Otherwise we get false positives when cpu is
// heavily used during initial startup.
//
// FIXME: It's also possible that region ready status should be flipped during an OAR load since this
// also makes heavy use of the CPU.
SceneManager.OnRegionsReadyStatusChange
+= sm => { MemoryWatchdog.Enabled = sm.AllRegionsReady; Watchdog.Enabled = sm.AllRegionsReady; };
}
/// <summary>
@@ -412,7 +420,7 @@ namespace OpenSim
// scripting engines.
scene.CreateScriptInstances();
m_sceneManager.Add(scene);
SceneManager.Add(scene);
if (m_autoCreateClientStack)
{
@@ -432,7 +440,6 @@ namespace OpenSim
mscene = scene;
scene.Start();
scene.StartScripts();
return clientServer;
@@ -561,14 +568,14 @@ namespace OpenSim
{
// only need to check this if we are not at the
// root level
if ((m_sceneManager.CurrentScene != null) &&
(m_sceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID))
if ((SceneManager.CurrentScene != null) &&
(SceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID))
{
m_sceneManager.TrySetCurrentScene("..");
SceneManager.TrySetCurrentScene("..");
}
scene.DeleteAllSceneObjects();
m_sceneManager.CloseScene(scene);
SceneManager.CloseScene(scene);
ShutdownClientServer(scene.RegionInfo);
if (!cleanup)
@@ -610,7 +617,7 @@ namespace OpenSim
public void RemoveRegion(string name, bool cleanUp)
{
Scene target;
if (m_sceneManager.TryGetScene(name, out target))
if (SceneManager.TryGetScene(name, out target))
RemoveRegion(target, cleanUp);
}
@@ -623,13 +630,13 @@ namespace OpenSim
{
// only need to check this if we are not at the
// root level
if ((m_sceneManager.CurrentScene != null) &&
(m_sceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID))
if ((SceneManager.CurrentScene != null) &&
(SceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID))
{
m_sceneManager.TrySetCurrentScene("..");
SceneManager.TrySetCurrentScene("..");
}
m_sceneManager.CloseScene(scene);
SceneManager.CloseScene(scene);
ShutdownClientServer(scene.RegionInfo);
}
@@ -641,7 +648,7 @@ namespace OpenSim
public void CloseRegion(string name)
{
Scene target;
if (m_sceneManager.TryGetScene(name, out target))
if (SceneManager.TryGetScene(name, out target))
CloseRegion(target);
}
@@ -698,6 +705,7 @@ namespace OpenSim
scene.LoadWorldMap();
scene.PhysicsScene = GetPhysicsScene(scene.RegionInfo.RegionName);
scene.PhysicsScene.RequestAssetMethod = scene.PhysicsRequestAsset;
scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
scene.PhysicsScene.SetWaterLevel((float) regionInfo.RegionSettings.WaterHeight);
@@ -897,7 +905,7 @@ namespace OpenSim
try
{
m_sceneManager.Close();
SceneManager.Close();
}
catch (Exception e)
{
@@ -922,7 +930,7 @@ namespace OpenSim
/// <param name="usernum">The first out parameter describing the number of all the avatars in the Region server</param>
public void GetAvatarNumber(out int usernum)
{
usernum = m_sceneManager.GetCurrentSceneAvatars().Count;
usernum = SceneManager.GetCurrentSceneAvatars().Count;
}
/// <summary>
@@ -931,7 +939,7 @@ namespace OpenSim
/// <param name="regionnum">The first out parameter describing the number of regions</param>
public void GetRegionNumber(out int regionnum)
{
regionnum = m_sceneManager.Scenes.Count;
regionnum = SceneManager.Scenes.Count;
}
/// <summary>

View File

@@ -123,9 +123,14 @@ namespace OpenSim.Region.ClientStack.Linden
IConfig sconfig = config.Configs["Startup"];
if (sconfig != null)
{
m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
m_levelUpload = sconfig.GetInt("LevelUpload", 0);
}
IConfig appearanceConfig = config.Configs["Appearance"];
if (appearanceConfig != null)
{
m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
}
}
m_assetService = m_Scene.AssetService;

View File

@@ -106,7 +106,7 @@ namespace OpenSim.Region.ClientStack.Linden
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
MainConsole.Instance.Commands.AddCommand(
"Comms",
"Debug",
false,
"debug eq",
"debug eq [0|1|2]",

View File

@@ -51,7 +51,16 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
[SetUp]
public void SetUp()
{
MainServer.Instance = new BaseHttpServer(9999, false, 9998, "");
uint port = 9999;
uint sslPort = 9998;
// This is an unfortunate bit of clean up we have to do because MainServer manages things through static
// variables and the VM is not restarted between tests.
MainServer.RemoveHttpServer(port);
BaseHttpServer server = new BaseHttpServer(port, false, sslPort, "");
MainServer.AddHttpServer(server);
MainServer.Instance = server;
IConfigSource config = new IniConfigSource();
config.AddConfig("Startup");
@@ -85,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
UUID spId = TestHelpers.ParseTail(0x1);
SceneHelpers.AddScenePresence(m_scene, spId);
m_scene.IncomingCloseAgent(spId);
m_scene.IncomingCloseAgent(spId, false);
// TODO: Add more assertions for the other aspects of event queues
Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));

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

@@ -66,9 +66,9 @@ namespace OpenSim.Region.ClientStack.Linden
public void Initialise(IConfigSource source)
{
IConfig sconfig = source.Configs["Startup"];
if (sconfig != null)
m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
IConfig appearanceConfig = source.Configs["Appearance"];
if (appearanceConfig != null)
m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
}
public void AddRegion(Scene s)

View File

@@ -41,7 +41,7 @@ using OpenMetaverse.Messages.Linden;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Client;
using OpenSim.Framework.Statistics;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
@@ -59,7 +59,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Handles new client connections
/// Constructor takes a single Packet and authenticates everything
/// </summary>
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IClientIPEndpoint, IStatsCollector
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IStatsCollector
{
/// <value>
/// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details.
@@ -347,8 +347,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private int m_animationSequenceNumber = 1;
private bool m_SendLogoutPacketWhenClosing = true;
private AgentUpdateArgs lastarg;
private bool m_IsActive = true;
private bool m_IsLoggingOut = false;
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
@@ -357,7 +355,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected string m_lastName;
protected Thread m_clientThread;
protected Vector3 m_startpos;
protected EndPoint m_userEndPoint;
protected UUID m_activeGroupID;
protected string m_activeGroupName = String.Empty;
protected ulong m_activeGroupPowers;
@@ -413,16 +410,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public uint CircuitCode { get { return m_circuitCode; } }
public int MoneyBalance { get { return m_moneyBalance; } }
public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } }
public bool IsActive
{
get { return m_IsActive; }
set { m_IsActive = value; }
}
public bool IsLoggingOut
{
get { return m_IsLoggingOut; }
set { m_IsLoggingOut = value; }
}
/// <summary>
/// As well as it's function in IClientAPI, in LLClientView we are locking on this property in order to
/// prevent race conditions by different threads calling Close().
/// </summary>
public bool IsActive { get; set; }
/// <summary>
/// Used to synchronise threads when client is being closed.
/// </summary>
public Object CloseSyncLock { get; private set; }
public bool IsLoggingOut { get; set; }
public bool DisableFacelights
{
@@ -442,15 +442,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>
/// Constructor
/// </summary>
public LLClientView(EndPoint remoteEP, Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo,
public LLClientView(Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo,
UUID agentId, UUID sessionId, uint circuitCode)
{
// DebugPacketLevel = 1;
CloseSyncLock = new Object();
RegisterInterface<IClientIM>(this);
RegisterInterface<IClientInventory>(this);
RegisterInterface<IClientChat>(this);
RegisterInterface<IClientIPEndpoint>(this);
m_scene = scene;
m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
@@ -467,7 +468,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_sessionId = sessionId;
m_secureSessionId = sessionInfo.LoginInfo.SecureSession;
m_circuitCode = circuitCode;
m_userEndPoint = remoteEP;
m_firstName = sessionInfo.LoginInfo.First;
m_lastName = sessionInfo.LoginInfo.Last;
m_startpos = sessionInfo.LoginInfo.StartPos;
@@ -481,17 +481,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_prioritizer = new Prioritizer(m_scene);
RegisterLocalPacketHandlers();
IsActive = true;
}
#region Client Methods
/// <summary>
/// Shut down the client view
/// </summary>
public void Close()
{
IsActive = false;
Close(false);
}
public void Close(bool force)
{
// We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
// a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
lock (CloseSyncLock)
{
// We still perform a force close inside the sync lock since this is intended to attempt close where
// there is some unidentified connection problem, not where we have issues due to deadlock
if (!IsActive && !force)
return;
IsActive = false;
CloseWithoutChecks();
}
}
/// <summary>
/// Closes down the client view without first checking whether it is active.
/// </summary>
/// <remarks>
/// This exists because LLUDPServer has to set IsActive = false in earlier synchronous code before calling
/// CloseWithoutIsActiveCheck asynchronously.
///
/// Callers must lock ClosingSyncLock before calling.
/// </remarks>
public void CloseWithoutChecks()
{
m_log.DebugFormat(
"[CLIENT]: Close has been called for {0} attached to scene {1}",
Name, m_scene.RegionInfo.RegionName);
@@ -3570,7 +3597,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
{
if (!IsActive) return; // We don't need to update inactive clients.
// We don't need to update inactive clients.
if (!IsActive)
return;
CoarseLocationUpdatePacket loc = (CoarseLocationUpdatePacket)PacketPool.Instance.GetPacket(PacketType.CoarseLocationUpdate);
loc.Header.Reliable = false;
@@ -3808,6 +3837,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
&& part.ParentGroup.HasPrivateAttachmentPoint
&& part.ParentGroup.AttachedAvatar != AgentId)
continue;
// If the part has since been deleted, then drop the update. In the case of attachments,
// this is to avoid spurious updates to other viewers since post-processing of attachments
// has to change the IsAttachment flag for various reasons (which will end up in a pass
// of the test above).
//
// Actual deletions (kills) happen in another method.
if (part.ParentGroup.IsDeleted)
continue;
}
objectUpdateBlocks.Value.Add(updateBlock);
@@ -3815,7 +3853,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
else if (!canUseImproved)
{
compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
SceneObjectPart part = (SceneObjectPart)update.Entity;
ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
= CreateCompressedUpdateBlock(part, updateFlags);
// If the part has since been deleted, then drop the update. In the case of attachments,
// this is to avoid spurious updates to other viewers since post-processing of attachments
// has to change the IsAttachment flag for various reasons (which will end up in a pass
// of the test above).
//
// Actual deletions (kills) happen in another method.
if (part.ParentGroup.IsDeleted)
continue;
compressedUpdateBlocks.Value.Add(compressedBlock);
compressedUpdates.Value.Add(update);
}
else
@@ -3828,9 +3879,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
else
{
// Everything else goes here
terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
= CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
// Everything else goes here
if (update.Entity is SceneObjectPart)
{
SceneObjectPart part = (SceneObjectPart)update.Entity;
@@ -3841,11 +3893,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
&& part.ParentGroup.HasPrivateAttachmentPoint
&& part.ParentGroup.AttachedAvatar != AgentId)
continue;
// If the part has since been deleted, then drop the update. In the case of attachments,
// this is to avoid spurious updates to other viewers since post-processing of attachments
// has to change the IsAttachment flag for various reasons (which will end up in a pass
// of the test above).
//
// Actual deletions (kills) happen in another method.
if (part.ParentGroup.IsDeleted)
continue;
}
terseUpdateBlocks.Value.Add(terseUpdateBlock);
terseUpdates.Value.Add(update);
}
}
++updatesThisCall;
#endregion Block Construction
}
@@ -3912,8 +3976,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// If any of the packets created from this call go unacknowledged, all of the updates will be resent
OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
}
++updatesThisCall;
}
#endregion Packet Sending
@@ -4389,37 +4451,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (bl[i].BannedUserID == UUID.Zero)
continue;
BannedUsers.Add(bl[i].BannedUserID);
if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
{
EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
packet.AgentData.TransactionID = UUID.Random();
packet.AgentData.AgentID = AgentId;
packet.AgentData.SessionID = SessionId;
packet.MethodData.Invoice = invoice;
packet.MethodData.Method = Utils.StringToBytes("setaccess");
EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
int j;
for (j = 0; j < (6 + BannedUsers.Count); j++)
{
returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
}
j = 0;
returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
foreach (UUID banned in BannedUsers)
{
returnblock[j].Parameter = banned.GetBytes(); j++;
}
packet.ParamList = returnblock;
packet.Header.Reliable = true;
OutPacket(packet, ThrottleOutPacketType.Task);
BannedUsers.Clear();
}
}
EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
packet.AgentData.TransactionID = UUID.Random();
packet.AgentData.AgentID = AgentId;
packet.AgentData.SessionID = SessionId;
packet.MethodData.Invoice = invoice;
packet.MethodData.Method = Utils.StringToBytes("setaccess");
EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
for (int i = 0; i < (6 + BannedUsers.Count); i++)
{
returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock();
}
int j = 0;
returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
foreach (UUID banned in BannedUsers)
{
returnblock[j].Parameter = banned.GetBytes(); j++;
}
packet.ParamList = returnblock;
packet.Header.Reliable = false;
OutPacket(packet, ThrottleOutPacketType.Task);
}
public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -5134,7 +5203,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer);
AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate);
AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply);
AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage, false);
AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage);
AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship);
AddLocalPacketHandler(PacketType.DeclineFriendship, HandlerDeclineFriendship);
AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFriendship);
@@ -5752,7 +5821,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
args.Channel = ch;
args.From = String.Empty;
args.Message = Utils.BytesToString(msg);
args.Type = ChatTypeEnum.Shout;
args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
args.Position = new Vector3();
args.Scene = Scene;
args.Sender = this;
@@ -11800,7 +11869,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
ClientInfo info = m_udpClient.GetClientInfo();
info.userEP = m_userEndPoint;
info.proxyEP = null;
info.agentcircuit = RequestClientInfo();
@@ -11812,11 +11880,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_udpClient.SetClientInfo(info);
}
public EndPoint GetClientEP()
{
return m_userEndPoint;
}
#region Media Parcel Members
public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time)
@@ -11937,7 +12000,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
Kick(reason);
Thread.Sleep(1000);
Close();
Disconnect();
}
public void Disconnect()
@@ -12086,24 +12149,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return numPackets;
}
#region IClientIPEndpoint Members
public IPAddress EndPoint
{
get
{
if (m_userEndPoint is IPEndPoint)
{
IPEndPoint ep = (IPEndPoint)m_userEndPoint;
return ep.Address;
}
return null;
}
}
#endregion
public void SendRebakeAvatarTextures(UUID textureID)
{
RebakeAvatarTexturesPacket pack =

View File

@@ -278,7 +278,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public string GetStats()
{
return string.Format(
"{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}",
"{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7} {12,7}",
Util.EnvironmentTickCountSubtract(TickLastPacketReceived),
PacketsReceived,
PacketsSent,
PacketsResent,

View File

@@ -37,7 +37,7 @@ using log4net;
using Nini.Config;
using OpenMetaverse.Packets;
using OpenSim.Framework;
using OpenSim.Framework.Statistics;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Scenes;
using OpenMetaverse;
@@ -270,7 +270,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
false,
true,
GetWatchdogIncomingAlarmData,
Watchdog.WATCHDOG_TIMEOUT_MS);
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
Watchdog.StartThread(
OutgoingPacketHandler,
@@ -279,7 +279,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
false,
true,
GetWatchdogOutgoingAlarmData,
Watchdog.WATCHDOG_TIMEOUT_MS);
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
m_elapsedMSSinceLastStatReport = Environment.TickCount;
}
@@ -986,8 +986,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
m_log.DebugFormat(
"[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} from {1}",
uccp.CircuitCode.Code, buffer.RemoteEndPoint);
"[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}",
uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, buffer.RemoteEndPoint);
remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
@@ -1016,8 +1016,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
// Don't create clients for unauthorized requesters.
m_log.WarnFormat(
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
uccp.CircuitCode.ID, uccp.CircuitCode.Code, remoteEndPoint);
"[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, remoteEndPoint);
}
// m_log.DebugFormat(
@@ -1103,7 +1103,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client.OnLogout += LogoutHandler;
((LLClientView)client).DisableFacelights = m_disableFacelights;
@@ -1123,22 +1123,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// regular client pings.
/// </remarks>
/// <param name='client'></param>
private void DeactivateClientDueToTimeout(IClientAPI client)
private void DeactivateClientDueToTimeout(LLClientView client)
{
// We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even
// though it's set later on by LLClientView.Close()
client.IsActive = false;
m_log.WarnFormat(
"[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}",
client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName);
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
if (!client.SceneAgent.IsChildAgent)
client.Kick("Simulator logged you out due to connection timeout");
client.Close();
lock (client.CloseSyncLock)
{
m_log.WarnFormat(
"[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}",
client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName);
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
if (!client.SceneAgent.IsChildAgent)
client.Kick("Simulator logged you out due to connection timeout");
client.CloseWithoutChecks();
}
}
private void IncomingPacketHandler()

View File

@@ -44,9 +44,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
}
protected int m_objectNameCallsReceived;
public MockScene()
public MockScene() : base(new RegionInfo(1000, 1000, null, null))
{
m_regInfo = new RegionInfo(1000, 1000, null, null);
m_regStatus = RegionStatus.Up;
}

View File

@@ -53,9 +53,8 @@ namespace OpenSim.Region.ClientStack
protected ISimulationDataService m_simulationDataService;
protected IEstateDataService m_estateDataService;
protected ClientStackManager m_clientStackManager;
protected SceneManager m_sceneManager = new SceneManager();
public SceneManager SceneManager { get { return m_sceneManager; } }
public SceneManager SceneManager { get; protected set; }
public NetworkServersInfo NetServersInfo { get { return m_networkServersInfo; } }
public ISimulationDataService SimulationDataService { get { return m_simulationDataService; } }
public IEstateDataService EstateDataService { get { return m_estateDataService; } }
@@ -77,6 +76,7 @@ namespace OpenSim.Region.ClientStack
protected override void StartupSpecific()
{
SceneManager = new SceneManager();
m_clientStackManager = CreateClientStackManager();
Initialize();
@@ -94,22 +94,19 @@ namespace OpenSim.Region.ClientStack
m_log.InfoFormat("[REGION SERVER]: Starting HTTP server on port {0}", m_httpServerPort);
m_httpServer.Start();
MainServer.AddHttpServer(m_httpServer);
MainServer.Instance = m_httpServer;
// "OOB" Server
if (m_networkServersInfo.ssl_listener)
{
BaseHttpServer server = null;
server = new BaseHttpServer(
BaseHttpServer server = new BaseHttpServer(
m_networkServersInfo.https_port, m_networkServersInfo.ssl_listener, m_networkServersInfo.cert_path,
m_networkServersInfo.cert_pass);
// Add the server to m_Servers
if(server != null)
{
m_log.InfoFormat("[REGION SERVER]: Starting HTTPS server on port {0}", server.Port);
MainServer.AddHttpServer(server);
server.Start();
}
m_log.InfoFormat("[REGION SERVER]: Starting HTTPS server on port {0}", server.Port);
MainServer.AddHttpServer(server);
server.Start();
}
base.StartupSpecific();

View File

@@ -143,7 +143,7 @@ namespace Flotsam.RegionModules.AssetCache
IConfig assetConfig = source.Configs["AssetCache"];
if (assetConfig == null)
{
m_log.Warn(
m_log.Debug(
"[FLOTSAM ASSET CACHE]: AssetCache section missing from config (not copied config-include/FlotsamCache.ini.example? Using defaults.");
}
else

View File

@@ -28,6 +28,8 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
using System.Xml;
using log4net;
using Mono.Addins;
using Nini.Config;
@@ -100,6 +102,56 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
#region IAttachmentsModule
public void CopyAttachments(IScenePresence sp, AgentData ad)
{
lock (sp.AttachmentsSyncLock)
{
// Attachment objects
List<SceneObjectGroup> attachments = sp.GetAttachments();
if (attachments.Count > 0)
{
ad.AttachmentObjects = new List<ISceneObject>();
ad.AttachmentObjectStates = new List<string>();
// IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
sp.InTransitScriptStates.Clear();
foreach (SceneObjectGroup sog in attachments)
{
// We need to make a copy and pass that copy
// because of transfers withn the same sim
ISceneObject clone = sog.CloneForNewScene();
// Attachment module assumes that GroupPosition holds the offsets...!
((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
((SceneObjectGroup)clone).IsAttachment = false;
ad.AttachmentObjects.Add(clone);
string state = sog.GetStateSnapshot();
ad.AttachmentObjectStates.Add(state);
sp.InTransitScriptStates.Add(state);
// Let's remove the scripts of the original object here
sog.RemoveScriptInstances(true);
}
}
}
}
public void CopyAttachments(AgentData ad, IScenePresence sp)
{
if (ad.AttachmentObjects != null && ad.AttachmentObjects.Count > 0)
{
lock (sp.AttachmentsSyncLock)
sp.ClearAttachments();
int i = 0;
foreach (ISceneObject so in ad.AttachmentObjects)
{
((SceneObjectGroup)so).LocalId = 0;
((SceneObjectGroup)so).RootPart.ClearUpdateSchedule();
so.SetState(ad.AttachmentObjectStates[i++], m_scene);
m_scene.IncomingCreateObject(Vector3.Zero, so);
}
}
}
/// <summary>
/// RezAttachments. This should only be called upon login on the first region.
/// Attachment rezzings on crossings and TPs are done in a different way.
@@ -152,31 +204,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
}
}
public void SaveChangedAttachments(IScenePresence sp, bool saveAllScripted)
public void DeRezAttachments(IScenePresence sp)
{
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
if (!Enabled)
return;
foreach (SceneObjectGroup grp in sp.GetAttachments())
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
lock (sp.AttachmentsSyncLock)
{
grp.IsAttachment = false;
grp.AbsolutePosition = grp.RootPart.AttachedPos;
UpdateKnownItem(sp, grp, saveAllScripted);
grp.IsAttachment = true;
foreach (SceneObjectGroup so in sp.GetAttachments())
{
UpdateDetachedObject(sp, so);
}
sp.ClearAttachments();
}
}
public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent)
{
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
// m_scene.RegionInfo.RegionName, sp.Name, silent);
if (!Enabled)
return;
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
// m_scene.RegionInfo.RegionName, sp.Name, silent);
foreach (SceneObjectGroup sop in sp.GetAttachments())
{
sop.Scene.DeleteSceneObject(sop, silent);
@@ -185,13 +239,22 @@ 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)
{
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
if (group.GetSittingAvatarsCount() != 0)
{
// m_log.WarnFormat(
// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it",
// group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount());
return false;
}
if (sp.GetAttachments(attachmentPt).Contains(group))
{
@@ -233,33 +296,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
group.AttachmentPoint = attachmentPt;
group.AbsolutePosition = attachPos;
// We also don't want to do any of the inventory operations for an NPC.
if (sp.PresenceType != PresenceType.Npc)
{
// Remove any previous attachments
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
// At the moment we can only deal with a single attachment
if (attachments.Count != 0)
{
UUID oldAttachmentItemID = attachments[0].FromItemID;
if (oldAttachmentItemID != UUID.Zero)
DetachSingleAttachmentToInvInternal(sp, oldAttachmentItemID);
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;
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
}
UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp);
AttachToAgent(sp, group, attachmentPt, attachPos, silent);
}
@@ -267,7 +306,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return true;
}
public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp)
{
// Remove any previous attachments
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
// At the moment we can only deal with a single attachment
if (attachments.Count != 0)
{
if (attachments[0].FromItemID != UUID.Zero)
DetachSingleAttachmentToInvInternal(sp, attachments[0]);
// 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.
if (!temp)
{
UUID newAttachmentItemID = group.FromItemID;
if (newAttachmentItemID == UUID.Zero)
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
}
}
public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
{
if (!Enabled)
return null;
@@ -306,12 +373,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return null;
}
SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt);
if (att == null)
DetachSingleAttachmentToInv(sp, itemID);
return att;
return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt);
}
public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -348,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);
@@ -358,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);
@@ -388,18 +456,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
}
public void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID)
public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so)
{
lock (sp.AttachmentsSyncLock)
{
// Save avatar attachment information
// m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID);
bool changed = sp.Appearance.DetachAttachment(itemID);
if (so.AttachedAvatar != sp.UUID)
{
m_log.WarnFormat(
"[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}",
so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName);
return;
}
bool changed = sp.Appearance.DetachAttachment(so.FromItemID);
if (changed && m_scene.AvatarFactory != null)
m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
DetachSingleAttachmentToInvInternal(sp, itemID);
DetachSingleAttachmentToInvInternal(sp, so);
}
}
@@ -408,17 +485,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
if (!Enabled)
return;
// First we save the
// attachment point information, then we update the relative
// positioning. Then we have to mark the object as NOT an
// attachment. This is necessary in order to correctly save
// and retrieve GroupPosition information for the attachment.
// Finally, we restore the object's attachment status.
uint attachmentPoint = sog.AttachmentPoint;
sog.UpdateGroupPosition(pos);
sog.IsAttachment = false;
sog.AbsolutePosition = sog.RootPart.AttachedPos;
sog.AttachmentPoint = attachmentPoint;
sog.HasGroupChanged = true;
}
@@ -461,8 +528,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
/// </remarks>
/// <param name="sp"></param>
/// <param name="grp"></param>
private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted)
/// <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)
@@ -471,13 +546,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return;
}
if (grp.HasGroupChanged || (saveAllScripted && grp.ContainsScripts()))
if (grp.HasGroupChanged)
{
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
// grp.UUID, grp.AttachmentPoint);
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, scriptedState);
InventoryItemBase item = new InventoryItemBase(grp.FromItemID, sp.UUID);
item = m_scene.InventoryService.GetItem(item);
@@ -500,10 +575,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
m_scene.InventoryService.UpdateItem(item);
// this gets called when the agent logs off!
// If the name of the object has been changed whilst attached then we want to update the inventory
// item in the viewer.
if (sp.ControllingClient != null)
sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
}
grp.HasGroupChanged = false; // Prevent it being saved over and over
}
// else
@@ -562,6 +639,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
{
m_scene.SendKillObject(new List<uint> { so.RootPart.LocalId });
}
else if (so.HasPrivateAttachmentPoint)
{
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}",
// so.Name, sp.Name, so.AttachmentPoint);
// As this scene object can now only be seen by the attaching avatar, tell everybody else in the
// scene that it's no longer in their awareness.
m_scene.ForEachClient(
client =>
{ if (client.AgentId != so.AttachedAvatar)
client.SendKillObject(m_scene.RegionInfo.RegionHandle, new List<uint>() { so.LocalId });
});
}
so.IsSelected = false; // fudge....
so.ScheduleGroupForFullUpdate();
@@ -587,11 +678,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
// grp.Name, grp.LocalId, remoteClient.Name);
InventoryItemBase newItem = m_invAccessModule.CopyToInventory(
DeRezAction.TakeCopy,
m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID,
new List<SceneObjectGroup> { grp },
sp.ControllingClient, true)[0];
InventoryItemBase newItem
= m_invAccessModule.CopyToInventory(
DeRezAction.TakeCopy,
m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID,
new List<SceneObjectGroup> { grp },
sp.ControllingClient, true)[0];
// sets itemID so client can show item as 'attached' in inventory
grp.FromItemID = newItem.ID;
@@ -599,46 +691,68 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return newItem;
}
// What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
// To LocalId or UUID, *THAT* is the question. How now Brown UUID??
private void DetachSingleAttachmentToInvInternal(IScenePresence sp, UUID itemID)
private string GetObjectScriptStates(SceneObjectGroup grp)
{
using (StringWriter sw = new StringWriter())
{
using (XmlTextWriter writer = new XmlTextWriter(sw))
{
grp.SaveScriptedState(writer);
}
return sw.ToString();
}
}
private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so)
{
// Don't save attachments for HG visitors, it
// messes up their inventory. When a HG visitor logs
// out on a foreign grid, their attachments will be
// reloaded in the state they were in when they left
// the home grid. This is best anyway as the visited
// grid may use an incompatible script engine.
bool saveChanged
= sp.PresenceType != PresenceType.Npc
&& (m_scene.UserManagementModule == null
|| m_scene.UserManagementModule.IsLocalGridUser(sp.UUID));
// Scripts MUST be snapshotted before the object is
// removed from the scene because doing otherwise will
// clobber the run flag
string scriptedState = GetObjectScriptStates(so);
// Remove the object from the scene so no more updates
// are sent. Doing this before the below changes will ensure
// updates can't cause "HUD artefacts"
m_scene.DeleteSceneObject(so, false, false);
// Prepare sog for storage
so.AttachedAvatar = UUID.Zero;
so.RootPart.SetParentLocalId(0);
so.IsAttachment = false;
if (saveChanged)
{
// We cannot use AbsolutePosition here because that would
// attempt to cross the prim as it is detached
so.ForEachPart(x => { x.GroupPosition = so.RootPart.AttachedPos; });
UpdateKnownItem(sp, so, scriptedState);
}
// Now, remove the scripts
so.RemoveScriptInstances(true);
}
private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so)
{
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
if (itemID == UUID.Zero) // If this happened, someone made a mistake....
return;
m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero);
sp.RemoveAttachment(so);
// We can NOT use the dictionries here, as we are looking
// for an entity by the fromAssetID, which is NOT the prim UUID
EntityBase[] detachEntities = m_scene.GetEntities();
SceneObjectGroup group;
lock (sp.AttachmentsSyncLock)
{
foreach (EntityBase entity in detachEntities)
{
if (entity is SceneObjectGroup)
{
group = (SceneObjectGroup)entity;
if (group.FromItemID == itemID)
{
m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
sp.RemoveAttachment(group);
// Prepare sog for storage
group.AttachedAvatar = UUID.Zero;
group.RootPart.SetParentLocalId(0);
group.IsAttachment = false;
group.AbsolutePosition = group.RootPart.AttachedPos;
UpdateKnownItem(sp, group, true);
m_scene.DeleteSceneObject(group, false);
return;
}
}
}
}
UpdateDetachedObject(sp, so);
}
private SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
@@ -660,22 +774,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
false, false, sp.UUID, true);
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
// objatt.Name, remoteClient.Name, AttachmentPt);
if (objatt != null)
{
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}",
// objatt.Name, sp.Name, attachmentPt, m_scene.Name);
// HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
objatt.HasGroupChanged = false;
bool tainted = false;
if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
tainted = true;
// FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal
// course of events. If not, then it's probably not worth trying to recover the situation
// since this is more likely to trigger further exceptions and confuse later debugging. If
// exceptions can be thrown in expected error conditions (not NREs) then make this consistent
// since other normal error conditions will simply return false instead.
// This will throw if the attachment fails
try
{
AttachObject(sp, objatt, attachmentPt, false);
AttachObject(sp, objatt, attachmentPt, false, false);
}
catch (Exception e)
{
@@ -742,7 +861,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
item = m_scene.InventoryService.GetItem(item);
bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
if (changed && m_scene.AvatarFactory != null)
{
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()",
// sp.Name, att.Name, AttachmentPt);
m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
}
}
#endregion
@@ -823,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
@@ -846,8 +971,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
if (sp != null && group != null)
DetachSingleAttachmentToInv(sp, group.FromItemID);
if (sp != null && group != null && group.FromItemID != UUID.Zero)
DetachSingleAttachmentToInv(sp, group);
}
private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient)
@@ -857,7 +983,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
if (sp != null)
DetachSingleAttachmentToInv(sp, itemID);
{
lock (sp.AttachmentsSyncLock)
{
List<SceneObjectGroup> attachments = sp.GetAttachments();
foreach (SceneObjectGroup group in attachments)
{
if (group.FromItemID == itemID && group.FromItemID != UUID.Zero)
{
DetachSingleAttachmentToInv(sp, group);
return;
}
}
}
}
}
private void Client_OnObjectDrop(uint soLocalId, IClientAPI remoteClient)

View File

@@ -31,6 +31,7 @@ using System.Reflection;
using System.Text;
using System.Threading;
using System.Timers;
using System.Xml;
using Timer=System.Timers.Timer;
using Nini.Config;
using NUnit.Framework;
@@ -38,11 +39,17 @@ using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
using OpenSim.Region.CoreModules.Avatar.Attachments;
using OpenSim.Region.CoreModules.Framework;
using OpenSim.Region.CoreModules.Framework.EntityTransfer;
using OpenSim.Region.CoreModules.Framework.InventoryAccess;
using OpenSim.Region.CoreModules.World.Serialiser;
using OpenSim.Region.CoreModules.Scripting.WorldComm;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
using OpenSim.Region.CoreModules.World.Serialiser;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.XEngine;
using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
@@ -52,11 +59,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
/// Attachment tests
/// </summary>
[TestFixture]
public class AttachmentsModuleTests
public class AttachmentsModuleTests : OpenSimTestCase
{
private Scene scene;
private AttachmentsModule m_attMod;
private ScenePresence m_presence;
private AutoResetEvent m_chatEvent = new AutoResetEvent(false);
private OSChatMessage m_osChatMessageReceived;
[TestFixtureSetUp]
public void FixtureInit()
@@ -65,18 +71,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
Util.FireAndForgetMethod = FireAndForgetMethod.None;
}
[SetUp]
public void Init()
{
IConfigSource config = new IniConfigSource();
config.AddConfig("Modules");
config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
scene = new SceneHelpers().SetupScene();
m_attMod = new AttachmentsModule();
SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule());
}
[TestFixtureTearDown]
public void TearDown()
{
@@ -85,14 +79,100 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
}
/// <summary>
/// Add the standard presence for a test.
/// </summary>
private void AddPresence()
private void OnChatFromWorld(object sender, OSChatMessage oscm)
{
UUID userId = TestHelpers.ParseTail(0x1);
UserAccountHelpers.CreateUserWithInventory(scene, userId);
m_presence = SceneHelpers.AddScenePresence(scene, userId);
// Console.WriteLine("Got chat [{0}]", oscm.Message);
m_osChatMessageReceived = oscm;
m_chatEvent.Set();
}
private Scene CreateTestScene()
{
IConfigSource config = new IniConfigSource();
List<object> modules = new List<object>();
AddCommonConfig(config, modules);
Scene scene
= new SceneHelpers().SetupScene(
"attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config);
SceneHelpers.SetupSceneModules(scene, config, modules.ToArray());
return scene;
}
private Scene CreateScriptingEnabledTestScene()
{
IConfigSource config = new IniConfigSource();
List<object> modules = new List<object>();
AddCommonConfig(config, modules);
AddScriptingConfig(config, modules);
Scene scene
= new SceneHelpers().SetupScene(
"attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config);
SceneHelpers.SetupSceneModules(scene, config, modules.ToArray());
scene.StartScripts();
return scene;
}
private void AddCommonConfig(IConfigSource config, List<object> modules)
{
config.AddConfig("Modules");
config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
modules.Add(new AttachmentsModule());
modules.Add(new BasicInventoryAccessModule());
}
private void AddScriptingConfig(IConfigSource config, List<object> modules)
{
IConfig startupConfig = config.AddConfig("Startup");
startupConfig.Set("DefaultScriptEngine", "XEngine");
IConfig xEngineConfig = config.AddConfig("XEngine");
xEngineConfig.Set("Enabled", "true");
xEngineConfig.Set("StartDelay", "0");
// These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call
// to AssemblyResolver.OnAssemblyResolve fails.
xEngineConfig.Set("AppDomainLoading", "false");
modules.Add(new XEngine());
// Necessary to stop serialization complaining
// FIXME: Stop this being necessary if at all possible
// modules.Add(new WorldCommModule());
}
/// <summary>
/// Creates an attachment item in the given user's inventory. Does not attach.
/// </summary>
/// <remarks>
/// A user with the given ID and an inventory must already exist.
/// </remarks>
/// <returns>
/// The attachment item.
/// </returns>
/// <param name='scene'></param>
/// <param name='userId'></param>
/// <param name='attName'></param>
/// <param name='rawItemId'></param>
/// <param name='rawAssetId'></param>
private InventoryItemBase CreateAttachmentItem(
Scene scene, UUID userId, string attName, int rawItemId, int rawAssetId)
{
return UserInventoryHelpers.CreateInventoryItem(
scene,
attName,
TestHelpers.ParseTail(rawItemId),
TestHelpers.ParseTail(rawAssetId),
userId,
InventoryType.Object);
}
[Test]
@@ -101,16 +181,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
AddPresence();
Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
string attName = "att";
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, m_presence.UUID).ParentGroup;
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false);
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false);
// Check status on scene presence
Assert.That(m_presence.HasAttachments(), Is.True);
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
Assert.That(sp.HasAttachments(), Is.True);
List<SceneObjectGroup> attachments = sp.GetAttachments();
Assert.That(attachments.Count, Is.EqualTo(1));
SceneObjectGroup attSo = attachments[0];
Assert.That(attSo.Name, Is.EqualTo(attName));
@@ -121,51 +204,123 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
// Check item status
Assert.That(
m_presence.Appearance.GetAttachpoint(attSo.FromItemID),
sp.Appearance.GetAttachpoint(attSo.FromItemID),
Is.EqualTo((int)AttachmentPoint.Chest));
InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
Assert.That(attachmentItem, Is.Not.Null);
Assert.That(attachmentItem.Name, Is.EqualTo(attName));
InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(m_presence.UUID, AssetType.Object);
InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
// TestHelpers.DisableLogging();
}
/// <summary>
/// Test that we do not attempt to attach an in-world object that someone else is sitting on.
/// </summary>
[Test]
public void TestAddAttachmentFromInventory()
public void TestAddSatOnAttachmentFromGround()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
string attName = "att";
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
UserAccount ua2 = UserAccountHelpers.CreateUserWithInventory(scene, 0x2);
ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, ua2);
// Put avatar within 10m of the prim so that sit doesn't fail.
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, false);
Assert.That(sp.HasAttachments(), Is.False);
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
}
[Test]
public void TestRezAttachmentFromInventory()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
AddPresence();
Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
UUID attItemId = TestHelpers.ParseTail(0x2);
UUID attAssetId = TestHelpers.ParseTail(0x3);
string attName = "att";
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
UserInventoryHelpers.CreateInventoryItem(
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
m_attMod.RezSingleAttachmentFromInventory(
m_presence, attItemId, (uint)AttachmentPoint.Chest);
scene.AttachmentsModule.RezSingleAttachmentFromInventory(
sp, attItem.ID, (uint)AttachmentPoint.Chest);
// Check scene presence status
Assert.That(m_presence.HasAttachments(), Is.True);
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
Assert.That(sp.HasAttachments(), Is.True);
List<SceneObjectGroup> attachments = sp.GetAttachments();
Assert.That(attachments.Count, Is.EqualTo(1));
SceneObjectGroup attSo = attachments[0];
Assert.That(attSo.Name, Is.EqualTo(attName));
Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
Assert.That(attSo.IsAttachment);
Assert.That(attSo.UsesPhysics, Is.False);
Assert.That(attSo.IsTemporary, Is.False);
// Check appearance status
Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(1));
Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
}
/// <summary>
/// Test specific conditions associated with rezzing a scripted attachment from inventory.
/// </summary>
[Test]
public void TestRezScriptedAttachmentFromInventory()
{
TestHelpers.InMethod();
Scene scene = CreateScriptingEnabledTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
TaskInventoryItem scriptItem
= TaskInventoryHelpers.AddScript(
scene,
so.RootPart,
"scriptItem",
"default { attach(key id) { if (id != NULL_KEY) { llSay(0, \"Hello World\"); } } }");
InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000);
// FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running.
// In the future, we need to be able to do this programatically more predicably.
scene.EventManager.OnChatFromWorld += OnChatFromWorld;
scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
m_chatEvent.WaitOne(60000);
// TODO: Need to have a test that checks the script is actually started but this involves a lot more
// plumbing of the script engine and either pausing for events or more infrastructure to turn off various
// script engine delays/asychronicity that isn't helpful in an automated regression testing context.
SceneObjectGroup attSo = scene.GetSceneObjectGroup(so.Name);
Assert.That(attSo.ContainsScripts(), Is.True);
TaskInventoryItem reRezzedScriptItem = attSo.RootPart.Inventory.GetInventoryItem(scriptItem.Name);
IScriptModule xengine = scene.RequestModuleInterface<IScriptModule>();
Assert.That(xengine.GetScriptState(reRezzedScriptItem.ItemID), Is.True);
}
[Test]
@@ -174,29 +329,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
AddPresence();
Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
UUID attItemId = TestHelpers.ParseTail(0x2);
UUID attAssetId = TestHelpers.ParseTail(0x3);
string attName = "att";
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
UserInventoryHelpers.CreateInventoryItem(
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory(
m_presence, attItemId, (uint)AttachmentPoint.Chest);
m_attMod.DetachSingleAttachmentToGround(m_presence, so.LocalId);
ISceneEntity so
= scene.AttachmentsModule.RezSingleAttachmentFromInventory(
sp, attItem.ID, (uint)AttachmentPoint.Chest);
scene.AttachmentsModule.DetachSingleAttachmentToGround(sp, so.LocalId);
// Check scene presence status
Assert.That(m_presence.HasAttachments(), Is.False);
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
Assert.That(sp.HasAttachments(), Is.False);
List<SceneObjectGroup> attachments = sp.GetAttachments();
Assert.That(attachments.Count, Is.EqualTo(0));
// Check appearance status
Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(0));
Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(0));
// Check item status
Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Null);
Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItem.ID)), Is.Null);
// Check object in scene
Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null);
@@ -206,28 +359,86 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
public void TestDetachAttachmentToInventory()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
AddPresence();
Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
UUID attItemId = TestHelpers.ParseTail(0x2);
UUID attAssetId = TestHelpers.ParseTail(0x3);
string attName = "att";
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
UserInventoryHelpers.CreateInventoryItem(
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
m_attMod.RezSingleAttachmentFromInventory(
m_presence, attItemId, (uint)AttachmentPoint.Chest);
m_attMod.DetachSingleAttachmentToInv(m_presence, attItemId);
SceneObjectGroup so
= (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory(
sp, attItem.ID, (uint)AttachmentPoint.Chest);
scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, so);
// Check status on scene presence
Assert.That(m_presence.HasAttachments(), Is.False);
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
Assert.That(sp.HasAttachments(), Is.False);
List<SceneObjectGroup> attachments = sp.GetAttachments();
Assert.That(attachments.Count, Is.EqualTo(0));
// Check item status
Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0));
Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0));
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(0));
}
/// <summary>
/// Test specific conditions associated with detaching a scripted attachment from inventory.
/// </summary>
[Test]
public void TestDetachScriptedAttachmentToInventory()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
Scene scene = CreateScriptingEnabledTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
TaskInventoryItem scriptTaskItem
= TaskInventoryHelpers.AddScript(
scene,
so.RootPart,
"scriptItem",
"default { attach(key id) { if (id != NULL_KEY) { llSay(0, \"Hello World\"); } } }");
InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000);
// FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running.
// In the future, we need to be able to do this programatically more predicably.
scene.EventManager.OnChatFromWorld += OnChatFromWorld;
SceneObjectGroup rezzedSo
= scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
// Wait for chat to signal rezzed script has been started.
m_chatEvent.WaitOne(60000);
scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, rezzedSo);
InventoryItemBase userItemUpdated = scene.InventoryService.GetItem(userItem);
AssetBase asset = scene.AssetService.Get(userItemUpdated.AssetID.ToString());
// TODO: It would probably be better here to check script state via the saving and retrieval of state
// information at a higher level, rather than having to inspect the serialization.
XmlDocument soXml = new XmlDocument();
soXml.LoadXml(Encoding.UTF8.GetString(asset.Data));
XmlNodeList scriptStateNodes = soXml.GetElementsByTagName("ScriptState");
Assert.That(scriptStateNodes.Count, Is.EqualTo(1));
// Re-rez the attachment to check script running state
SceneObjectGroup reRezzedSo = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
// Wait for chat to signal rezzed script has been started.
m_chatEvent.WaitOne(60000);
TaskInventoryItem reRezzedScriptItem = reRezzedSo.RootPart.Inventory.GetInventoryItem(scriptTaskItem.Name);
IScriptModule xengine = scene.RequestModuleInterface<IScriptModule>();
Assert.That(xengine.GetScriptState(reRezzedScriptItem.ItemID), Is.True);
// Console.WriteLine(soXml.OuterXml);
}
/// <summary>
@@ -239,24 +450,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
UUID userId = TestHelpers.ParseTail(0x1);
UUID attItemId = TestHelpers.ParseTail(0x2);
UUID attAssetId = TestHelpers.ParseTail(0x3);
string attName = "att";
Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
UserAccountHelpers.CreateUserWithInventory(scene, userId);
InventoryItemBase attItem
= UserInventoryHelpers.CreateInventoryItem(
scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
acd.Appearance = new AvatarAppearance();
acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
SceneObjectGroup rezzedAtt = presence.GetAttachments()[0];
scene.IncomingCloseAgent(presence.UUID);
scene.IncomingCloseAgent(presence.UUID, false);
// Check that we can't retrieve this attachment from the scene.
Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);
@@ -268,17 +473,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
UUID userId = TestHelpers.ParseTail(0x1);
UUID attItemId = TestHelpers.ParseTail(0x2);
UUID attAssetId = TestHelpers.ParseTail(0x3);
string attName = "att";
Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
UserAccountHelpers.CreateUserWithInventory(scene, userId);
InventoryItemBase attItem
= UserInventoryHelpers.CreateInventoryItem(
scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
acd.Appearance = new AvatarAppearance();
acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
@@ -288,7 +487,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
Assert.That(attachments.Count, Is.EqualTo(1));
SceneObjectGroup attSo = attachments[0];
Assert.That(attSo.Name, Is.EqualTo(attName));
Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
Assert.That(attSo.IsAttachment);
Assert.That(attSo.UsesPhysics, Is.False);
@@ -298,9 +497,125 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments();
Assert.That(retreivedAttachments.Count, Is.EqualTo(1));
Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest));
Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItemId));
Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attAssetId));
Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItem.ID));
Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attItem.AssetID));
Assert.That(presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
}
[Test]
public void TestUpdateAttachmentPosition()
{
TestHelpers.InMethod();
Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
acd.Appearance = new AvatarAppearance();
acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, acd);
SceneObjectGroup attSo = sp.GetAttachments()[0];
Vector3 newPosition = new Vector3(1, 2, 4);
scene.SceneGraph.UpdatePrimGroupPosition(attSo.LocalId, newPosition, sp.ControllingClient);
Assert.That(attSo.AbsolutePosition, Is.EqualTo(sp.AbsolutePosition));
Assert.That(attSo.RootPart.AttachedPos, Is.EqualTo(newPosition));
}
[Test]
public void TestSameSimulatorNeighbouringRegionsTeleport()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
AttachmentsModule attModA = new AttachmentsModule();
AttachmentsModule attModB = new AttachmentsModule();
EntityTransferModule etmA = new EntityTransferModule();
EntityTransferModule etmB = new EntityTransferModule();
LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
IConfigSource config = new IniConfigSource();
IConfig modulesConfig = config.AddConfig("Modules");
modulesConfig.Set("EntityTransferModule", etmA.Name);
modulesConfig.Set("SimulationServices", lscm.Name);
IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
// In order to run a single threaded regression test we do not want the entity transfer module waiting
// for a callback from the destination scene before removing its avatar data.
entityTransferConfig.Set("wait_for_callback", false);
modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule");
SceneHelpers sh = new SceneHelpers();
TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000);
SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
SceneHelpers.SetupSceneModules(
sceneA, config, new CapabilitiesModule(), etmA, attModA, new BasicInventoryAccessModule());
SceneHelpers.SetupSceneModules(
sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule());
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1);
ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, ua1.PrincipalID, sh.SceneManager);
beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32);
InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20);
sceneA.AttachmentsModule.RezSingleAttachmentFromInventory(
beforeTeleportSp, attItem.ID, (uint)AttachmentPoint.Chest);
Vector3 teleportPosition = new Vector3(10, 11, 12);
Vector3 teleportLookAt = new Vector3(20, 21, 22);
sceneA.RequestTeleportLocation(
beforeTeleportSp.ControllingClient,
sceneB.RegionInfo.RegionHandle,
teleportPosition,
teleportLookAt,
(uint)TeleportFlags.ViaLocation);
((TestClient)beforeTeleportSp.ControllingClient).CompleteTeleportClientSide();
// Check attachments have made it into sceneB
ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID);
// This is appearance data, as opposed to actually rezzed attachments
List<AvatarAttachment> sceneBAttachments = afterTeleportSceneBSp.Appearance.GetAttachments();
Assert.That(sceneBAttachments.Count, Is.EqualTo(1));
Assert.That(sceneBAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest));
Assert.That(sceneBAttachments[0].ItemID, Is.EqualTo(attItem.ID));
Assert.That(sceneBAttachments[0].AssetID, Is.EqualTo(attItem.AssetID));
Assert.That(afterTeleportSceneBSp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
// This is the actual attachment
List<SceneObjectGroup> actualSceneBAttachments = afterTeleportSceneBSp.GetAttachments();
Assert.That(actualSceneBAttachments.Count, Is.EqualTo(1));
SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0];
Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name));
Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest));
Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1));
// Check attachments have been removed from sceneA
ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(ua1.PrincipalID);
// Since this is appearance data, it is still present on the child avatar!
List<AvatarAttachment> sceneAAttachments = afterTeleportSceneASp.Appearance.GetAttachments();
Assert.That(sceneAAttachments.Count, Is.EqualTo(1));
Assert.That(afterTeleportSceneASp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
// This is the actual attachment, which should no longer exist
List<SceneObjectGroup> actualSceneAAttachments = afterTeleportSceneASp.GetAttachments();
Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0));
Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0));
}
// I'm commenting this test because scene setup NEEDS InventoryService to
@@ -326,4 +641,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
// Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects");
// }
}
}
}

View File

@@ -66,11 +66,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
scene.RegisterModuleInterface<IAvatarFactoryModule>(this);
scene.EventManager.OnNewClient += SubscribeToClientEvents;
IConfig sconfig = config.Configs["Startup"];
if (sconfig != null)
IConfig appearanceConfig = config.Configs["Appearance"];
if (appearanceConfig != null)
{
m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
m_savetime = Convert.ToInt32(appearanceConfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
m_sendtime = Convert.ToInt32(appearanceConfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
// m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
}
@@ -128,7 +128,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
/// <param name="visualParam"></param>
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams)
{
// m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId);
// m_log.DebugFormat(
// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
// sp.Name, textureEntry, visualParams);
// TODO: This is probably not necessary any longer, just assume the
// textureEntry set implies that the appearance transaction is complete

View File

@@ -37,7 +37,7 @@ using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Statistics;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;

View File

@@ -96,7 +96,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups
scene.EventManager.OnNewClient += OnNewClient;
scene.EventManager.OnClientClosed += OnClientClosed;
scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
// scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
}
public void PostInitialise()
@@ -133,7 +133,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups
private void OnNewClient(IClientAPI client)
{
// Subscribe to instant messages
client.OnInstantMessage += OnInstantMessage;
// client.OnInstantMessage += OnInstantMessage;
client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
lock (m_ClientMap)
@@ -171,15 +171,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups
ActiveGroupTitle);
}
private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
{
}
// private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
// {
// }
private void OnGridInstantMessage(GridInstantMessage msg)
{
// Trigger the above event handler
OnInstantMessage(null, msg);
}
// private void OnGridInstantMessage(GridInstantMessage msg)
// {
// // Trigger the above event handler
// OnInstantMessage(null, msg);
// }
private void HandleUUIDGroupNameRequest(UUID id,IClientAPI remote_client)
{

View File

@@ -137,13 +137,15 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
foreach (Scene scene in m_Scenes)
{
// m_log.DebugFormat(
// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
// toAgentID.ToString(), scene.RegionInfo.RegionName);
ScenePresence sp = scene.GetScenePresence(toAgentID);
if (sp != null && !sp.IsChildAgent)
{
// Local message
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID);
sp.ControllingClient.SendInstantMessage(im);
// Message sent
@@ -155,13 +157,15 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
// try child avatar second
foreach (Scene scene in m_Scenes)
{
// m_log.DebugFormat(
// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
m_log.DebugFormat(
"[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
ScenePresence sp = scene.GetScenePresence(toAgentID);
if (sp != null)
{
// Local message
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID);
sp.ControllingClient.SendInstantMessage(im);
// Message sent
@@ -170,10 +174,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
}
}
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
SendGridInstantMessageViaXMLRPC(im, result);
m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
return;
SendGridInstantMessageViaXMLRPC(im, result);
}
private void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)

View File

@@ -48,7 +48,7 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{
[TestFixture]
public class InventoryArchiveTestCase
public class InventoryArchiveTestCase : OpenSimTestCase
{
protected ManualResetEvent mre = new ManualResetEvent(false);
@@ -84,8 +84,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
protected string m_coaItemName = "Coalesced Item";
[SetUp]
public virtual void SetUp()
public override void SetUp()
{
base.SetUp();
m_iarStream = new MemoryStream(m_iarStreamBytes);
}

View File

@@ -350,38 +350,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID));
}
/// <summary>
/// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
/// an account exists with the same name as the creator, though not the same id.
/// </summary>
[Test]
public void TestLoadIarV0_1SameNameCreator()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire");
m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
InventoryItemBase foundItem1
= InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
Assert.That(
foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),
"Loaded item non-uuid creator doesn't match original");
Assert.That(
foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),
"Loaded item uuid creator doesn't match original");
Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID),
"Loaded item owner doesn't match inventory reciever");
AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
string xmlData = Utils.BytesToString(asset1.Data);
SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID));
}
// /// <summary>
// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
// /// an account exists with the same name as the creator, though not the same id.
// /// </summary>
// [Test]
// public void TestLoadIarV0_1SameNameCreator()
// {
// TestHelpers.InMethod();
// TestHelpers.EnableLogging();
//
// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire");
//
// m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
// InventoryItemBase foundItem1
// = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
//
// Assert.That(
// foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),
// "Loaded item non-uuid creator doesn't match original");
// Assert.That(
// foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),
// "Loaded item uuid creator doesn't match original");
// Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID),
// "Loaded item owner doesn't match inventory reciever");
//
// AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
// string xmlData = Utils.BytesToString(asset1.Data);
// SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
//
// Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID));
// }
/// <summary>
/// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where

View File

@@ -297,7 +297,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
});
}
}
else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined)
else if (
im.dialog == (byte)InstantMessageDialog.InventoryDeclined
|| im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined)
{
// Here, the recipient is local and we can assume that the
// inventory is loaded. Courtesy of the above bulk update,

View File

@@ -644,7 +644,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// an agent cannot teleport back to this region if it has teleported away.
Thread.Sleep(2000);
sp.Scene.IncomingCloseAgent(sp.UUID);
sp.Scene.IncomingCloseAgent(sp.UUID, false);
}
else
{
@@ -709,6 +709,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.CallbackURI, region.RegionName);
}
/// <summary>
/// Clean up operations once an agent has moved away through cross or teleport.
/// </summary>
/// <param name='sp'></param>
/// <param name='logout'></param>
protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout)
{
if (sp.Scene.AttachmentsModule != null)
@@ -1666,6 +1671,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#endregion
#region Object Transfers
/// <summary>
/// Move the given scene object into a new region depending on which region its absolute position has moved
/// into.
@@ -1967,35 +1973,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return successYN;
}
protected bool CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent)
/// <summary>
/// Cross the attachments for an avatar into the destination region.
/// </summary>
/// <remarks>
/// This is only invoked for simulators released prior to April 2011. Versions of OpenSimulator since then
/// transfer attachments in one go as part of the ChildAgentDataUpdate data passed in the update agent call.
/// </remarks>
/// <param name='destination'></param>
/// <param name='sp'></param>
/// <param name='silent'></param>
protected void CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent)
{
List<SceneObjectGroup> m_attachments = sp.GetAttachments();
List<SceneObjectGroup> attachments = sp.GetAttachments();
// Validate
// foreach (SceneObjectGroup gobj in m_attachments)
// {
// if (gobj == null || gobj.IsDeleted)
// return false;
// }
// m_log.DebugFormat(
// "[ENTITY TRANSFER MODULE]: Crossing {0} attachments into {1} for {2}",
// m_attachments.Count, destination.RegionName, sp.Name);
foreach (SceneObjectGroup gobj in m_attachments)
foreach (SceneObjectGroup gobj in attachments)
{
// If the prim group is null then something must have happened to it!
if (gobj != null && !gobj.IsDeleted)
{
// Set the parent localID to 0 so it transfers over properly.
gobj.RootPart.SetParentLocalId(0);
gobj.AbsolutePosition = gobj.RootPart.AttachedPos;
gobj.IsAttachment = false;
SceneObjectGroup clone = (SceneObjectGroup)gobj.CloneForNewScene();
clone.RootPart.GroupPosition = gobj.RootPart.AttachedPos;
clone.IsAttachment = false;
//gobj.RootPart.LastOwnerID = gobj.GetFromAssetID();
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName);
CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, gobj, silent);
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}",
clone.UUID, destination.RegionName);
CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, clone, silent);
}
}
sp.ClearAttachments();
return true;
}
#endregion

View File

@@ -204,8 +204,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
m_Scene.AssetService.Store(asset);
m_Scene.CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
m_Scene.CreateNewInventoryItem(
remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
}
else
{

View File

@@ -39,7 +39,7 @@ using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.CoreModules.Avatar.Attachments
namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BinaryLoggingModule")]
public class BinaryLoggingModule : INonSharedRegionModule

View File

@@ -0,0 +1,161 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.IO;
using System.Text;
using log4net;
namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
{
/// <summary>
/// Class for writing a high performance, high volume log file.
/// Sometimes, to debug, one has a high volume logging to do and the regular
/// log file output is not appropriate.
/// Create a new instance with the parameters needed and
/// call Write() to output a line. Call Close() when finished.
/// If created with no parameters, it will not log anything.
/// </summary>
public class LogWriter : IDisposable
{
public bool Enabled { get; private set; }
private string m_logDirectory = ".";
private int m_logMaxFileTimeMin = 5; // 5 minutes
public String LogFileHeader { get; set; }
private StreamWriter m_logFile = null;
private TimeSpan m_logFileLife;
private DateTime m_logFileEndTime;
private Object m_logFileWriteLock = new Object();
// set externally when debugging. If let 'null', this does not write any error messages.
public ILog ErrorLogger = null;
private string LogHeader = "[LOG WRITER]";
/// <summary>
/// Create a log writer that will not write anything. Good for when not enabled
/// but the write statements are still in the code.
/// </summary>
public LogWriter()
{
Enabled = false;
m_logFile = null;
}
/// <summary>
/// Create a log writer instance.
/// </summary>
/// <param name="dir">The directory to create the log file in. May be 'null' for default.</param>
/// <param name="headr">The characters that begin the log file name. May be 'null' for default.</param>
/// <param name="maxFileTime">Maximum age of a log file in minutes. If zero, will set default.</param>
public LogWriter(string dir, string headr, int maxFileTime)
{
m_logDirectory = dir == null ? "." : dir;
LogFileHeader = headr == null ? "log-" : headr;
m_logMaxFileTimeMin = maxFileTime;
if (m_logMaxFileTimeMin < 1)
m_logMaxFileTimeMin = 5;
m_logFileLife = new TimeSpan(0, m_logMaxFileTimeMin, 0);
m_logFileEndTime = DateTime.Now + m_logFileLife;
Enabled = true;
}
public void Dispose()
{
this.Close();
}
public void Close()
{
Enabled = false;
if (m_logFile != null)
{
m_logFile.Close();
m_logFile.Dispose();
m_logFile = null;
}
}
public void Write(string line, params object[] args)
{
if (!Enabled) return;
Write(String.Format(line, args));
}
public void Write(string line)
{
if (!Enabled) return;
try
{
lock (m_logFileWriteLock)
{
DateTime now = DateTime.Now;
if (m_logFile == null || now > m_logFileEndTime)
{
if (m_logFile != null)
{
m_logFile.Close();
m_logFile.Dispose();
m_logFile = null;
}
// First log file or time has expired, start writing to a new log file
m_logFileEndTime = now + m_logFileLife;
string path = (m_logDirectory.Length > 0 ? m_logDirectory
+ System.IO.Path.DirectorySeparatorChar.ToString() : "")
+ String.Format("{0}{1}.log", LogFileHeader, now.ToString("yyyyMMddHHmmss"));
m_logFile = new StreamWriter(File.Open(path, FileMode.Append, FileAccess.Write));
}
if (m_logFile != null)
{
StringBuilder buff = new StringBuilder(line.Length + 25);
buff.Append(now.ToString("yyyyMMddHHmmssfff"));
// buff.Append(now.ToString("yyyyMMddHHmmss"));
buff.Append(",");
buff.Append(line);
buff.Append("\r\n");
m_logFile.Write(buff.ToString());
}
}
}
catch (Exception e)
{
if (ErrorLogger != null)
{
ErrorLogger.ErrorFormat("{0}: FAILURE WRITING TO LOGFILE: {1}", LogHeader, e);
}
Enabled = false;
}
return;
}
}
}

View File

@@ -40,6 +40,7 @@ using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;

View File

@@ -79,7 +79,6 @@
<RegionModule id="AuthenticationServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Authentication.AuthenticationServiceInConnectorModule" />
<RegionModule id="AccessModule" type="OpenSim.Region.CoreModules.World.AccessModule" /> \
<RegionModule id="MapImageModule" type="OpenSim.Region.CoreModules.World.LegacyMap.MapImageModule" /> \
<RegionModule id="Warp3DImageModule" type="OpenSim.Region.CoreModules.World.Warp3DMap.Warp3DImageModule" /> \
</Extension>

View File

@@ -49,6 +49,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
public const int DISP_EXPIRE = 1;
public const int DISP_TEMP = 2;
/// <summary>
/// If true then where possible dynamic textures are reused.
/// </summary>
public bool ReuseTextures { get; set; }
private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>();
private Dictionary<string, IDynamicTextureRender> RenderPlugins =
@@ -56,6 +61,15 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>();
/// <summary>
/// Record dynamic textures that we can reuse for a given data and parameter combination rather than
/// regenerate.
/// </summary>
/// <remarks>
/// Key is string.Format("{0}{1}", data
/// </remarks>
private Cache m_reuseableDynamicTextures;
#region IDynamicTextureManager Members
public void RegisterRender(string handleType, IDynamicTextureRender render)
@@ -71,7 +85,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
/// </summary>
/// <param name="id"></param>
/// <param name="data"></param>
public void ReturnData(UUID id, byte[] data)
/// <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;
@@ -88,7 +103,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
if (RegisteredScenes.ContainsKey(updater.SimUUID))
{
Scene scene = RegisteredScenes[updater.SimUUID];
updater.DataReceived(data, scene);
UUID newTextureID = updater.DataReceived(data, scene);
if (ReuseTextures && isReuseable && !updater.BlendWithOldTexture)
m_reuseableDynamicTextures.Store(
GenerateReusableTextureKey(updater.BodyData, updater.Params), newTextureID);
}
}
@@ -167,22 +186,61 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data,
string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face)
{
if (RenderPlugins.ContainsKey(contentType))
{
DynamicTextureUpdater updater = new DynamicTextureUpdater();
updater.SimUUID = simID;
updater.PrimID = primID;
updater.ContentType = contentType;
updater.BodyData = data;
updater.UpdateTimer = updateTimer;
updater.UpdaterID = UUID.Random();
updater.Params = extraParams;
updater.BlendWithOldTexture = SetBlending;
updater.FrontAlpha = AlphaValue;
updater.Face = face;
updater.Url = "Local image";
updater.Disp = disp;
if (!RenderPlugins.ContainsKey(contentType))
return UUID.Zero;
Scene scene;
RegisteredScenes.TryGetValue(simID, out scene);
if (scene == null)
return UUID.Zero;
SceneObjectPart part = scene.GetSceneObjectPart(primID);
if (part == null)
return UUID.Zero;
// If we want to reuse dynamic textures then we have to ignore any request from the caller to expire
// them.
if (ReuseTextures)
disp = disp & ~DISP_EXPIRE;
DynamicTextureUpdater updater = new DynamicTextureUpdater();
updater.SimUUID = simID;
updater.PrimID = primID;
updater.ContentType = contentType;
updater.BodyData = data;
updater.UpdateTimer = updateTimer;
updater.UpdaterID = UUID.Random();
updater.Params = extraParams;
updater.BlendWithOldTexture = SetBlending;
updater.FrontAlpha = AlphaValue;
updater.Face = face;
updater.Url = "Local image";
updater.Disp = disp;
object objReusableTextureUUID = null;
if (ReuseTextures && !updater.BlendWithOldTexture)
{
string reuseableTextureKey = GenerateReusableTextureKey(data, extraParams);
objReusableTextureUUID = m_reuseableDynamicTextures.Get(reuseableTextureKey);
if (objReusableTextureUUID != null)
{
// If something else has removed this temporary asset from the cache, detect and invalidate
// our cached uuid.
if (scene.AssetService.GetMetadata(objReusableTextureUUID.ToString()) == null)
{
m_reuseableDynamicTextures.Invalidate(reuseableTextureKey);
objReusableTextureUUID = null;
}
}
}
// We cannot reuse a dynamic texture if the data is going to be blended with something already there.
if (objReusableTextureUUID == null)
{
lock (Updaters)
{
if (!Updaters.ContainsKey(updater.UpdaterID))
@@ -192,10 +250,20 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
}
RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
return updater.UpdaterID;
}
return UUID.Zero;
else
{
// 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);
}
return updater.UpdaterID;
}
private string GenerateReusableTextureKey(string data, string extraParams)
{
return string.Format("{0}{1}", data, extraParams);
}
public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize,
@@ -215,6 +283,10 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
public void Initialise(Scene scene, IConfigSource config)
{
IConfig texturesConfig = config.Configs["Textures"];
if (texturesConfig != null)
ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false);
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
{
RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
@@ -224,6 +296,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
public void PostInitialise()
{
if (ReuseTextures)
{
m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative);
m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0);
}
}
public void Close()
@@ -268,10 +345,61 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
BodyData = null;
}
/// <summary>
/// Update the given part with the new texture.
/// </summary>
/// <returns>
/// The old texture UUID.
/// </returns>
public UUID UpdatePart(SceneObjectPart part, UUID textureID)
{
UUID oldID;
lock (part)
{
// mostly keep the values from before
Primitive.TextureEntry tmptex = part.Shape.Textures;
// FIXME: Need to return the appropriate ID if only a single face is replaced.
oldID = tmptex.DefaultTexture.TextureID;
if (Face == ALL_SIDES)
{
oldID = tmptex.DefaultTexture.TextureID;
tmptex.DefaultTexture.TextureID = textureID;
}
else
{
try
{
Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
texface.TextureID = textureID;
tmptex.FaceTextures[Face] = texface;
}
catch (Exception)
{
tmptex.DefaultTexture.TextureID = textureID;
}
}
// I'm pretty sure we always want to force this to true
// I'm pretty sure noone whats to set fullbright true if it wasn't true before.
// tmptex.DefaultTexture.Fullbright = true;
part.UpdateTextureEntry(tmptex.GetBytes());
}
return oldID;
}
/// <summary>
/// Called once new texture data has been received for this updater.
/// </summary>
public void DataReceived(byte[] data, Scene scene)
/// <param name="data"></param>
/// <param name="scene"></param>
/// <param name="isReuseable">True if the data given is reuseable.</param>
/// <returns>The asset UUID given to the incoming data.</returns>
public UUID DataReceived(byte[] data, Scene scene)
{
SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
@@ -281,7 +409,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url);
scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,
0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false);
return;
return UUID.Zero;
}
byte[] assetData = null;
@@ -323,52 +452,23 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
cacheLayerDecode = null;
}
UUID oldID = UUID.Zero;
lock (part)
{
// mostly keep the values from before
Primitive.TextureEntry tmptex = part.Shape.Textures;
// remove the old asset from the cache
oldID = tmptex.DefaultTexture.TextureID;
if (Face == ALL_SIDES)
{
tmptex.DefaultTexture.TextureID = asset.FullID;
}
else
{
try
{
Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
texface.TextureID = asset.FullID;
tmptex.FaceTextures[Face] = texface;
}
catch (Exception)
{
tmptex.DefaultTexture.TextureID = asset.FullID;
}
}
// I'm pretty sure we always want to force this to true
// I'm pretty sure noone whats to set fullbright true if it wasn't true before.
// tmptex.DefaultTexture.Fullbright = true;
part.UpdateTextureEntry(tmptex.GetBytes());
}
UUID oldID = UpdatePart(part, asset.FullID);
if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0))
{
if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString());
if (oldAsset == null)
oldAsset = scene.AssetService.Get(oldID.ToString());
if (oldAsset != null)
{
if (oldAsset.Temporary == true)
if (oldAsset.Temporary)
{
scene.AssetService.Delete(oldID.ToString());
}
}
}
return asset.FullID;
}
private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)

View File

@@ -41,13 +41,39 @@ using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
{
/// <summary>
/// Data describing an external URL set up by a script.
/// </summary>
public class UrlData
{
/// <summary>
/// Scene object part hosting the script
/// </summary>
public UUID hostID;
/// <summary>
/// The item ID of the script that requested the URL.
/// </summary>
public UUID itemID;
/// <summary>
/// The script engine that runs the script.
/// </summary>
public IScriptModule engine;
/// <summary>
/// The generated URL.
/// </summary>
public string url;
/// <summary>
/// The random UUID component of the generated URL.
/// </summary>
public UUID urlcode;
/// <summary>
/// The external requests currently being processed or awaiting retrieval for this URL.
/// </summary>
public Dictionary<UUID, RequestData> requests;
}
@@ -58,25 +84,40 @@ 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;
public string uri;
}
/// <summary>
/// This module provides external URLs for in-world scripts.
/// </summary>
public class UrlModule : ISharedRegionModule, IUrlModule
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private Dictionary<UUID, UrlData> m_RequestMap =
new Dictionary<UUID, UrlData>();
private Dictionary<string, UrlData> m_UrlMap =
new Dictionary<string, UrlData>();
/// <summary>
/// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the request ID
/// randomly generated when a request is received for this URL.
/// </summary>
/// <remarks>
/// Manipulation or retrieval from this dictionary must be locked on m_UrlMap to preserve consistency with
/// m_UrlMap
/// </remarks>
private Dictionary<UUID, UrlData> m_RequestMap = new Dictionary<UUID, UrlData>();
/// <summary>
/// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the full URL
/// </summary>
private Dictionary<string, UrlData> m_UrlMap = new Dictionary<string, UrlData>();
/// <summary>
/// Maximum number of external urls that can be set up by this module.
/// </summary>
private int m_TotalUrls = 100;
private uint https_port = 0;
@@ -103,10 +144,14 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
{
m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName);
bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false);
if (ssl_enabled)
{
https_port = (uint) config.Configs["Network"].GetInt("https_port",0);
}
IConfig llFunctionsConfig = config.Configs["LL-Functions"];
if (llFunctionsConfig != null)
m_TotalUrls = llFunctionsConfig.GetInt("max_external_urls_per_simulator", m_TotalUrls);
}
public void PostInitialise()
@@ -217,7 +262,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
urlData.urlcode = urlcode;
urlData.requests = new Dictionary<UUID, RequestData>();
m_UrlMap[url] = urlData;
string uri = "/lslhttps/" + urlcode.ToString() + "/";
@@ -259,41 +303,65 @@ 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)
{
if (m_RequestMap.ContainsKey(request))
lock (m_UrlMap)
{
UrlData urlData = m_RequestMap[request];
urlData.requests[request].responseCode = status;
urlData.requests[request].responseBody = body;
//urlData.requests[request].ev.Set();
urlData.requests[request].requestDone =true;
}
else
{
m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString());
if (m_RequestMap.ContainsKey(request))
{
UrlData urlData = m_RequestMap[request];
urlData.requests[request].responseCode = status;
urlData.requests[request].responseBody = body;
//urlData.requests[request].ev.Set();
urlData.requests[request].requestDone =true;
}
else
{
m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString());
}
}
}
public string GetHttpHeader(UUID requestId, string header)
{
if (m_RequestMap.ContainsKey(requestId))
lock (m_UrlMap)
{
UrlData urlData=m_RequestMap[requestId];
string value;
if (urlData.requests[requestId].headers.TryGetValue(header,out value))
return value;
}
else
{
m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId);
if (m_RequestMap.ContainsKey(requestId))
{
UrlData urlData = m_RequestMap[requestId];
string value;
if (urlData.requests[requestId].headers.TryGetValue(header, out value))
return value;
}
else
{
m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId);
}
}
return String.Empty;
}
public int GetFreeUrls()
{
return m_TotalUrls - m_UrlMap.Count;
lock (m_UrlMap)
return m_TotalUrls - m_UrlMap.Count;
}
public void ScriptRemoved(UUID itemID)
@@ -332,6 +400,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
{
RemoveUrl(url.Value);
removeURLs.Add(url.Key);
foreach (UUID req in url.Value.requests.Keys)
m_RequestMap.Remove(req);
}
@@ -342,145 +411,166 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
}
}
private void RemoveUrl(UrlData data)
{
m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/");
m_HttpServer.RemoveHTTPHandler("", "/lslhttp/" + data.urlcode.ToString() + "/");
}
private Hashtable NoEvents(UUID requestID, UUID sessionID)
{
Hashtable response = new Hashtable();
UrlData url;
lock (m_RequestMap)
UrlData urlData;
lock (m_UrlMap)
{
// We need to return a 404 here in case the request URL was removed at exactly the same time that a
// request was made. In this case, the request thread can outrace llRemoveURL() and still be polling
// for the request ID.
if (!m_RequestMap.ContainsKey(requestID))
return response;
url = m_RequestMap[requestID];
}
if (System.Environment.TickCount - url.requests[requestID].startTime > 25000)
{
response["int_response_code"] = 500;
response["str_response_string"] = "Script timeout";
response["content_type"] = "text/plain";
response["keepalive"] = false;
response["reusecontext"] = false;
//remove from map
lock (url)
{
url.requests.Remove(requestID);
m_RequestMap.Remove(requestID);
response["int_response_code"] = 404;
response["str_response_string"] = "";
response["keepalive"] = false;
response["reusecontext"] = false;
return response;
}
return response;
urlData = m_RequestMap[requestID];
if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000)
{
response["int_response_code"] = 500;
response["str_response_string"] = "Script timeout";
response["content_type"] = "text/plain";
response["keepalive"] = false;
response["reusecontext"] = false;
//remove from map
urlData.requests.Remove(requestID);
m_RequestMap.Remove(requestID);
return response;
}
}
return response;
}
private bool HasEvents(UUID requestID, UUID sessionID)
{
UrlData url=null;
lock (m_RequestMap)
lock (m_UrlMap)
{
// We return true here because an external URL request that happened at the same time as an llRemoveURL()
// can still make it through to HttpRequestHandler(). That will return without setting up a request
// when it detects that the URL has been removed. The poller, however, will continue to ask for
// events for that request, so here we will signal that there are events and in GetEvents we will
// return a 404.
if (!m_RequestMap.ContainsKey(requestID))
{
return false;
return true;
}
url = m_RequestMap[requestID];
if (!url.requests.ContainsKey(requestID))
UrlData urlData = m_RequestMap[requestID];
if (!urlData.requests.ContainsKey(requestID))
{
return false;
return true;
}
// Trigger return of timeout response.
if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000)
{
return true;
}
return urlData.requests[requestID].requestDone;
}
if (System.Environment.TickCount-url.requests[requestID].startTime>25000)
{
return true;
}
if (url.requests[requestID].requestDone)
return true;
else
return false;
}
private Hashtable GetEvents(UUID requestID, UUID sessionID, string request)
{
UrlData url = null;
RequestData requestData = null;
Hashtable response;
lock (m_RequestMap)
lock (m_UrlMap)
{
UrlData url = null;
RequestData requestData = null;
if (!m_RequestMap.ContainsKey(requestID))
return NoEvents(requestID,sessionID);
return NoEvents(requestID, sessionID);
url = m_RequestMap[requestID];
requestData = url.requests[requestID];
}
if (!requestData.requestDone)
return NoEvents(requestID,sessionID);
Hashtable response = new Hashtable();
if (!requestData.requestDone)
return NoEvents(requestID, sessionID);
if (System.Environment.TickCount - requestData.startTime > 25000)
{
response["int_response_code"] = 500;
response["str_response_string"] = "Script timeout";
response["content_type"] = "text/plain";
response = new Hashtable();
if (System.Environment.TickCount - requestData.startTime > 25000)
{
response["int_response_code"] = 500;
response["str_response_string"] = "Script timeout";
response["content_type"] = "text/plain";
response["keepalive"] = false;
response["reusecontext"] = false;
return response;
}
//put response
response["int_response_code"] = requestData.responseCode;
response["str_response_string"] = requestData.responseBody;
response["content_type"] = requestData.responseType;
// response["content_type"] = "text/plain";
response["keepalive"] = false;
response["reusecontext"] = false;
return response;
}
//put response
response["int_response_code"] = requestData.responseCode;
response["str_response_string"] = requestData.responseBody;
response["content_type"] = "text/plain";
response["keepalive"] = false;
response["reusecontext"] = false;
//remove from map
lock (url)
{
//remove from map
url.requests.Remove(requestID);
m_RequestMap.Remove(requestID);
}
return response;
}
public void HttpRequestHandler(UUID requestID, Hashtable request)
{
lock (request)
{
string uri = request["uri"].ToString();
bool is_ssl = uri.Contains("lslhttps");
string uri = request["uri"].ToString();
bool is_ssl = uri.Contains("lslhttps");
try
{
Hashtable headers = (Hashtable)request["headers"];
try
{
Hashtable headers = (Hashtable)request["headers"];
// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
int pos1 = uri.IndexOf("/");// /lslhttp
int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp/<UUID>/
string uri_tmp = uri.Substring(0, pos3 + 1);
//HTTP server code doesn't provide us with QueryStrings
string pathInfo;
string queryString;
queryString = "";
int pos1 = uri.IndexOf("/");// /lslhttp
int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp/<UUID>/
string uri_tmp = uri.Substring(0, pos3 + 1);
//HTTP server code doesn't provide us with QueryStrings
string pathInfo;
string queryString;
queryString = "";
pathInfo = uri.Substring(pos3);
pathInfo = uri.Substring(pos3);
UrlData url = null;
if (!is_ssl)
url = m_UrlMap["http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp];
UrlData urlData = null;
lock (m_UrlMap)
{
string url;
if (is_ssl)
url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp;
else
url = m_UrlMap["https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp];
url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp;
// Avoid a race - the request URL may have been released via llRequestUrl() whilst this
// request was being processed.
if (!m_UrlMap.TryGetValue(url, out urlData))
return;
//for llGetHttpHeader support we need to store original URI here
//to make x-path-info / x-query-string / x-script-url / x-remote-ip headers
@@ -500,6 +590,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
string value = (string)header.Value;
requestData.headers.Add(key, value);
}
foreach (DictionaryEntry de in request)
{
if (de.Key.ToString() == "querystringkeys")
@@ -513,11 +604,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
queryString = queryString + key + "=" + val + "&";
}
}
if (queryString.Length > 1)
queryString = queryString.Substring(0, queryString.Length - 1);
}
}
//if this machine is behind DNAT/port forwarding, currently this is being
@@ -525,34 +615,23 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"];
requestData.headers["x-path-info"] = pathInfo;
requestData.headers["x-query-string"] = queryString;
requestData.headers["x-script-url"] = url.url;
//requestData.ev = new ManualResetEvent(false);
lock (url.requests)
{
url.requests.Add(requestID, requestData);
}
lock (m_RequestMap)
{
//add to request map
m_RequestMap.Add(requestID, url);
}
url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() });
//send initial response?
// Hashtable response = new Hashtable();
return;
requestData.headers["x-script-url"] = urlData.url;
urlData.requests.Add(requestID, requestData);
m_RequestMap.Add(requestID, urlData);
}
catch (Exception we)
{
//Hashtable response = new Hashtable();
m_log.Warn("[HttpRequestHandler]: http-in request failed");
m_log.Warn(we.Message);
m_log.Warn(we.StackTrace);
}
urlData.engine.PostScriptEvent(
urlData.itemID,
"http_request",
new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() });
}
catch (Exception we)
{
//Hashtable response = new Hashtable();
m_log.Warn("[HttpRequestHandler]: http-in request failed");
m_log.Warn(we.Message);
m_log.Warn(we.StackTrace);
}
}
@@ -561,4 +640,4 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
ScriptRemoved(itemID);
}
}
}
}

View File

@@ -67,12 +67,18 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
return true;
}
// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
// {
// // We don't support conversion of body data.
// return false;
// }
public byte[] ConvertUrl(string url, string extraParams)
{
return null;
}
public byte[] ConvertStream(Stream data, string extraParams)
public byte[] ConvertData(string bodyData, string extraParams)
{
return null;
}
@@ -236,9 +242,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
stream.Close();
}
}
m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}",
imageJ2000.Length, state.RequestID);
m_textureManager.ReturnData(state.RequestID, imageJ2000);
m_textureManager.ReturnData(state.RequestID, imageJ2000, false);
}
#region Nested type: RequestState

View File

@@ -0,0 +1,294 @@
/*
* 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 NUnit.Framework;
using OpenMetaverse;
using OpenMetaverse.Assets;
using OpenSim.Framework;
using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
using OpenSim.Region.CoreModules.Scripting.VectorRender;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
{
[TestFixture]
public class VectorRenderModuleTests : OpenSimTestCase
{
Scene m_scene;
DynamicTextureModule m_dtm;
VectorRenderModule m_vrm;
private void SetupScene(bool reuseTextures)
{
m_scene = new SceneHelpers().SetupScene();
m_dtm = new DynamicTextureModule();
m_dtm.ReuseTextures = reuseTextures;
m_vrm = new VectorRenderModule();
SceneHelpers.SetupSceneModules(m_scene, m_dtm, m_vrm);
}
[Test]
public void TestDraw()
{
TestHelpers.InMethod();
SetupScene(false);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
"PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
"",
0);
Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestRepeatSameDraw()
{
TestHelpers.InMethod();
string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
SetupScene(false);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestRepeatSameDrawDifferentExtraParams()
{
TestHelpers.InMethod();
string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
SetupScene(false);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"alpha:250",
0);
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestRepeatSameDrawContainingImage()
{
TestHelpers.InMethod();
string dtText
= "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
SetupScene(false);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestDrawReusingTexture()
{
TestHelpers.InMethod();
SetupScene(true);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
"PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
"",
0);
Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestRepeatSameDrawReusingTexture()
{
TestHelpers.InMethod();
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,
"",
0);
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestRepeatSameDrawDifferentExtraParamsReusingTexture()
{
TestHelpers.InMethod();
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,
"",
0);
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"alpha:250",
0);
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestRepeatSameDrawContainingImageReusingTexture()
{
TestHelpers.InMethod();
string dtText
= "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
SetupScene(true);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
}
}

View File

@@ -30,6 +30,7 @@ using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using Nini.Config;
using OpenMetaverse;
@@ -47,7 +48,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string m_name = "VectorRenderModule";
private Scene m_scene;
private IDynamicTextureManager m_textureManager;
private Graphics m_graph;
@@ -61,12 +61,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
public string GetContentType()
{
return ("vector");
return "vector";
}
public string GetName()
{
return m_name;
return Name;
}
public bool SupportsAsynchronous()
@@ -74,14 +74,26 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
return true;
}
// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
// {
// string[] lines = GetLines(bodyData);
// return lines.Any((str, r) => str.StartsWith("Image"));
// }
public byte[] ConvertUrl(string url, string extraParams)
{
return null;
}
public byte[] ConvertStream(Stream data, string extraParams)
public byte[] ConvertData(string bodyData, string extraParams)
{
return null;
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)
@@ -91,23 +103,30 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
public bool AsyncConvertData(UUID id, string bodyData, string extraParams)
{
Draw(bodyData, id, extraParams);
// XXX: This isn't actually being done asynchronously!
bool reuseable;
byte[] data = ConvertData(bodyData, extraParams, out reuseable);
m_textureManager.ReturnData(id, data, reuseable);
return true;
}
public void GetDrawStringSize(string text, string fontName, int fontSize,
out double xSize, out double ySize)
{
Font myFont = new Font(fontName, fontSize);
SizeF stringSize = new SizeF();
lock (m_graph) {
stringSize = m_graph.MeasureString(text, myFont);
xSize = stringSize.Width;
ySize = stringSize.Height;
using (Font myFont = new Font(fontName, fontSize))
{
SizeF stringSize = new SizeF();
lock (m_graph)
{
stringSize = m_graph.MeasureString(text, myFont);
xSize = stringSize.Width;
ySize = stringSize.Height;
}
}
}
#endregion
#region IRegionModule Members
@@ -121,6 +140,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
if (m_graph == null)
{
// We won't dispose of these explicitly since this module is only removed when the entire simulator
// is shut down.
Bitmap bitmap = new Bitmap(1024, 1024, PixelFormat.Format32bppArgb);
m_graph = Graphics.FromImage(bitmap);
}
@@ -148,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
public string Name
{
get { return m_name; }
get { return "VectorRenderModule"; }
}
public bool IsSharedModule
@@ -158,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
#endregion
private void Draw(string data, UUID id, 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
@@ -299,53 +320,80 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
}
Bitmap bitmap;
if (alpha == 256)
{
bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
}
else
{
bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
}
Graphics graph = Graphics.FromImage(bitmap);
// this is really just to save people filling the
// background color in their scripts, only do when fully opaque
if (alpha >= 255)
{
graph.FillRectangle(new SolidBrush(bgColor), 0, 0, width, height);
}
for (int w = 0; w < bitmap.Width; w++)
{
if (alpha <= 255)
{
for (int h = 0; h < bitmap.Height; h++)
{
bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
}
}
}
GDIDraw(data, graph, altDataDelim);
byte[] imageJ2000 = new byte[0];
Bitmap bitmap = null;
Graphics graph = null;
try
{
imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[VECTORRENDERMODULE]: OpenJpeg Encode Failed. Exception {0}{1}",
e.Message, e.StackTrace);
}
// XXX: 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.
lock (this)
{
if (alpha == 256)
bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
else
bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
graph = Graphics.FromImage(bitmap);
// this is really just to save people filling the
// background color in their scripts, only do when fully opaque
if (alpha >= 255)
{
using (SolidBrush bgFillBrush = new SolidBrush(bgColor))
{
graph.FillRectangle(bgFillBrush, 0, 0, width, height);
}
}
for (int w = 0; w < bitmap.Width; w++)
{
if (alpha <= 255)
{
for (int h = 0; h < bitmap.Height; h++)
{
bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
}
}
}
GDIDraw(data, graph, altDataDelim, out reuseable);
}
byte[] imageJ2000 = new byte[0];
try
{
imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[VECTORRENDERMODULE]: OpenJpeg Encode Failed. Exception {0}{1}",
e.Message, e.StackTrace);
}
m_textureManager.ReturnData(id, imageJ2000);
return imageJ2000;
}
finally
{
// XXX: 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.
lock (this)
{
if (graph != null)
graph.Dispose();
if (bitmap != null)
bitmap.Dispose();
}
}
}
private int parseIntParam(string strInt)
@@ -403,241 +451,308 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
*/
private void GDIDraw(string data, Graphics graph, char dataDelim)
/// <summary>
/// Split input data into discrete command lines.
/// </summary>
/// <returns></returns>
/// <param name='data'></param>
/// <param name='dataDelim'></param>
private string[] GetLines(string data, char dataDelim)
{
char[] lineDelimiter = { dataDelim };
return data.Split(lineDelimiter);
}
private void GDIDraw(string data, Graphics graph, char dataDelim, out bool reuseable)
{
reuseable = true;
Point startPoint = new Point(0, 0);
Point endPoint = new Point(0, 0);
Pen drawPen = new Pen(Color.Black, 7);
string fontName = m_fontName;
float fontSize = 14;
Font myFont = new Font(fontName, fontSize);
SolidBrush myBrush = new SolidBrush(Color.Black);
char[] lineDelimiter = {dataDelim};
char[] partsDelimiter = {','};
string[] lines = data.Split(lineDelimiter);
Pen drawPen = null;
Font myFont = null;
SolidBrush myBrush = null;
foreach (string line in lines)
try
{
string nextLine = line.Trim();
//replace with switch, or even better, do some proper parsing
if (nextLine.StartsWith("MoveTo"))
drawPen = new Pen(Color.Black, 7);
string fontName = m_fontName;
float fontSize = 14;
myFont = new Font(fontName, fontSize);
myBrush = new SolidBrush(Color.Black);
char[] partsDelimiter = {','};
foreach (string line in GetLines(data, dataDelim))
{
float x = 0;
float y = 0;
GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
startPoint.X = (int) x;
startPoint.Y = (int) y;
}
else if (nextLine.StartsWith("LineTo"))
{
float x = 0;
float y = 0;
GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
endPoint.X = (int) x;
endPoint.Y = (int) y;
graph.DrawLine(drawPen, startPoint, endPoint);
startPoint.X = endPoint.X;
startPoint.Y = endPoint.Y;
}
else if (nextLine.StartsWith("Text"))
{
nextLine = nextLine.Remove(0, 4);
nextLine = nextLine.Trim();
graph.DrawString(nextLine, myFont, myBrush, startPoint);
}
else if (nextLine.StartsWith("Image"))
{
float x = 0;
float y = 0;
GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);
endPoint.X = (int) x;
endPoint.Y = (int) y;
Image image = ImageHttpRequest(nextLine);
if (image != null)
string nextLine = line.Trim();
//replace with switch, or even better, do some proper parsing
if (nextLine.StartsWith("MoveTo"))
{
graph.DrawImage(image, (float)startPoint.X, (float)startPoint.Y, x, y);
float x = 0;
float y = 0;
GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
startPoint.X = (int) x;
startPoint.Y = (int) y;
}
else
else if (nextLine.StartsWith("LineTo"))
{
graph.DrawString("URL couldn't be resolved or is", new Font(m_fontName,6),
myBrush, startPoint);
graph.DrawString("not an image. Please check URL.", new Font(m_fontName, 6),
myBrush, new Point(startPoint.X, 12 + startPoint.Y));
float x = 0;
float y = 0;
GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
endPoint.X = (int) x;
endPoint.Y = (int) y;
graph.DrawLine(drawPen, startPoint, endPoint);
startPoint.X = endPoint.X;
startPoint.Y = endPoint.Y;
}
else if (nextLine.StartsWith("Text"))
{
nextLine = nextLine.Remove(0, 4);
nextLine = nextLine.Trim();
graph.DrawString(nextLine, myFont, myBrush, startPoint);
}
else if (nextLine.StartsWith("Image"))
{
// We cannot reuse any generated texture involving fetching an image via HTTP since that image
// can change.
reuseable = false;
float x = 0;
float y = 0;
GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);
endPoint.X = (int) x;
endPoint.Y = (int) y;
using (Image image = ImageHttpRequest(nextLine))
{
if (image != null)
{
graph.DrawImage(image, (float)startPoint.X, (float)startPoint.Y, x, y);
}
else
{
using (Font errorFont = new Font(m_fontName,6))
{
graph.DrawString("URL couldn't be resolved or is", errorFont,
myBrush, startPoint);
graph.DrawString("not an image. Please check URL.", errorFont,
myBrush, new Point(startPoint.X, 12 + startPoint.Y));
}
graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
}
}
startPoint.X += endPoint.X;
startPoint.Y += endPoint.Y;
}
else if (nextLine.StartsWith("Rectangle"))
{
float x = 0;
float y = 0;
GetParams(partsDelimiter, ref nextLine, 9, ref x, ref y);
endPoint.X = (int) x;
endPoint.Y = (int) y;
graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
startPoint.X += endPoint.X;
startPoint.Y += endPoint.Y;
}
startPoint.X += endPoint.X;
startPoint.Y += endPoint.Y;
}
else if (nextLine.StartsWith("Rectangle"))
{
float x = 0;
float y = 0;
GetParams(partsDelimiter, ref nextLine, 9, ref x, ref y);
endPoint.X = (int) x;
endPoint.Y = (int) y;
graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
startPoint.X += endPoint.X;
startPoint.Y += endPoint.Y;
}
else if (nextLine.StartsWith("FillRectangle"))
{
float x = 0;
float y = 0;
GetParams(partsDelimiter, ref nextLine, 13, ref x, ref y);
endPoint.X = (int) x;
endPoint.Y = (int) y;
graph.FillRectangle(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
startPoint.X += endPoint.X;
startPoint.Y += endPoint.Y;
}
else if (nextLine.StartsWith("FillPolygon"))
{
PointF[] points = null;
GetParams(partsDelimiter, ref nextLine, 11, ref points);
graph.FillPolygon(myBrush, points);
}
else if (nextLine.StartsWith("Polygon"))
{
PointF[] points = null;
GetParams(partsDelimiter, ref nextLine, 7, ref points);
graph.DrawPolygon(drawPen, points);
}
else if (nextLine.StartsWith("Ellipse"))
{
float x = 0;
float y = 0;
GetParams(partsDelimiter, ref nextLine, 7, ref x, ref y);
endPoint.X = (int)x;
endPoint.Y = (int)y;
graph.DrawEllipse(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
startPoint.X += endPoint.X;
startPoint.Y += endPoint.Y;
}
else if (nextLine.StartsWith("FontSize"))
{
nextLine = nextLine.Remove(0, 8);
nextLine = nextLine.Trim();
fontSize = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
myFont = new Font(fontName, fontSize);
}
else if (nextLine.StartsWith("FontProp"))
{
nextLine = nextLine.Remove(0, 8);
nextLine = nextLine.Trim();
string[] fprops = nextLine.Split(partsDelimiter);
foreach (string prop in fprops)
else if (nextLine.StartsWith("FillRectangle"))
{
float x = 0;
float y = 0;
GetParams(partsDelimiter, ref nextLine, 13, ref x, ref y);
endPoint.X = (int) x;
endPoint.Y = (int) y;
graph.FillRectangle(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
startPoint.X += endPoint.X;
startPoint.Y += endPoint.Y;
}
else if (nextLine.StartsWith("FillPolygon"))
{
PointF[] points = null;
GetParams(partsDelimiter, ref nextLine, 11, ref points);
graph.FillPolygon(myBrush, points);
}
else if (nextLine.StartsWith("Polygon"))
{
PointF[] points = null;
GetParams(partsDelimiter, ref nextLine, 7, ref points);
graph.DrawPolygon(drawPen, points);
}
else if (nextLine.StartsWith("Ellipse"))
{
float x = 0;
float y = 0;
GetParams(partsDelimiter, ref nextLine, 7, ref x, ref y);
endPoint.X = (int)x;
endPoint.Y = (int)y;
graph.DrawEllipse(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
startPoint.X += endPoint.X;
startPoint.Y += endPoint.Y;
}
else if (nextLine.StartsWith("FontSize"))
{
nextLine = nextLine.Remove(0, 8);
nextLine = nextLine.Trim();
fontSize = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
switch (prop)
myFont.Dispose();
myFont = new Font(fontName, fontSize);
}
else if (nextLine.StartsWith("FontProp"))
{
nextLine = nextLine.Remove(0, 8);
nextLine = nextLine.Trim();
string[] fprops = nextLine.Split(partsDelimiter);
foreach (string prop in fprops)
{
case "B":
if (!(myFont.Bold))
myFont = new Font(myFont, myFont.Style | FontStyle.Bold);
break;
case "I":
if (!(myFont.Italic))
myFont = new Font(myFont, myFont.Style | FontStyle.Italic);
break;
case "U":
if (!(myFont.Underline))
myFont = new Font(myFont, myFont.Style | FontStyle.Underline);
break;
case "S":
if (!(myFont.Strikeout))
myFont = new Font(myFont, myFont.Style | FontStyle.Strikeout);
break;
case "R":
myFont = new Font(myFont, FontStyle.Regular);
break;
switch (prop)
{
case "B":
if (!(myFont.Bold))
{
Font newFont = new Font(myFont, myFont.Style | FontStyle.Bold);
myFont.Dispose();
myFont = newFont;
}
break;
case "I":
if (!(myFont.Italic))
{
Font newFont = new Font(myFont, myFont.Style | FontStyle.Italic);
myFont.Dispose();
myFont = newFont;
}
break;
case "U":
if (!(myFont.Underline))
{
Font newFont = new Font(myFont, myFont.Style | FontStyle.Underline);
myFont.Dispose();
myFont = newFont;
}
break;
case "S":
if (!(myFont.Strikeout))
{
Font newFont = new Font(myFont, myFont.Style | FontStyle.Strikeout);
myFont.Dispose();
myFont = newFont;
}
break;
case "R":
// We need to place this newFont inside its own context so that the .NET compiler
// doesn't complain about a redefinition of an existing newFont, even though there is none
// The mono compiler doesn't produce this error.
{
Font newFont = new Font(myFont, FontStyle.Regular);
myFont.Dispose();
myFont = newFont;
}
break;
}
}
}
}
else if (nextLine.StartsWith("FontName"))
{
nextLine = nextLine.Remove(0, 8);
fontName = nextLine.Trim();
myFont = new Font(fontName, fontSize);
}
else if (nextLine.StartsWith("PenSize"))
{
nextLine = nextLine.Remove(0, 7);
nextLine = nextLine.Trim();
float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
drawPen.Width = size;
}
else if (nextLine.StartsWith("PenCap"))
{
bool start = true, end = true;
nextLine = nextLine.Remove(0, 6);
nextLine = nextLine.Trim();
string[] cap = nextLine.Split(partsDelimiter);
if (cap[0].ToLower() == "start")
end = false;
else if (cap[0].ToLower() == "end")
start = false;
else if (cap[0].ToLower() != "both")
return;
string type = cap[1].ToLower();
if (end)
else if (nextLine.StartsWith("FontName"))
{
switch (type)
nextLine = nextLine.Remove(0, 8);
fontName = nextLine.Trim();
myFont.Dispose();
myFont = new Font(fontName, fontSize);
}
else if (nextLine.StartsWith("PenSize"))
{
nextLine = nextLine.Remove(0, 7);
nextLine = nextLine.Trim();
float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
drawPen.Width = size;
}
else if (nextLine.StartsWith("PenCap"))
{
bool start = true, end = true;
nextLine = nextLine.Remove(0, 6);
nextLine = nextLine.Trim();
string[] cap = nextLine.Split(partsDelimiter);
if (cap[0].ToLower() == "start")
end = false;
else if (cap[0].ToLower() == "end")
start = false;
else if (cap[0].ToLower() != "both")
return;
string type = cap[1].ToLower();
if (end)
{
case "arrow":
drawPen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
break;
case "round":
drawPen.EndCap = System.Drawing.Drawing2D.LineCap.RoundAnchor;
break;
case "diamond":
drawPen.EndCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor;
break;
case "flat":
drawPen.EndCap = System.Drawing.Drawing2D.LineCap.Flat;
break;
switch (type)
{
case "arrow":
drawPen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
break;
case "round":
drawPen.EndCap = System.Drawing.Drawing2D.LineCap.RoundAnchor;
break;
case "diamond":
drawPen.EndCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor;
break;
case "flat":
drawPen.EndCap = System.Drawing.Drawing2D.LineCap.Flat;
break;
}
}
if (start)
{
switch (type)
{
case "arrow":
drawPen.StartCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
break;
case "round":
drawPen.StartCap = System.Drawing.Drawing2D.LineCap.RoundAnchor;
break;
case "diamond":
drawPen.StartCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor;
break;
case "flat":
drawPen.StartCap = System.Drawing.Drawing2D.LineCap.Flat;
break;
}
}
}
if (start)
else if (nextLine.StartsWith("PenColour") || nextLine.StartsWith("PenColor"))
{
switch (type)
nextLine = nextLine.Remove(0, 9);
nextLine = nextLine.Trim();
int hex = 0;
Color newColor;
if (Int32.TryParse(nextLine, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out hex))
{
case "arrow":
drawPen.StartCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
break;
case "round":
drawPen.StartCap = System.Drawing.Drawing2D.LineCap.RoundAnchor;
break;
case "diamond":
drawPen.StartCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor;
break;
case "flat":
drawPen.StartCap = System.Drawing.Drawing2D.LineCap.Flat;
break;
newColor = Color.FromArgb(hex);
}
else
{
// this doesn't fail, it just returns black if nothing is found
newColor = Color.FromName(nextLine);
}
myBrush.Color = newColor;
drawPen.Color = newColor;
}
}
else if (nextLine.StartsWith("PenColour") || nextLine.StartsWith("PenColor"))
{
nextLine = nextLine.Remove(0, 9);
nextLine = nextLine.Trim();
int hex = 0;
}
finally
{
if (drawPen != null)
drawPen.Dispose();
Color newColor;
if (Int32.TryParse(nextLine, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out hex))
{
newColor = Color.FromArgb(hex);
}
else
{
// this doesn't fail, it just returns black if nothing is found
newColor = Color.FromName(nextLine);
}
if (myFont != null)
myFont.Dispose();
myBrush.Color = newColor;
drawPen.Color = newColor;
}
if (myBrush != null)
myBrush.Dispose();
}
}
@@ -691,7 +806,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
{
try
{
WebRequest request = HttpWebRequest.Create(url);
WebRequest request = HttpWebRequest.Create(url);
//Ckrinke: Comment out for now as 'str' is unused. Bring it back into play later when it is used.
//Ckrinke Stream str = null;
HttpWebResponse response = (HttpWebResponse)(request).GetResponse();
@@ -702,7 +817,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
}
catch { }
return null;
}
}
}
}

View File

@@ -131,11 +131,12 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
{
// Start http server
// Attach xmlrpc handlers
m_log.Info("[XML RPC MODULE]: " +
"Starting up XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands.");
BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort);
// m_log.InfoFormat(
// "[XML RPC MODULE]: Starting up XMLRPC Server on port {0} for llRemoteData commands.",
// m_remoteDataPort);
IHttpServer httpServer = MainServer.GetHttpServer((uint)m_remoteDataPort);
httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData);
httpServer.Start();
}
}

View File

@@ -75,7 +75,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land
if (!m_Enabled)
return;
m_log.Info("[LAND IN CONNECTOR]: Starting...");
// m_log.Info("[LAND IN CONNECTOR]: Starting...");
}
public void Close()

View File

@@ -74,7 +74,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Neighbour
if (!m_Enabled)
return;
m_log.Info("[NEIGHBOUR IN CONNECTOR]: Starting...");
// m_log.Info("[NEIGHBOUR IN CONNECTOR]: Starting...");
}
public void Close()

View File

@@ -41,8 +41,7 @@ using OpenMetaverse;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
{
public class LocalGridServicesConnector :
ISharedRegionModule, IGridService
public class LocalGridServicesConnector : ISharedRegionModule, IGridService
{
private static readonly ILog m_log =
LogManager.GetLogger(
@@ -51,7 +50,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
private IGridService m_GridService;
private Dictionary<UUID, RegionCache> m_LocalCache = new Dictionary<UUID, RegionCache>();
private bool m_Enabled = false;
private bool m_Enabled;
public LocalGridServicesConnector()
{
@@ -59,7 +58,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public LocalGridServicesConnector(IConfigSource source)
{
m_log.Debug("[LOCAL GRID CONNECTOR]: LocalGridServicesConnector instantiated");
m_log.Debug("[LOCAL GRID SERVICE CONNECTOR]: LocalGridServicesConnector instantiated directly.");
InitialiseService(source);
}
@@ -84,8 +83,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (name == Name)
{
InitialiseService(source);
m_Enabled = true;
m_log.Info("[LOCAL GRID CONNECTOR]: Local grid connector enabled");
m_log.Info("[LOCAL GRID SERVICE CONNECTOR]: Local grid connector enabled");
}
}
}
@@ -95,7 +93,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
IConfig assetConfig = source.Configs["GridService"];
if (assetConfig == null)
{
m_log.Error("[LOCAL GRID CONNECTOR]: GridService missing from OpenSim.ini");
m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: GridService missing from OpenSim.ini");
return;
}
@@ -104,7 +102,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (serviceDll == String.Empty)
{
m_log.Error("[LOCAL GRID CONNECTOR]: No LocalServiceModule named in section GridService");
m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: No LocalServiceModule named in section GridService");
return;
}
@@ -115,16 +113,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (m_GridService == null)
{
m_log.Error("[LOCAL GRID CONNECTOR]: Can't load grid service");
m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: Can't load grid service");
return;
}
m_Enabled = true;
}
public void PostInitialise()
{
// FIXME: We will still add this command even if we aren't enabled since RemoteGridServiceConnector
// will have instantiated us directly.
MainConsole.Instance.Commands.AddCommand("Regions", false, "show neighbours",
"show neighbours",
"Shows the local regions' neighbours", NeighboursCommand);
"Shows the local regions' neighbours", HandleShowNeighboursCommand);
}
public void Close()
@@ -133,17 +135,22 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public void AddRegion(Scene scene)
{
if (m_Enabled)
scene.RegisterModuleInterface<IGridService>(this);
if (!m_Enabled)
return;
scene.RegisterModuleInterface<IGridService>(this);
if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID))
m_log.ErrorFormat("[LOCAL GRID CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
m_log.ErrorFormat("[LOCAL GRID SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
else
m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene));
}
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
m_LocalCache[scene.RegionInfo.RegionID].Clear();
m_LocalCache.Remove(scene.RegionInfo.RegionID);
}
@@ -232,7 +239,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
#endregion
public void NeighboursCommand(string module, string[] cmdparams)
public void HandleShowNeighboursCommand(string module, string[] cmdparams)
{
System.Text.StringBuilder caps = new System.Text.StringBuilder();

View File

@@ -31,7 +31,7 @@ using System.Collections.Generic;
using System.Reflection;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Statistics;
using OpenSim.Framework.Monitoring;
using OpenSim.Services.Connectors;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;

View File

@@ -128,11 +128,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
m_enabled = true;
}
///<summary>
///
///</summary>
///<summary>
///
///</summary>
@@ -146,10 +141,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
lock (m_scenes)
m_scenes[scene.RegionInfo.RegionID] = scene;
scene.EventManager.OnLoginsEnabled += OnLoginsEnabled;
scene.EventManager.OnRegionReadyStatusChange += s => { if (s.Ready) UploadMapTile(s); };
}
///<summary>
///
///</summary>
@@ -163,21 +157,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
}
#endregion ISharedRegionModule
void OnLoginsEnabled(string regionName)
{
Scene scene = null;
foreach (Scene s in m_scenes.Values)
if (s.RegionInfo.RegionName == regionName)
{
scene = s;
break;
}
if (scene != null)
UploadMapTile(scene);
}
///<summary>
///
///</summary>

View File

@@ -125,13 +125,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour
uint x, y;
Utils.LongToUInts(regionHandle, out x, out y);
m_log.DebugFormat("[NEIGHBOUR CONNECTOR]: HelloNeighbour from region {0} to region at {1}-{2}",
thisRegion.RegionName, x / Constants.RegionSize, y / Constants.RegionSize);
foreach (Scene s in m_Scenes)
{
if (s.RegionInfo.RegionHandle == regionHandle)
{
m_log.DebugFormat("[LOCAL NEIGHBOUR SERVICE CONNECTOR]: HelloNeighbour from region {0} to neighbour {1} at {2}-{3}",
thisRegion.RegionName, s.Name, x / Constants.RegionSize, y / Constants.RegionSize);
//m_log.Debug("[NEIGHBOUR CONNECTOR]: Found region to SendHelloNeighbour");
return s.IncomingHelloNeighbour(thisRegion);
}

View File

@@ -312,7 +312,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
// s.RegionInfo.RegionName, destination.RegionHandle);
Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); });
Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); });
return true;
}
@@ -354,24 +354,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return false;
}
public bool CreateObject(GridRegion destination, UUID userID, UUID itemID)
{
if (destination == null)
return false;
if (m_scenes.ContainsKey(destination.RegionID))
{
// m_log.DebugFormat(
// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
// s.RegionInfo.RegionName, destination.RegionHandle);
return m_scenes[destination.RegionID].IncomingCreateObject(userID, itemID);
}
return false;
}
#endregion /* IInterregionComms */
#region Misc

View File

@@ -300,13 +300,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return false;
}
public bool CreateObject(GridRegion destination, UUID userID, UUID itemID)
{
// Not Implemented
return false;
}
#endregion /* IInterregionComms */
}
}
}

View File

@@ -129,18 +129,18 @@ namespace OpenSim.Region.CoreModules.World
switch (cmd[1])
{
case "enable":
scene.LoginsDisabled = false;
scene.LoginsEnabled = true;
MainConsole.Instance.Output(String.Format("Logins are enabled for region {0}", scene.RegionInfo.RegionName));
break;
case "disable":
scene.LoginsDisabled = true;
scene.LoginsEnabled = false;
MainConsole.Instance.Output(String.Format("Logins are disabled for region {0}", scene.RegionInfo.RegionName));
break;
case "status":
if (scene.LoginsDisabled)
MainConsole.Instance.Output(String.Format("Login in {0} are disabled", scene.RegionInfo.RegionName));
else
if (scene.LoginsEnabled)
MainConsole.Instance.Output(String.Format("Login in {0} are enabled", scene.RegionInfo.RegionName));
else
MainConsole.Instance.Output(String.Format("Login in {0} are disabled", scene.RegionInfo.RegionName));
break;
default:
MainConsole.Instance.Output("Syntax: login enable|disable|status");

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

@@ -124,7 +124,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
LandData landData = lo.LandData;
string landDataPath = String.Format("{0}{1}.xml", ArchiveConstants.LANDDATA_PATH,
landData.GlobalID.ToString());
m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData));
m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options));
}
m_log.InfoFormat("[ARCHIVER]: Adding terrain information to archive.");

View File

@@ -46,8 +46,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
/// <summary>
/// Store for asset data we received before we get the metadata
/// </summary>

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