Compare commits

..

539 Commits

Author SHA1 Message Date
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)
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
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
Justin Clark-Casey (justincc)
0d2243a393 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-06-14 01:38:41 +01:00
Justin Clark-Casey (justincc)
917d753f1c Fix a race condition where an object update for a hud could be sent to non-owner avatars if the hud was attached directly from within the region.
If this happens, then the non-owners would see unremovable huds that they did not own until relog, and sometimes even beyond that.
This was due to a race between the entity update and the attachment code when moving an object from within scene to a hud.
2012-06-14 01:36:37 +01:00
Justin Clark-Casey (justincc)
a4290048e5 Add SOG.HasPrivateAttachmentPoint to tell if a SOG has a private attachment point. HUDs attachment points are private.
Change SOP.SendFullUpdateToClient() and SoundModule.PlayAttachedSound() to use this rather than different magic number formulations.
This also corrects a bug in PlayAttachedSound() where the code assumed that all attachment points over 30 were HUDs.
It appears this is no longer true with Neck and Root (Avatar Center)
2012-06-14 01:20:55 +01:00
Melanie
cba8b4f8b8 Fix not sending TransferInfo when an asset is not found. This clogs
up the sound pipeline in the viewer.
2012-06-14 00:58:17 +01:00
Justin Clark-Casey (justincc)
6a77a65675 minor: remove unnecessary IsAttachment = false setting for new object in UploadObjectAssetModule, property always starts as false 2012-06-14 00:35:26 +01:00
Justin Clark-Casey (justincc)
16ffc764bf minor: refactor part of LLClientView.ProcessEntityUpdates() to remove duplicate code 2012-06-13 23:54:32 +01:00
Justin Clark-Casey (justincc)
cf080a68d6 Remove long obsolete and unused IClientAPI.KillEndDone() 2012-06-13 23:42:22 +01:00
Justin Clark-Casey (justincc)
f726150afd Add ObjectUpdate as one of the packets that can be screened out when setting debug packet level 2012-06-13 23:39:23 +01:00
Justin Clark-Casey (justincc)
1f34c8277d In the osGetGrid functions, if the [GridInfo] section does not exist then return "Configuration Error", as already happens if there is no GridInfoURI 2012-06-13 04:05:02 +01:00
Justin Clark-Casey (justincc)
66cb533f26 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-06-13 03:51:13 +01:00
Justin Clark-Casey (justincc)
5145356467 Add "deregister region" by uuid command to grid service to allow manual deregistration of simulators.
Useful if a simulator has crashed without removing its regions and those regions have been reconfigured differently
2012-06-13 03:49:22 +01:00
Melanie
77f579dcc8 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-06-13 02:34:25 +01:00
BlueWall
7c0843aad1 Add the updated OpenSimDefaults.ini for the prior timer_Interval patch. 2012-06-12 21:55:31 -04:00
Melanie
4e18e71089 Committing the Avination implementation of llCastRay. This is a complete rewrite
wich does it's thing independently of physics. Enjoy!
2012-06-13 02:32:25 +01:00
Justin Clark-Casey (justincc)
94bbbf96c7 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-06-13 02:25:42 +01:00
Justin Clark-Casey (justincc)
c6e375291a Don't include time to transmit response back to requester when assessing slow handling of requests.
This is to avoid logging a 'slow' request when the source of delay is the viewer in processing a response.
This is not something we can do much about on the server end - it's server-side delay that we're interested in.
To ensure consistency, this commit also had to refactor and simplify inbound non-poll network request handling, though there should be no functional change.
IOSHttpResponse no longer exposes the Send() method, only classes in OpenSim.Framework.Servers.HttpServer should be doing this.
Only the GetTextureHandler was sending its own response.  Now it leaves this to BaseHttpServer, like all other core handlers.
2012-06-13 00:03:44 +01:00
BlueWall
c53c55fed0 Add variable timer configureation for the timer_Script
Added "timer_Interval" to the OpenSimDefaults.ini, leaving the default value set to 1200, as the previous default setting. The value represents seconds. To change the default, copy the entry to OpenSim.ini and multiply the number of minutes for the interval by 60.
2012-06-12 17:15:56 -04:00
Justin Clark-Casey (justincc)
2ca31a9841 Remove accidental timeout left in during earlier debugging. Has been in since two commits ago (b099f26) 2012-06-12 02:46:14 +01:00
Justin Clark-Casey (justincc)
1b1f0a2d77 OnConnectionClosed listeners, retrieve data from IClientAPI.SceneAgent rather than scanning all scene for the presence with the right id
Stop checking IsLoggingOut on these listeners, if called with a root agent then we always want to perform these actions.
This covers cases where the client is closed due to manual kick, simulator shutdown, etc.
2012-06-12 02:43:33 +01:00
Justin Clark-Casey (justincc)
b099f26376 Set IClientAPI.IsActive = false early on client removal due to ack timeout rather than using IsLoggingOut flag.
IsActive is more appropriate since unack timeout is not due to voluntary logout.
This is in line with operations such as manual kick that do not set the IsLoggingOut flag.
It's also slightly better race-wise since it reduces the chance of this operation clashing with another reason for client deactivation (e.g. manual kick).
2012-06-12 02:16:36 +01:00
Justin Clark-Casey (justincc)
c89db34fc4 If the simulator closes a root agent due to ack timeout, then send the client a kick message with that reason, in case it is somehow still listening. 2012-06-12 02:03:31 +01:00
Justin Clark-Casey (justincc)
8c7149063b In PresenceDetector.OnConnectionClose(), use the IsChildAgent check already available on IClientAPI.SceneAgent rather than retrieving it again by scanning all scenes. 2012-06-12 01:25:09 +01:00
Justin Clark-Casey (justincc)
bab7dab4c5 Comment out the scene presence sitting debug log messages for now 2012-06-11 23:37:16 +01:00
Justin Clark-Casey (justincc)
51fe97a00c Set CreateDefaultAvatarEntries = true in Robust.HG.ini.example to match Robust.HG.ini
Thanks to Ai Austin for the spot.
2012-06-11 23:33:32 +01:00
Justin Clark-Casey (justincc)
daad0a3e11 Revert "Bind ~ and ! operators in LSL tighter in order to resolve issues in LSL where these aren't evaluated propertly."
This reverts commit a8a9d13dc0.

Accidentally committed, this patch might not be the correct approach.
2012-06-11 23:30:58 +01:00
Justin Clark-Casey (justincc)
a927787434 Add last frame time monitor to MonitorModule now that this value is useful 2012-06-11 23:30:11 +01:00
Justin Clark-Casey (justincc)
cbb5ddd944 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-06-11 23:27:48 +01:00
Melanie
71ba85137f Commitig the Avination implementation of llTeleportAgent and
llTeleportAgentGlobalCoords. These do NOT use PERMISSION_TELEPORT like
their SL counterparts because that permission is not yet understood by TPVs
based on v1.x.
2012-06-11 16:45:52 +01:00
Justin Clark-Casey (justincc)
a8a9d13dc0 Bind ~ and ! operators in LSL tighter in order to resolve issues in LSL where these aren't evaluated propertly.
Addresses http://opensimulator.org/mantis/view.php?id=3268
2012-06-09 05:11:08 +01:00
Justin Clark-Casey (justincc)
1f3218e53f Create avatar entries necessary to stop new v3 avatars being clouds (pants, shape, etc.) by default in grid mode.
This only affects avatars created through the "create user" console command or createuser XMLRPC.
This matches the default setting for standalone
2012-06-09 01:11:15 +01:00
Justin Clark-Casey (justincc)
08cd5d2503 Add documentation to AllowGodFunctions setting in [LL-Functions] 2012-06-09 00:33:17 +01:00
Justin Clark-Casey (justincc)
817f2d341d Fix regression in 5f4f9f0 (Fri Jun 8 2012) which stopped "show stats" and json stats from working 2012-06-08 23:36:53 +01:00
Justin Clark-Casey (justincc)
794d184c25 Stop sending a DisableSimulator packet in LLClientView.Close(), which is a duplicate for child agents and unnecessary for root agents.
Close() already calls Scene.RemoveClient() which sends the right eq or udp DisableSimulator message to child agents.
2012-06-08 04:32:51 +01:00
Justin Clark-Casey (justincc)
f94b92df46 Instead of retrieving the known client again in LLUDPServer.RemoveClient(), check the IsLoggingOut flag instead.
This is slightly better thread-race wise
2012-06-08 04:12:22 +01:00
Justin Clark-Casey (justincc)
c215b1ad16 If logging a client out due to ack timeout, do this asynchronously rather than synchronously on the outgoing packet loop.
This is the same async behaviour as normal logouts.
This is necessary because the event queue will sleep the thread for 5 seconds on an ack timeout logout as the client isn't around to pick up the final event queue messages.
2012-06-08 03:53:03 +01:00
Justin Clark-Casey (justincc)
5f4f9f0230 Add regression test for client logout due to ack timeout. 2012-06-08 03:12:23 +01:00
Justin Clark-Casey (justincc)
d73805d7f4 Remove null checks at top of LLUDPServer.ProcessInPacket(). Neither packet nor client are ever null. 2012-06-08 01:51:28 +01:00
Justin Clark-Casey (justincc)
d71c6dea7e Store already retrieve IClientAPI in IncomingPacket structure for later use rather than doing another retrieve on dequeue.
Instead of checking whether the client still exists by trying to retrieve again from the client manager, this patch gets it back from IncomingPacket and checks the IClientAPI.IsActive state.
2012-06-08 01:43:58 +01:00
Justin Clark-Casey (justincc)
30f4a33f01 Don't make duplicate call to ScenePresence.Close() separately in ETM.DoTeleport() if an agent needs closing.
This is always done as part of Scene.RemoveClient()
Also refactors try/catching in Scene.RemoveClient() to log NREs instead of silently discarding, since these are useful symptoms of problems.
2012-06-08 01:26:43 +01:00
Justin Clark-Casey (justincc)
5c162ccd57 Go back to calling IncomingCloseAgent() in the "kick user" command for consistency instead of IClientAPI.Close() directly.
This no longer double counts child agent removals
2012-06-08 00:59:39 +01:00
Justin Clark-Casey (justincc)
d547bcf8d1 Remove duplicate update of user count in Scene.IncomingCloseAgent()
This is already done in Scene.RemoveClient() which IncomingCloseAgent() always ends up calling.
2012-06-08 00:40:38 +01:00
Justin Clark-Casey (justincc)
af2954898e Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-06-08 00:24:39 +01:00
Justin Clark-Casey (justincc)
b56673c920 Fix bug with "kick user" reducing agent counts by 2 instead of 1.
This is done by making the kick user command call IClientAPI.Close() rather than routing through Scene.IncomingCloseAgent(), which also called IClientAPI.Close()
DisableSimulator for child agents is moved from IncomingCloseAgent() to RemoveClient(), this is not a functional change since IncomingCloseAgent() always ends up calling RemoveClient()
2012-06-08 00:18:25 +01:00
Justin Clark-Casey (justincc)
0c5fefacb4 Record the fact that child agents can have asset transactions.
Also change code to grab the agent asset transaction module once.
2012-06-07 23:51:04 +01:00
Justin Clark-Casey (justincc)
de87e4871b Don't send kill object messages to clients when a child agent is closed. 2012-06-07 23:35:21 +01:00
Melanie
39cb2063bf Add collision sounds to the asset set 2012-06-07 23:35:08 +01:00
Talun
d5cc959683 Mantis 6044 Building master currently fails.
Add missing reference to System.Core

Signed-off-by: BlueWall <jamesh@bluewallgroup.com>
2012-06-07 11:16:18 -04:00
BlueWall
a1e857932a Make change to fix Windows builds 2012-06-07 10:17:37 -04:00
Justin Clark-Casey (justincc)
7550b97e65 Log warning if we try to remove a UDP client that has already been removed. 2012-06-07 04:00:29 +01:00
Justin Clark-Casey (justincc)
98b46d48fe Allow the thread watchdog to accept an alarm method that is invoked if the timeout is breached.
This alarm can then invoke this to log extra information.
This is used in LLUDPServer to show which client was being processed when incoming and outgoing udp watchdog alarms are triggered.
2012-06-07 02:44:13 +01:00
Justin Clark-Casey (justincc)
514dd85199 minor: Change log messages on Warp3DImageModule to show they are from this module 2012-06-06 04:18:38 +01:00
Justin Clark-Casey (justincc)
53c25a4778 Rename MapImageModule for Warp3D to Warp3DImageModule to match its class name and make it easier to distinguish between map image modules. 2012-06-06 04:15:00 +01:00
Justin Clark-Casey (justincc)
2b0de66216 Actively dispose of Bitmaps in Warp3D image module and world map module once we've finished with them.
This might help with memory leakage issues though I suspect it won't.
2012-06-06 04:11:16 +01:00
SignpostMarv
3b25021180 enabling all corners of a sim to be set in one call 2012-06-06 02:47:47 +01:00
Justin Clark-Casey (justincc)
abf94627f6 Ensure closure of bitmap and memory stream with using() statements in WorldViewModule.
If this has any effect then it will only be to the map images returned via requests to the /worldview simulator HTTP path (not enabled by default)
2012-06-06 02:45:36 +01:00
Justin Clark-Casey (justincc)
6adc810eaa Stop accidentally reading 4 Int16s instead of 2 in SIZE section of Terragen file when loaded from a stream.
Fixes a bug introduced 2 weeks ago in 67ebe80
Thanks to Plugh for pointing this out.
2012-06-05 19:40:16 +01:00
Justin Clark-Casey (justincc)
a5410c2c19 minor: Add user feedback when executing fix-phantoms 2012-06-05 01:37:40 +01:00
Justin Clark-Casey (justincc)
42179578fc Allow fix-phantoms command to appear even if CombineContiguousRegions = false, since this allows one to go back from a megaregion to normal regions.
Adapted from a patch by Garmin Kawaguichi in http://opensimulator.org/mantis/view.php?id=6027
Garmin says that fix-phantoms allows one to reset objects when going back from megaregion to normal regions as well as the othe rway around.
Thanks!
2012-06-05 01:33:58 +01:00
Talun
008c6a4610 Mantis 4597 AgentPaused packet is ignored.
The packet was actually being handled but not acted on.
This change extends the default timeout for paused clients to 5 minutes
and makes both the paused and non-paused timeout periods configurable.
2012-06-05 01:22:05 +01:00
Justin Clark-Casey (justincc)
01280e9b94 Remove unused ScenePresence list structure in llGetAgentList() 2012-06-05 00:34:18 +01:00
Justin Clark-Casey (justincc)
96d1ba90d7 Scale down per frame MS stats to match scaled simulator FPS stat.
This makes frame time stats properly tally with fps, which saves confusion and makes it easier to interpret numbers.
In some ways this is not so artifical - physics FPS runs at the higher rate.
2012-06-05 00:27:51 +01:00
Justin Clark-Casey (justincc)
655625ab87 Start sending spare frame time MS viewer stat. Make frame time correctly display total frame time, not just non-spare time.
This makes it easier to see when components of frame time exceed normal permitted frame time.
Currently reflect scene frame times.
2012-06-05 00:17:55 +01:00
Justin Clark-Casey (justincc)
c3d9acc9a9 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-06-05 00:15:29 +01:00
Justin Clark-Casey (justincc)
a7f4804f53 Properly show per frame millisecond statistics per frame, not as amount of time taken per second.
This is to make these statistics actually match their names (and also be more accurate as number of frames can vary under heavy load)
Currently using scene frames (11.23 every second) instead of physics frames (56.18 per second)
2012-06-04 23:07:53 +01:00
BlueWall
3229e32b4e Add replaceable region modules to the "show modules" command 2012-06-04 17:25:38 -04:00
Melanie
9707a2d57c Remove profile from basic configuration 2012-06-04 18:24:02 +01:00
Melanie
d9d4fb10d9 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-06-04 18:22:43 +01:00
Robert Adams
f94ef37b46 Correct the delegate specification in EventManager.TriggerTerrainTainted. Looks like the wrong one was cut and pasted. 2012-06-04 10:26:39 -07:00
Melanie
5c646e2603 Remove the "Profile" config as it's covered by the replaceable interface 2012-06-04 18:22:09 +01:00
Justin Clark-Casey (justincc)
729d90173f Fix build break whree accidentally did inv.Folders rather than inv.Folders.Count in a minor change. 2012-06-02 05:03:56 +01:00
Justin Clark-Casey (justincc)
2de5479c3f minor: tidy up some comments 2012-06-02 05:01:56 +01:00
Justin Clark-Casey (justincc)
01a2b0b289 Fix various issues with http inventory
1) The return messages were being wrongly populated with the names of asset, inventory and sale types when their corresponding integers should have been used instead.
2) Folders with links were including the linked items in the descendents figure, when only the links should be included.
3) Links and linked items in link folders were not being included in the return data, and not in the correct order.

Now that these issues have been addressed, outfits and attachments appear to work consistently when HTTP inventory is enabled (as is now the default).
2012-06-02 04:57:10 +01:00
Justin Clark-Casey (justincc)
72219eae7d Instead of updating sim stats root agent, child, objects and scripts accounts every single scene frame, update in the once every 3 seconds SimStatsReporter run 2012-06-01 04:47:11 +01:00
Justin Clark-Casey (justincc)
6375db1533 Add optional total avatars, total prims and active prims stats to ODE plugin.
These will act as a sanity check with the main scene stats, to show that physics scene entities are being managed properly.
Total prims will not match scene total prims since physics total does not include phantom prims
2012-06-01 04:23:36 +01:00
Justin Clark-Casey (justincc)
4e06a46dc5 If OdeScene.Near() returns no collision contacts, then exit as early as possible. All subsequent code is only relevant if there are contacts. 2012-06-01 04:07:39 +01:00
Justin Clark-Casey (justincc)
200376b3c4 Add optional stat for the other collision time per frame not spent in ODE native spaces or geom collision code 2012-06-01 03:49:42 +01:00
Justin Clark-Casey (justincc)
d34b84b531 Add avatar forces calculation, prim force and raycasting per frame millisecond optional stats 2012-06-01 03:23:19 +01:00
Justin Clark-Casey (justincc)
9ff8efc720 Collection optional avatar and prim taint frame millisecond times 2012-06-01 03:03:48 +01:00
Justin Clark-Casey (justincc)
d1b5f8d9d7 Remove recent optional native collision frame milliseconds stat
Unnecessary since this has now been broken down into space collisions and geom collisions
2012-06-01 02:35:11 +01:00
Justin Clark-Casey (justincc)
31343aa7c3 Add optional stat that records milliseconds spent notifying collision listeners in physics frames 2012-06-01 02:33:44 +01:00
Justin Clark-Casey (justincc)
5f44be99ef Add avatar and prim update milliseconds per frame optional stats 2012-06-01 02:25:42 +01:00
Justin Clark-Casey (justincc)
5cc9b820e5 Add option native step frame ms stat 2012-06-01 01:58:28 +01:00
Justin Clark-Casey (justincc)
f2c8c7a7b8 Add total ODE frame time optional stat, as a sanity check on the main scene physics stat 2012-06-01 01:37:19 +01:00
Justin Clark-Casey (justincc)
8333b928fa Break down native ODE collision frame time stat into native space collision and geom collision stats 2012-06-01 01:27:19 +01:00
Justin Clark-Casey (justincc)
c33c8db825 Rename new collision stats to 'contacts' - there are/can be multiple contacts per collision and this is what is actually being measured. 2012-06-01 01:15:27 +01:00
Justin Clark-Casey (justincc)
e1f8d2adb0 Stop adding an unnecessary duplicate _perloopcontact if the avatar is standing on a prim.
This has already been added earlier on in the method.
2012-06-01 01:12:30 +01:00
Justin Clark-Casey (justincc)
8301f7b17f minor: comment out currently unused OdeScene.sCollisionData 2012-06-01 00:57:55 +01:00
Justin Clark-Casey (justincc)
93fa9e8991 Add ODE avatar and prim collision numbers if extra stats collection is enabled. 2012-06-01 00:56:13 +01:00
Justin Clark-Casey (justincc)
878b67b333 Fix OdeScene.GetTopColliders() to return the top 25 colliders rather than the first 25 that had non-zero collision scores.
Also zeros collisions scores on all prims after report collection, not just the top 25.
As before, this collision scores are only reset after a report is requested, which may give unrealistic numbers on the first request.
So to see more realistic scores, ignore the first report and then refresh the request after a couple of seconds or so.
2012-06-01 00:26:11 +01:00
Justin Clark-Casey (justincc)
0b02a4d42e Add an optional mechanism for physics modules to collect and return arbitrary stats.
If active, the physics module can return arbitrary stat counters that can be seen via the MonitoringModule
(http://opensimulator.org/wiki/Monitoring_Module)
This is only active in OdeScene if collect_stats = true in [ODEPhysicsSettings].
This patch allows OdeScene to collect elapsed time information for calls to the ODE native collision methods to assess what proportion of time this takes compared to total physics processing.
This data is returned as ODENativeCollisionFrameMS in the monitoring module, updated every 3 seconds.
The performance effect of collecting stats is probably extremely minor, dwarfed by the rest of the physics code.
2012-05-31 01:52:26 +01:00
Justin Clark-Casey (justincc)
bf0b8170f7 Add console command "teleport user" to allow teleport from the region console
See "help teleport user" on the console for more details
2012-05-29 23:35:20 +01:00
Melanie
b660c4991b Fix collision filtering. The filter should be checked on the receiving part! 2012-05-29 18:18:47 +01:00
Justin Clark-Casey (justincc)
79f3ce2e9f refactor: factor out entity transfer state machine into a separate class to make code more analyzable 2012-05-28 23:06:00 +01:00
Justin Clark-Casey (justincc)
8f87f55d05 If handling the failure of teleport, move agent state to CleaningUp when we start the handling.
Also fixes the log warning from ResetInTransit() if the state is cleared direct from Transferring or ReceiveAtDestination, as pointed out in mantis 5426
2012-05-28 22:16:06 +01:00
Justin Clark-Casey (justincc)
7fd38788b4 minor: code formatting from 0b72f773 2012-05-26 02:14:32 +01:00
Talun
0b72f773c7 Mantis 6025 llRequestPermissions auto grant for NPCs.
If the script requesting permissions is owned by either the NPC or
the NPCs owner (if the NPC is created as owned) then grant any
permissions automatically.
2012-05-26 02:09:22 +01:00
Justin Clark-Casey (justincc)
43a6f28620 If restating a region, clean up the physics scene after the main scene has been closed not before.
If this is done before then on ODE agent update calls still incoming can fail as they try to use a raycastmanager that has been disposed.
Bullet plugin does nothing on Dispose()
However, I wouldn't be at all surprised if individual region restarting was buggy in lots of other areas.
2012-05-26 01:55:35 +01:00
Justin Clark-Casey (justincc)
3ac3be99ae Add Blake/Techplex to CONTRIBUTORS. Thanks! 2012-05-26 01:35:33 +01:00
Blake.Bourque
33b66009e4 One can now get hyoergrid region co-ordinates with llRequestSimulatorData 2012-05-26 01:32:42 +01:00
Justin Clark-Casey (justincc)
d6476b6277 Use GetInventoryItem() in LSL_Api.InventoryKey(string name, int type).
Also removes small bug where calling this method would add 1 to LPS, evne though all callers already did this.
2012-05-26 01:03:53 +01:00
Justin Clark-Casey (justincc)
f2a5fad18f Use SceneObjectPartInventory.GetInventoryItem() in OSSL.AvatarStopAnimation instead of searching the task inventory manually. 2012-05-26 00:54:00 +01:00
Justin Clark-Casey (justincc)
ff53add54d refactor: replace LSL_Api.InventoryKey(string) largely with SceneObjectPartInventory.GetInventoryItem(string)
Also gets llStopAnimation() to call KeyOrName rather than duplicating logic.
2012-05-26 00:36:01 +01:00
Talun
120f8145fc Mantis 6028 osAvatarStopAnimation not stopping animations via UUID
Corrected to stop animations using the animation UUID similar to llStopAnimation.
See http://opensimulator.org/wiki/OsAvatarStopAnimation
2012-05-25 23:45:03 +01:00
Justin Clark-Casey (justincc)
67ebe80dd9 Resolve some mono compiler warnings. 2012-05-25 04:03:16 +01:00
Justin Clark-Casey (justincc)
ab59c0a658 on agent cross, remove from physics scene after its been placed in transit, not before. 2012-05-25 03:39:10 +01:00
Justin Clark-Casey (justincc)
888210ea4a refactor: make ETM.CrossAgentToNewRegionAsync neighbourRegion == null check return earlier to simplify method 2012-05-25 03:06:26 +01:00
Justin Clark-Casey (justincc)
9f1fc7ea88 Remove a call stack debugging line accidentally left in from a few days ago at SceneObjectPartInventory.ApplyNextOwnerPermissions(). 2012-05-25 02:54:37 +01:00
Justin Clark-Casey (justincc)
96cde407ab Fix bug where a failed QueryAccess to a remove region would always have the reason "Communications failure" no matter what the destination region actually returned 2012-05-25 02:37:22 +01:00
Justin Clark-Casey (justincc)
40c78b0624 Stop it being possible for an agent to teleport back to its source region before the source region has finished cleaning up old agent data and structures.
If this is allowed, then the client usually gets forcibly logged out and data structures might be put into bad states.
To prevent this, the binary state machine of EMT.m_agentsInTransit is replaced with a 4 state machine (Preparing, Transferring, ReceivedAtDestination, CleaningUp).
This is necessary because the source region needs to know when the destination region has received the user but a teleport back cannot happen until the source region has cleaned up.
Tested on standalone, grid and with v1 and v3 clients.
2012-05-25 02:02:53 +01:00
Justin Clark-Casey (justincc)
7cceab1295 In remote QueryAccess, also receive the actual status (true|false) instead of always true no matter what the callee actually returned.
This was due to two things
1) SimulationServiceConnector.QueryAccess was always looking to the outer result["success"].
But if a "_Result" map is returned (which is certainly the case right now), then the true success is _Result["success"], result["success"] is always true no matter what
2) If QueryAccess was false at the destination, then AgentHandlers.DoQueryAccess() was never putting this in the result.
The default action of SerializeJsonString() is not to put false booleans in the JSON!!!, so this has to be explicitly set.
2012-05-25 01:41:00 +01:00
Justin Clark-Casey (justincc)
93ff27053a Don't actually proceed on a within-region teleport if another is already taking place, rather than just (falsely) logging that we're not going to proceed.
An oversight from recent commit 9ab0c81
2012-05-24 22:59:52 +01:00
Justin Clark-Casey (justincc)
cc53d91d2f On inter-region teleport, only stand the avatar up if the QueryAccess call to the destination scene actually succeeds. 2012-05-24 22:46:45 +01:00
Justin Clark-Casey (justincc)
cd225215b1 Now that the EntityTransferModule is per-region, fetch the event queue module once rather than repeatedly via scene presences 2012-05-24 22:40:24 +01:00
Justin Clark-Casey (justincc)
5c9086ade6 Fix issue where a dns resolution failure on the final destination might leave the user unable to teleport since the transit flag was not being reset.
This moves the 'already in transit' check further up and resets the flag if dns resolution fails and in the new required places.
2012-05-24 22:26:02 +01:00
SignpostMarv
99cebec4ab adding status codes from rfc 6585
Signed-off-by: BlueWall <jamesh@bluewallgroup.com>
2012-05-24 12:09:15 -04:00
SignpostMarv
87f9aa9d08 porting IDE tooltip-friendly documentation tweaks from Aurora-Sim
Signed-off-by: BlueWall <jamesh@bluewallgroup.com>
2012-05-24 12:09:15 -04:00
Justin Clark-Casey (justincc)
f4cd4c8e28 Comment out accidentally left in log line that was printing out the control file on OAR save 2012-05-24 04:33:36 +01:00
Justin Clark-Casey (justincc)
38ce9d45a5 Make ISimulationScene.GetScene() used the more efficient region id for lookup rather than the region handle. 2012-05-24 01:00:18 +01:00
Justin Clark-Casey (justincc)
459c7635af If an agent is still registered as 'in transit' by the source region, don't allow an immediate teleport back.
This is to help relieve a race condition when an agent teleports then immediately attempts to teleport back before the source region has properly cleaned up/demoted the old ScenePresence.
This is rare in viewers but much more possible via scripting or region module.
However, more needs to be done since virtually all clean up happens after the transit flag is cleared .
Possibly need to add a 'cleaning up' state to in transit.
This change required making the EntityTransferModule and HGEntityTransferModule per-region rather than shared, in order to allow separate transit lists.
Changes were also required in LocalSimulationConnector.
Tested in standalone, grid and with local and remote region crossings with attachments.
2012-05-24 00:31:14 +01:00
PixelTomsen
bc543c1797 Environment Module - allows Environment settings for Viewer3 warning: includes database region store migrations for mssql, mysql, sqlite
enable/disable this module:
Cap_EnvironmentSettings = "localhost" (for enable)
Cap_EnvironmentSettings = "" (for disable) at ClientStack.LindenCaps section (OpenSimDefaults.ini file)
 or owerwrite in OpenSim.ini

mantis: http://opensimulator.org/mantis/view.php?id=5860

Signed-off-by: BlueWall <jamesh@bluewallgroup.com>
2012-05-23 17:04:19 -04:00
BlueWall
b490050165 Format cleanup 2012-05-23 16:58:04 -04:00
BlueWall
682d4075e3 Fix llGetSimulatorHostname to return configured hostname 2012-05-23 15:08:39 -04:00
Justin Clark-Casey (justincc)
4d1986c0e4 minor: Change [OBJECT COMMANDS MODULE] log strings to [REGION COMMANDS MODULE] strings, though all these are currently commented out anyway 2012-05-23 04:20:54 +01:00
Justin Clark-Casey (justincc)
ee98b9c394 Add "show scene" command which lists stats for the currently selected console scene(s)
This includes prim count, script count, avatar count, etc.
Information is currently the same as "show stats", though show stats can only show one scene at a time because it listens for the latest outgoing stats packet (a bad approach that needs to change).
Might be better to tie this module into the other stats module to display arbitrary stats rather than fetching directly from scene.SimStatsReporter.
Console command is "show scene" because "show region" already exists for the grid service, which is unfortunate.
Might need to make a distinction between "scene" relating to a live scene and "region" relating to more static region data (url, coords, etc.)
2012-05-23 04:10:45 +01:00
Justin Clark-Casey (justincc)
8f88c17df9 refactor: Rename ConsoleTableRow and ConsoleTableColumn to ConsoleDisplayTableRow and ConsoleDisplayTableColumn 2012-05-23 03:23:37 +01:00
Justin Clark-Casey (justincc)
059a1e90b9 Add ConsoleDisplayList for more consistent formatting of console output in list form.
Convert "show region" to use this structure rather than hand-constructing
2012-05-23 03:19:25 +01:00
Justin Clark-Casey (justincc)
2222d979cc refactor: rename ConsoleTable -> ConsoleDisplayTable for clarity 2012-05-23 02:37:38 +01:00
Justin Clark-Casey (justincc)
c6ce41bfba Add missing Y co-ord in "show region" console command information 2012-05-23 02:31:53 +01:00
Justin Clark-Casey (justincc)
050007b44d Lay out "show region" information in an easier to read line by line format 2012-05-23 02:30:16 +01:00
Justin Clark-Casey (justincc)
68918d632f Fetch the dialog module reference in AttachmentsModule in RegionLoaded() not AddRegion()
The reference is not guaranteed to be there when AddRegion() is called but will definitely be present at RegionLoaded() if it's going to be present at all.
2012-05-23 02:09:31 +01:00
Justin Clark-Casey (justincc)
ec8745cf51 minor: Make log class names in InventoryAccessModule uniform 2012-05-23 02:05:48 +01:00
Justin Clark-Casey (justincc)
ff429a259b Fix bug where an avatar that had an object they owned attached through llAttachToAvatar() or osForceAttachToAvatar() would wrongly have next permissions come into play when they detached that object and rezzed it in scene.
This is because the attachments module code was setting the 'object slam' bit by using PermissionMask.All
Solution here is to route the attachment item creation call through the existing inventory code in BasicInventoryAccessModule rather than copy/pasted code in AttachmentsModule itself.
2012-05-23 01:58:10 +01:00
Justin Clark-Casey (justincc)
9ab0c81c1d Setting 'in transit' on a local teleport as well as inter-region teleports.
This is to eliminate possible race conditions if two teleport calls are made concurrently, where at least one is a local teleport.
This is pretty much impossible on a manual user teleport but can happen on script-invoked teleports.
2012-05-21 21:33:59 +01:00
Justin Clark-Casey (justincc)
7e97f0e898 minor: extend commented out LinkInventoryItem log message for future use 2012-05-21 21:00:22 +01:00
Justin Clark-Casey (justincc)
16d303f7cd Fix bug where outfit folders could not be renamed.
Outfit folders are a type of system folder whose details are allowed to change.
2012-05-21 19:38:43 +01:00
Justin Clark-Casey (justincc)
0db60eea85 Improve locking of RegionCombinerModule.m_regions 2012-05-19 04:59:36 +01:00
Justin Clark-Casey (justincc)
5759313f7f Add size of region to OAR control file. Megaregions (sw root OARs when saved) will have a size larger than 256x256
Not yet read.  Do not rely on this information yet, it may change.
2012-05-19 04:56:47 +01:00
Justin Clark-Casey (justincc)
824a3a114b refactor: Add RegionConnection.PosX and PosY to return position in meters rather than copy/pasting the necessary calculations in lots of places. 2012-05-19 04:22:30 +01:00
Justin Clark-Casey (justincc)
fb8705dd4d refactor: Rename connection paramaters from "conn" and "regionConnections" so that it's easy to tell whether they refer to the root region connection or a new region connection 2012-05-19 04:01:05 +01:00
Justin Clark-Casey (justincc)
d7f90dee1c Correct some log messages in RegionCombinerModule about the position of the root region of a megaregion relative to an added region 2012-05-19 03:56:25 +01:00
Justin Clark-Casey (justincc)
4e5ac27928 Make the megaregion total area given to the physics module accurate instead of over-inflated.
This was previously over-inflated because adding a region to the NE of the root region resulted in double counting of regions already added.
An accurate extent will also be necessary for other purposes.
2012-05-19 03:45:58 +01:00
Justin Clark-Casey (justincc)
3f2a727b6d Remove recent IRegionCombinerModule.IsMegaregion(). In theory, there can be more than one megaregion in a simulator, separated by water.
Rename IsRootRegion() to IsRootForMegaregion()
2012-05-19 03:17:21 +01:00
Justin Clark-Casey (justincc)
26dfcf5395 Add some method doc to RegionCombinerModule. Clean up log messages. 2012-05-19 03:07:24 +01:00
Justin Clark-Casey (justincc)
33247c8d85 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-05-19 02:46:37 +01:00
Justin Clark-Casey (justincc)
2b60a5c5d6 Add is_megaregion flag into oar control file. Not currently read - for future use. Please do not rely on this remaining here.
An adaptation of part of Garmin's patch from http://opensimulator.org/mantis/view.php?id=5975, thanks!
Flag only written if the SW corner OAR is saved - this is the only one that captures object data presently (though not land or terrain data).
This adds an IRegionCombinerModule interface and the necessary methods on RegionCombinerModule
2012-05-19 02:45:17 +01:00
BlueWall
247a56593f Further refinement on properties 2012-05-18 20:02:32 -04:00
BlueWall
e338c15433 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-05-18 19:34:19 -04:00
BlueWall
895dadbdbd Cleanup + change properties to set fields with private set : Thanks Justin for the tip. 2012-05-18 19:34:12 -04:00
Justin Clark-Casey (justincc)
9fa0577c7e Enable FetchInventoryDescendents2 and FetchInventory2 caps by default. This appears to be required now for LL 3.3.1 to work properly.
Without this, LL 3.3.1 continually pushes LLInventoryModelFetchDescendentsResponder::error 499 to its log.
This cap will be ignored by older viewers - UDP inventory will work normally.
2012-05-19 00:00:52 +01:00
Justin Clark-Casey (justincc)
fc5d274229 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-05-18 23:56:44 +01:00
Justin Clark-Casey (justincc)
896cd45939 Fix issue where a new outfit folder is not created when a new outfit is saved if there are no previous outfits
This was because AddFolder() was disallowing these though they are legal.
2012-05-18 23:55:18 +01:00
BlueWall
c05f87b50c Provide Telehub setting to allow use of landmarks
Setting to allow use of landmarks to override telehub routing. Default is off.
2012-05-18 17:51:38 -04:00
Justin Clark-Casey (justincc)
0147dc6302 Fix build break. Comment out EQG deregister/register logging. 2012-05-18 03:50:23 +01:00
Justin Clark-Casey (justincc)
90722875e8 Add millisecond logging to pCampBot for debugging purposes 2012-05-18 03:44:31 +01:00
Justin Clark-Casey (justincc)
45af29291a Add level 2 debug eq logging which logs event queue polls.
Refactor: eq message logging into common method.
2012-05-18 03:43:36 +01:00
Justin Clark-Casey (justincc)
565c73751c Invoke log4net configurator in pCampBot.exe in order to get OpenSim sylte logging 2012-05-18 00:49:39 +01:00
Justin Clark-Casey (justincc)
6501b1b1bb refactor: move EventQueueGet path generation into common method. Rename some local variables in line with code conventions. Add commented out EQG log lines for future use. 2012-05-18 00:38:29 +01:00
Justin Clark-Casey (justincc)
b18c8c8e78 Don't eagerly clear frame collision events when physics actors subscribe and unsubscribe from collisions, in order to avoid a race condition.
Since this is done directly from ScenePresence, it can lead to a race condition with the simulator loop.
There's no real point doing it anyway since the clear will be done very shortly afterwards by the simulate loop and either there are no events (for a new avatar) or events don't matter (for a departing avatar).
This matches existing behaviour in OdePrim
2012-05-17 23:59:43 +01:00
Justin Clark-Casey (justincc)
521ad080f1 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-05-17 23:56:36 +01:00
Justin Clark-Casey (justincc)
4d34763f8c Check agent limit against root agent count rather than both root and child agents
From sl docs such as http://community.secondlife.com/t5/English-Knowledge-Base/Managing-Private-Regions/ta-p/700115
agent should apply to avatars only.
This makes sense from a user perspective, and also from a code perspective since child agents with no physics or actions take up a fraction of root agent resources.
As such, the check is now only performed in Scene.QueryAccess() - cross and teleport check this before allowing an agent to translocate.
This also removes an off-by-one error that could occur in certain circumstances on teleport when a new child agent was double counted when a pre-teleport agent update was performed.
This does not affect an existing bug where limits or other QueryAccess() checks are not applied to avatars logging directly into a region.
2012-05-17 23:33:26 +01:00
BlueWall
2af11fea37 Merge branch 'master' of /home/opensim/lib/osgrid/opensim 2012-05-17 00:49:33 -04:00
BlueWall
295bb3227d Force the default Telehub router if no matches are found in the config. 2012-05-17 00:47:19 -04:00
BlueWall
bd39f5f803 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-05-16 23:20:37 -04:00
BlueWall
0aa7baf49a Fix boo-boo in OpenSim.ini.example affecting telehub sequential routing
Configuration value should be "sequence" instead of "sequential"
2012-05-16 23:17:42 -04:00
Justin Clark-Casey (justincc)
c45b5a3d1c minor: improve method doc for TestSameSimulatorSeparatedRegionsCreateAgentFails() 2012-05-17 03:27:05 +01:00
Justin Clark-Casey (justincc)
d19fb6fb0c Add regression TestSameSimulatorSeparatedRegionsCreateAgentFails() 2012-05-17 03:12:31 +01:00
Justin Clark-Casey (justincc)
f0c9cb8dc0 Comment out TestSameSimulatorSeparatedRegionsQueryAccessFails() regression test logging accidentally left in 2012-05-17 01:34:04 +01:00
Justin Clark-Casey (justincc)
6b6a00a3d5 minor: Remove redundant EstateOwner != UUID.Zero check in IsAdministrator because checking EstateOwner == user
Due to an earlier check we already know that user != UUID.Zero so if EstateOwner == UUID.Zero, EstateOwner == user can never be true
2012-05-17 01:30:50 +01:00
Justin Clark-Casey (justincc)
bdcf2d1348 Add regression TestSameSimulatorSeparatedRegionsQueryAccessFails() 2012-05-17 01:27:59 +01:00
Justin Clark-Casey (justincc)
e444cb9da4 Remove redundant "Teleport failed:" from reason when QueryAccess fails for the destination simulator. This part of the string is already provided by the viewer.
Also adds more reason logging for diagnostics when teleports are refused/fail.
2012-05-17 00:33:04 +01:00
Justin Clark-Casey (justincc)
23ae24b406 Route OAR SOG loading through the common SceneObjectSerializer.FromXml2Format() rather than the functionally identical but buggy Xml2ToSOG().
Remove buggy Xml2ToSOG().
2012-05-16 00:10:42 +01:00
Justin Clark-Casey (justincc)
e644e34545 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-05-15 23:47:42 +01:00
Justin Clark-Casey (justincc)
1b5ce8c10e Fix issue where loading OARs could sometimes result in link numbers being reordered.
This was because the parts in scene objects were sometimes not serialized in link order.
This is perfectly fine since the parts still have the right link numbers, but an extra fix to adjust for this
had not been done in the SerialiserModule methods that OAR loading used.
Add regression test for same.
Addresses http://opensimulator.org/mantis/view.php?id=5948, http://opensimulator.org/mantis/view.php?id=5749
2012-05-15 23:43:59 +01:00
Justin Clark-Casey (justincc)
02f3b116c6 Allow use of regular expressions in "show object name", "show part name" and "delete object name" console commands if --regex switch is used.
Deleteing objects by name, creator uuid or owner uuid now requires confirmation to avoid accidental deletion.
2012-05-15 23:42:49 +01:00
Melanie
ef94c31ef8 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-05-15 03:17:42 +01:00
dahlia
1ce576b115 Add another null check to Melanie's last commit. Seems to eliminate sqlite errors in log but no idea if it's working properly 2012-05-14 19:34:18 -07:00
Melanie
65e1d7b2d7 Guard against null root part on SQLite. This really needs to be fixed so SQLite
loads roots before children like MySQL does.
2012-05-15 03:16:12 +01:00
Melanie
069bcd45e5 Try to fix sqlite breakage 2012-05-15 02:27:21 +01:00
Melanie
e7819ce909 Port Avination's collision fixes to core. 2012-05-15 01:02:38 +01:00
Oren Hurvitz
52a32878a9 Save the Telehub and its Spawn Points in the OAR 2012-05-14 19:59:45 +01:00
Justin Clark-Casey (justincc)
d7fd9b159a set executable bit for Ionic.Zip.dll for running OpenSimulator under cygwin 2012-05-14 19:36:26 +01:00
Justin Clark-Casey (justincc)
af6c85308a minor: add explanative comment to 'missing baked texture' logging commonly seen on inter-simulator teleports where avatar baked textures are not available from the asset service. 2012-05-14 18:57:42 +01:00
Justin Clark-Casey (justincc)
deeac69312 minor: comment out individual attachment transfer log messages for now 2012-05-14 18:48:40 +01:00
Justin Clark-Casey (justincc)
c2aa3b90d9 Set the agent in transit teleport flag at the first available opportunity (i.e. when IsInTransit() was being checked) to close down a race condition.
On EntityTransferModule.DoTeleport() there was an IsInTransit() check to prevent multiple simultaneous teleport attempts.
However, the SetInTransit() was only performed later on, which left a window in which multiple threads could pass the IsInTransit() check.
This has been seen in the field and the results aren't pretty.
This commit effectively combines the IsInTransit() and SetInTransit() checks so there is no such window.
More failure cases are made to to call ResetInTransit() to adjust to this move.
2012-05-14 18:36:26 +01:00
Justin Clark-Casey (justincc)
42557d7d4c Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-05-14 18:33:20 +01:00
Justin Clark-Casey (justincc)
fad557485c Add more region information to some teleport related logging 2012-05-14 18:06:48 +01:00
BlueWall
847127f83c Oops - missed the config changes 2012-05-14 00:15:56 -04:00
BlueWall
171480f235 Merge branch 'master' of /home/opensim/src/OpenSim 2012-05-13 17:40:03 -04:00
BlueWall
b80db81cdd Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-05-13 17:39:05 -04:00
Chris Koeritz
30a272ba31 Modifications for SMTP in OpenSimulator. Email size limit was fixed (was out of step with documentation at 1024, so boosted to 4096). Added configuration item for maximum email size. Redundant sleep inside email module was fixed (LSL Api was already sleeping). Added sleep time configuration item for snooze between email sending for LSL Api. Added two new configuration items (email_max_size and email_pause_time) into the example OpenSim.ini, plus fixed a spelling error (llimits) and odd tabbing.
Signed-off-by: BlueWall <jamesh@bluewallgroup.com>
2012-05-13 17:34:20 -04:00
BlueWall
7c229c8b81 Add configurable SpawnPointRouting
Will use one of three selected methods to route avatar landing
	points when using Telehubs. The setting is in [Startup] using
        SpawnPointRouting = closest/random/sequence

	closest: The default setting. Routes avatar to the nearest SpawnPoint
	to the location.

	random: Picks random SpawnPoints to land the avatar.

	sequence: Follows a sequence to place the avatar on the next available
	SpawnPoint location

Conflicts:

	OpenSim/Region/Framework/Scenes/Scene.cs
2012-05-13 17:20:54 -04:00
Justin Clark-Casey (justincc)
9d66792c2a Fix mono compiler warning.
Last jenkins failure looked like a glitch.
2012-05-12 03:04:47 +01:00
Justin Clark-Casey (justincc)
8b958e7e74 Revert "Save the Telehub and its Spawn Points in the OAR"
This reverts commit b0b7b45b94.

Sorry BlueWall, I wanted to discuss an aspect of the data storage but I couldn't assign bugs in 'patch included' state to myself until I changed mantis just now and I forgot to mention it on irc.
I wouldn't normally revert but thinks get tricky when it comes to data formats.
Essentially, I would like to see the Yaw, Pitch and Distance values as separate XML entities (as used in other aspects such as vectors, quaternions) rather than as a . delimited string
We can discuss this more with Oren in opensimulator.org/mantis/view.php?id=6008
2012-05-12 02:36:56 +01:00
Oren Hurvitz
b0b7b45b94 Save the Telehub and its Spawn Points in the OAR
Signed-off-by: BlueWall <jamesh@bluewallgroup.com>
2012-05-10 22:56:37 -04:00
Justin Clark-Casey (justincc)
480216f50f Print out more information on connecting bots 2012-05-11 02:38:29 +01:00
Justin Clark-Casey (justincc)
f231ac39de Increase minimum period between bot actions to 3 seconds, so that teleport doesn't fall under the minimum 2 second limits that clients take to process it 2012-05-11 02:23:18 +01:00
Justin Clark-Casey (justincc)
9c392f6a68 Stagger multiple bot logins by 5 seconds to make this part of the test more 'realistic'
TODO: Need to make this value configurable by a command line parameter to pCampbot
2012-05-11 02:05:32 +01:00
Justin Clark-Casey (justincc)
0ddf3c5289 Do bot startup on another thread so console is responsive during this process 2012-05-11 01:56:00 +01:00
Justin Clark-Casey (justincc)
93b615c51d Do each bot shutdown on its own threads to prevent one slow shutdown holding up all the rest.
This does increase the aggressiveness of shutdown
Also prevents the bot list being locked for a long period, which was preventing commands such as "show bots" from working during shutdown
2012-05-11 01:37:03 +01:00
Justin Clark-Casey (justincc)
dc39ec82fa Change bot.IsConnected to be ConnectionState with Disconnected, Connecting, Connnected and Disconnecting states 2012-05-11 00:53:21 +01:00
Justin Clark-Casey (justincc)
ab4e6a02a5 If a bot is not connected, show region name "(none)" instead of throwing an exception in the "show bots" command of pCampbot 2012-05-11 00:37:20 +01:00
Justin Clark-Casey (justincc)
903cff9264 Add ConsoleTable framework class for future uniform formatting of console output tables.
Still subject to change - if you use this be prepared to change your output code if/when the methods change.
Make new "attachments show" command use this.
2012-05-10 23:47:39 +01:00
Justin Clark-Casey (justincc)
abc029d1f4 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-05-10 23:43:38 +01:00
Justin Clark-Casey (justincc)
bce3e7cb06 Add "attachments" show console command that will show the server's record of which attachments an in-scene avatar has.
For debugging purposes.
2012-05-10 22:48:03 +01:00
Dan Lake
117c183fde Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-05-10 14:43:02 -07:00
Dan Lake
f374b63ac8 Add even for terrain tainting and synchronize terrain module with physics scene before physics simulation step rather than after 2012-05-10 14:42:46 -07:00
Mic Bowman
de44734fe9 Saving estate state is really slow (relatively) and it gets
completely rewritten every time a region starts up. This
makes the data write only when the data was not already
read from the database.

There is a still a major race condition whenever two regions
share the same estate data, but at least it won't be triggered
on startup.
2012-05-10 09:08:40 -07:00
Justin Clark-Casey (justincc)
d8a78374aa Where necessary, rename OpenSim/Services/Connectors/*.cs files to reflect the actual class names.
This is usually because the file name was singular (*Service*) but the class name was plural (*Services*).
This is to make configuration easier rather than having to look in the c# code itself to find the slightly different name of the connector.
This does not affect existing configuration since the files are being renamed rather than the classes.
2012-05-09 23:25:01 +01:00
Justin Clark-Casey (justincc)
6987aef38d Improve logging on the prim inventory script asset request path for future use.
This adds name and description of the request handler to http request logging when DebugLevel >= 1
2012-05-09 23:12:30 +01:00
Justin Clark-Casey (justincc)
e813f41478 Escape and unescape xml element names if necessary in ServerUtils.BuildXmlData() and ParseElement()
If AvatarService appearance data is retrieved over the network, then ServerUtils was attempting to transfer names such as "Wearable 0:0" directly to xml element names, resulting in an exception.
Space is not valid in xml element names.  Neither is : in this case since the intention is not to namespace.  Using names directly as keys is not a good idea.
To get around this problem this patch escapes and unescapes the element names as appropriate.
This has no impact on existing xml (since it had to be valid in the first place) but allows AvatarService data to be used over the network.
Setting appearance (from simulator to AvatarService) did not suffer this problem since the values are passed in the query string which is already properly escaped.
2012-05-09 21:11:14 +01:00
Talun
61e99bcdcb Mantis 6015 new LSL function llGetAgentList.
Details in the lsl wiki
2012-05-09 00:14:24 +01:00
Justin Clark-Casey (justincc)
e5dbb652d5 Remove physics actor related race conditions in SetVehicleFlags() and SetPhysicsAxisRotation()
sop.PhysActor can currently become null at any time.
2012-05-09 00:11:10 +01:00
Dan Lake
3bc5620d74 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-05-08 16:06:02 -07:00
Dan Lake
20952c75c5 Trigger event when scene presences are updated 2012-05-08 16:05:34 -07:00
Talun
c21c9e13ef Mantis 1456 same region teleport of a sitting avatar.
Region to region was fixed some time ago in EntityTransferModule.
This applies the same fix for same region teleports.
2012-05-09 00:02:13 +01:00
Justin Clark-Casey (justincc)
ef279c5a62 Add automated TestllBreakLink() 2012-05-08 23:36:23 +01:00
Justin Clark-Casey (justincc)
c0658a102e Add automated TestllCreateLink() 2012-05-08 23:29:51 +01:00
Justin Clark-Casey (justincc)
6406d5a5b9 refactor: Eliminate local id parameter from api initialize.
This is always available from m_host.LocalId
2012-05-08 23:20:27 +01:00
Justin Clark-Casey (justincc)
01b78235db Instead of constantly looking up unchanging self item in script code, pass in self item on initialization. 2012-05-08 23:05:01 +01:00
Justin Clark-Casey (justincc)
abbd050a13 Perform SceneGraph.DuplicateObject() under existing m_updateLock already used for link and delinking, in order to avoid race conditions.
DuplicateObject() relies on source object having correct link numbers for the duration of the dupe.
Both link and delink can change link numbers such that they are not consistent for short periods of time.
2012-05-08 21:31:35 +01:00
Justin Clark-Casey (justincc)
5d1d47e1f9 Revert "Better error handling if Load OAR or Save OAR fail"
This reverts commit 65c88b2ff4.

Yet again I accidentally committed something whilst evaluating it.
2012-05-07 20:01:17 +01:00
Oren Hurvitz
15844da3af Log the full exception when errors occur in BaseHttpServer 2012-05-07 19:56:00 +01:00
Oren Hurvitz
65c88b2ff4 Better error handling if Load OAR or Save OAR fail 2012-05-07 19:07:38 +01:00
Justin Clark-Casey (justincc)
a82dc263ab For osGetGridNick(), osGetGridName(), osGetGridLoginURI() and osGetGridCustom(), try to read from the [GridInfoService] section on standalone rather than [GridInfo]
[GridInfoService] is the section that's actually in bin/config-include/StandaloneCommon.ini.example
2012-05-07 19:05:21 +01:00
Justin Clark-Casey (justincc)
5053506d88 refactor: Instead of performing a ScenePresence lookup twice over LocateClientObject() and GetClientScene(), do the lookup just once in LocateClientObject() 2012-05-07 18:27:33 +01:00
Justin Clark-Casey (justincc)
cdf97ab3a6 Fix a bug in FriendsModule.StatusNotify() where all subsequent friends would not be notified once a non-local friend was found. 2012-05-07 17:21:45 +01:00
dahlia
4032455332 add a null check for Primitive.Sculpt in PrimitiveBaseShape constructor for OpenMetaverse.Primitive object 2012-05-07 00:33:50 -07:00
dahlia
4186fa10f0 remove default values from prior commit since mono cant deal with them 2012-05-07 00:08:56 -07:00
dahlia
b697d0e895 add OS_NPC_RUNNING option to osNpcMoveToTarget() to allow running speed for moving NPCs 2012-05-06 23:54:50 -07:00
Melanie
b60f51dafc Stop llSetPos from sending one update per child prim 2012-05-06 19:21:54 +01:00
nebadon
c11b3760da just another test :) 2012-05-05 14:49:10 -07:00
nebadon
f19fe50629 never say last test!! 2012-05-05 14:45:53 -07:00
nebadon
86dd5adceb one last test.. 2012-05-05 14:42:33 -07:00
nebadon
8d070cf47b last test clean up the mess.. 2012-05-05 14:32:40 -07:00
nebadon
531c52abe3 test #2 2012-05-05 13:59:40 -07:00
nebadon
9317b888f9 testing new opensimulator.org hardware out to make sure git still works! 2012-05-05 13:49:10 -07:00
Justin Clark-Casey (justincc)
01b00ad0d5 Fire the scripting changed event with CHANGED_OWNER when an object that has changed owners is rezzed.
This needs to occur after the script is resumed rather than before, when the event is just dropped.
Addresses http://opensimulator.org/mantis/view.php?id=5890 and http://opensimulator.org/mantis/view.php?id=5952
2012-05-05 00:29:14 +01:00
Justin Clark-Casey (justincc)
e18686528e Use the more efficient HashSet instead of List for FlotasmAssetCache.m_CurrentlyWriting 2012-05-04 23:03:33 +01:00
Justin Clark-Casey (justincc)
dec6ad2933 Don't try and update the access time of a file that is actively being cached.
This may cause IOErrors on Windows.
Aims to help with http://opensimulator.org/mantis/view.php?id=6003
2012-05-04 22:57:33 +01:00
Justin Clark-Casey (justincc)
da4819a170 Temporarily add debug log lines to lsl url request and release
To help with http://opensimulator.org/mantis/view.php?id=5993
2012-05-04 22:11:25 +01:00
Justin Clark-Casey (justincc)
c84ef57e52 minor: remove mono compiler warning 2012-05-04 21:04:42 +01:00
Talun
92fde6ed26 Mantis 60004 problems with damage and llSetDamage. In damage enabled areas this patch - Deletes any objects that have damage set > 0 that deliver that damage to an avatar Stops Gods receiving damage, Stops volume detect objects causing damage Deletes NPCS when their helth reduces to zero Gradually "heals" damage to an avatar Resets health on going to a non damage area 2012-05-04 21:01:09 +01:00
Justin Clark-Casey (justincc)
6096a1f30e Change LongCallTime on WebUtil to 3000, to match the time where request handling is considered "slow".
This may be the wrong thing to do but stops lots of log spam in HG setups now that the monitoring is extended to other outgoing calls.
LongCallTime may need to be made configurable.
2012-05-04 20:53:30 +01:00
Justin Clark-Casey (justincc)
e83bc049df refactor: Rename new DeleteFoldersEx/PurgeFoldersEx methods to DeleteFolders/PurgeFolders overloads as previously discussed with Oren - I think this makes more sense on balance
These overloads are not publicly available on core connectors or IInventoryService.
2012-05-04 20:37:21 +01:00
Oren Hurvitz
ad23774433 Allow deleting folders even if they're not in the Trash
The functions DeleteFolders() and PurgeFolder() still work as before, i.e. they only allow deleting folders that are in the Trash. However, the functions DeleteFoldersEx() and PurgeFolderEx() can now be used to delete any folder.
2012-05-04 20:30:46 +01:00
Justin Clark-Casey (justincc)
cccef2e56d Calculate the Daylight Savings Time information sent to the viewer based on US Pacific Standard Time rather than whatever timezone the login server is set to.
This is because the viewer doesn't receive a timezone from the server but bases its displays on Pacific Standard Time.
However, it still expects to receive notification from the server as to whether or not Daylight Savings Time for PST is in operation.
This commit introduces a new DSTZone setting in the [LoginService] config setting that accepts a list of timezone names valid across different platforms to calculate Pacific DST.
If you need the old behaviour of calculating DST based on the local timezone of the server running the login service, then please override DSTZone with "local".
A mailing list announcement will be made later.
Thanks to Olivier Van Helden and Gudule Lapointe for determining this behaviour and providing this patch.
From http://opensimulator.org/mantis/view.php?id=5972
2012-05-04 19:21:43 +01:00
Justin Clark-Casey (justincc)
fb99ee6774 minor: Tweak BaseHttpServer message to make it clear that this relates to slow handling of inbound requests. 2012-05-04 01:16:56 +01:00
Justin Clark-Casey (justincc)
c9faf0df74 Extend 'slow' request logging to other server outbound requests (forms, rest, async rest) as well as the existing logging on outbound OSD requests.
Also prints out the first 100 chars of any slow request data since this can contain useful info (such as agent ID).
2012-05-04 01:12:56 +01:00
Justin Clark-Casey (justincc)
c221eaf0b0 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-05-03 22:39:04 +01:00
Justin Clark-Casey (justincc)
fcd5b0817b Reinsert a 2000ms delay before closing a no longer required agent on the source region after teleport to resolve Imprudence teleport problems.
Viewers 1 and 3 are fine with doing this immediately.  However, Imprudence has a small delay (<200ms, >500ms) after receiving the AgentCompleteMovement reply packet on the destination region before regarding that region as the currnet region.
If Imprudence receives a DisableSimulator in this period, it quits.
We are not restoring the full 5000ms delay since this brings back a bug where teleports permanently fail if an avatar tries to teleport back too quickly.
This commit also sends the AgentCompleteMovement packet to the client before telling the source region to release its old agent, in order to further cut down any possibility of the DisableSimulator being recieved before the AgentMovementComplete.
2012-05-03 22:30:36 +01:00
Snoopy Pfeffer
100e4ca67e Fixes Mantis #5999. llSetLinkPrimitiveParams with PRIM_BUMP_SHINY did cause a runtime error. 2012-05-03 19:00:09 +02:00
Justin Clark-Casey (justincc)
bf5f8b54ae Remove the somewhat misleading logging of the string length of some unknown requests, as this appeared to be some kind of numbered error code.
This brings these messages into line with similar messages that did not do this.
2012-05-03 02:22:06 +01:00
Justin Clark-Casey (justincc)
9ffc2c1062 minor: resolve some mono compiler warnings 2012-05-03 01:56:24 +01:00
Justin Clark-Casey (justincc)
231a3bf147 Implement optional name and description on http stream handlers so that we can relate a slow request to what the handler actually does and the agent it serves, if applicable.
This is most useful for capabilities where the url is not self-describing.
2012-05-03 01:45:49 +01:00
Justin Clark-Casey (justincc)
40f3c24562 Comment out the five second sleep in etm.DoTeleport() if the old agent needs to be closed because it is no longer in the child's view distance.
This sleep appears unnecessary since a sleep has already occurred in WaitForCallback() whilst waiting for the destination region to notify of teleport success.
There are no async operations between this sleep and the WaitForCallback()
If this sleep is present, then teleporting back to the source region within 5 seconds results in a disconnection.
If this sleep is commented out then teleporting quickly back and forth between two simulators appears to work without issue.
Tested on standalone, local grid and distributed grid.
Please revert if there's something that I've missed.
2012-05-01 23:49:02 +01:00
Justin Clark-Casey (justincc)
a29f7f7551 Remove some test code that accidentally crept in with 9d2e1c67 2012-05-01 23:25:30 +01:00
Justin Clark-Casey (justincc)
9d2e1c67a8 Add regression test for teleporting between neighbouring regions on the same simulator
This adds a non-advertised wait_for_callback option in [EntityTransfer].  Default is always true.
Teleport tests disable the wait for callback from the destination region in order to run within a single thread.
2012-05-01 23:14:12 +01:00
Justin Clark-Casey (justincc)
5786521103 Move max teleport distance check down into etm.DoTeleport() since this should apply to all teleport calls, not just those through Teleport() 2012-05-01 18:38:46 +01:00
Justin Clark-Casey (justincc)
37dd174697 refactor: Split most of EntityTransferModule.Teleport() into its same region and different region teleport components.
DoTeleport() now retrives IEventQueue itself rather than requiring it to be passed in.
2012-05-01 17:52:30 +01:00
Justin Clark-Casey (justincc)
b678ea18b2 Create TestHelpers.EnableLogging() and DisableLogging() to turn logging on and off within tests.
This makes *.Tests.dll.config files no longer needed, hence deleted.
2012-04-30 18:44:22 +01:00
Justin Clark-Casey (justincc)
cc482d2d56 Add TBG Renfold to contributors 2012-04-30 17:39:11 +01:00
TBG Renfold
9c2a73b61e llGenerateKey implementation. Creates a random UUID I.E: UUID.Random().ToString();
Signed-off-by: TBG Renfold <tbg.renfold@g2mv.co.uk>
2012-04-30 17:36:49 +01:00
Justin Clark-Casey (justincc)
d0598c63f3 refactor: Simplify by combining SafeSendControlsToScripts() from fe8e835 into SendControlsToScripts() (instead of SendControlToScripts()). 2012-04-30 17:33:08 +01:00
Oren Hurvitz
fe8e835bfc Fixed: scripted controls didn't work if the avatar was sitting down
This fixes a bug introduced in 6473674bbf
2012-04-30 17:18:15 +01:00
Justin Clark-Casey (justincc)
4ad45934c6 If there are no new prim items to store then don't bother opening the MySqlConnection only to do nothing with it. 2012-04-30 16:00:31 +01:00
Justin Clark-Casey (justincc)
522eff6138 Consistently use using() to make sure we dispose of used MySqlCommands where this is not already being done. 2012-04-30 15:54:35 +01:00
Justin Clark-Casey (justincc)
8380166251 Comment out debug [ASYNC DELETER] messages for now. 2012-04-28 00:39:40 +01:00
Justin Clark-Casey (justincc)
cd755fe598 Remove mono compiler warning. Adjust message log to error from info 2012-04-28 00:31:11 +01:00
Justin Clark-Casey (justincc)
133f05dc41 Add text about using double quotes to surround console command arguments containing spaces to "help" text.
e.g. show object name "My long object name"
2012-04-28 00:29:08 +01:00
Justin Clark-Casey (justincc)
2bad430ed8 Put scene object related console commands into new "Objects" help category rather than "Regions" 2012-04-28 00:08:04 +01:00
Justin Clark-Casey (justincc)
ab71779221 Revert "Revert "Implement bulk inventory update over CAPS (not recursive by design,""
This reverts commit a90b0e302c.

Sorry, accidentally reverted this completely by mistake, reverting the revert.
2012-04-27 23:54:45 +01:00
Justin Clark-Casey (justincc)
737e177163 Revert "Log the full exception when errors occur in BaseHttpServer"
This reverts commit e31e7c68c8.

Applied for patch assessment and accidentally committed too early.
2012-04-27 23:46:46 +01:00
Justin Clark-Casey (justincc)
a90b0e302c Revert "Implement bulk inventory update over CAPS (not recursive by design,"
This reverts commit 6e7f13a72d.
2012-04-27 23:46:33 +01:00
Justin Clark-Casey (justincc)
da29cbccfa Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-04-27 23:39:13 +01:00
Justin Clark-Casey (justincc)
d25469f66e Add flags information (phantom, physics, etc.) to "show object" and "show part" console commands 2012-04-27 23:38:25 +01:00
Oren Hurvitz
e31e7c68c8 Log the full exception when errors occur in BaseHttpServer 2012-04-27 21:52:04 +01:00
BlueWall
db566fbb09 Fix prebuild.xml
adding a reference to a dll requires 'path="..."'
2012-04-27 16:17:46 -04:00
Oren Hurvitz
6473674bbf Fixed: custom walking animations didn't stop when the avatar stopped walking.
This happened because the scripts were notified about control changes (e.g., the user stopped pressing the Forward key) when the animation was still WALK, so the script didn't stop the walking animation. Fixing this required: a) Update the movement animation *before* notifying the script; b) Add locking to prevent clashes with the Heartbeat thread (which also updates the animations); c) Handle the case of a user who stops walking just as the avatar is in the air: the avatar should STAND in that case, not WALK.

This reverts commit feef1dd732.
2012-04-27 20:47:02 +01:00
Oren Hurvitz
9622e8ac72 If a Grid God teleports then include the Godlike teleport flag. This can affect the starting position in the destination region. 2012-04-27 20:22:35 +01:00
Oren Hurvitz
37d770f814 Use DotNetZip to compress OARs and IARs.
DotNetZip provides much better compression than standard .NET.
2012-04-27 19:46:31 +01:00
Justin Clark-Casey (justincc)
9d1791def8 Add Stefan_Boom / stoehr to contributors 2012-04-27 19:42:12 +01:00
Justin Clark-Casey (justincc)
e39e4f6bfb minor: style adjustments in SensorRepeat, mainly related to patch from stoehr 2012-04-27 19:40:19 +01:00
Stefan_Boom
b35a1d5681 Fixing wrong position of llSensor, SensePoint wasnt following the rotation of the root prim. 2012-04-27 19:31:50 +01:00
Diva Canto
9bc94c502a MapImageService: changed the event at which the map tiles are uploaded, because they were being uploaded before the region was registered with the grid 2012-04-27 11:05:40 -07:00
Diva Canto
a9dbe39319 MapImage security issue. Compare strings instead of IPAddresses. 2012-04-27 10:39:20 -07:00
Diva Canto
292752bb78 MapImage security issue: better error messages 2012-04-27 10:22:43 -07:00
Diva Canto
ac64fe03d8 Amend to last commit: account for the existence of proxies. 2012-04-27 09:59:46 -07:00
Diva Canto
2970a18e54 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-04-27 09:26:14 -07:00
Diva Canto
c84f63f4dc Minor change in error message (HG teleport failures) 2012-04-27 09:24:50 -07:00
Diva Canto
e4e754ee93 MapImageService: added an additional security check for OSGrid and other grids like it. 2012-04-27 09:23:56 -07:00
Justin Clark-Casey (justincc)
07e62df558 Add regression test for teleporting an agent between separated regions on the same simulator.
This involves a large amount of change in test scene setup code to allow test scenes to share shared modules
SetupScene is now an instance method that requires an instantiation of SceneHelpers, though other SceneHelpers methods are still static
May split these out into separate classes in the future.
2012-04-27 00:58:54 +01:00
Oren Hurvitz
8a65f5a70d OSSL: Removed check for CanRunConsoleCommand() in osKickAvatar.
OSSL permissions are now controlled in OpenSim.ini.
2012-04-26 22:53:13 +01:00
Oren Hurvitz
0da8fe3124 Refactored how asset/inventory types are associated with content types: gathered all the knowledge into a single class. Added the Mesh content type. 2012-04-26 22:49:14 +01:00
Oren Hurvitz
ee13d817f1 When creating an OAR, objects where the user is the Creator are always included, regardless of their permissions.
The purpose of the permission checks is to prevent the unauthorized copying of assets, but users can always copy assets that they created.
2012-04-26 22:41:31 +01:00
Justin Clark-Casey (justincc)
cb6791fb30 Tweak log messages on local region to region teleport path to help with problem resolution. 2012-04-26 22:35:25 +01:00
Justin Clark-Casey (justincc)
d19aa9e792 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-04-26 21:54:50 +01:00
BlueWall
2542ca2a49 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-04-26 16:40:36 -04:00
BlueWall
fba802bb03 Merge branch 'master' of /home/opensim/var/repo/opensim 2012-04-26 16:13:47 -04:00
Talun
b8114d2b67 Add a version of osNpcSay that takes a channel number Mantis 5747
osNpcSay(UUID npc, string message) left untouched

New functions:-
osNpcSay(UUID npc, int channel, string message)
osNpcShout(UUID npc, int channel, string message)
osNpcWhisper(UUID npc, int channel, string message)

Signed-off-by: BlueWall <jamesh@bluewallgroup.com>
2012-04-26 16:13:29 -04:00
Justin Clark-Casey (justincc)
ca228c4770 Comment out old Scene.HandleLogOffUserFromGrid() to reduce client closing analysis complexity 2012-04-26 16:20:53 +01:00
Justin Clark-Casey (justincc)
f49912f92a minor: Add more detail to unauthorized caps client message 2012-04-26 16:10:24 +01:00
Justin Clark-Casey (justincc)
b0cbf16c19 minor: Add region name to dropped inbound packet message 2012-04-26 16:04:49 +01:00
Justin Clark-Casey (justincc)
4c4ffb9868 Add request verb and url to error messages in WebUtil that lack this.
Make exception printing consistent across windows and mono.
2012-04-26 00:43:31 +01:00
Justin Clark-Casey (justincc)
e52fe03fff minor: Add avatar name to removing agent log message 2012-04-26 00:42:37 +01:00
Justin Clark-Casey (justincc)
74dbfe6bb5 Comment out avatar move to target message for now. 2012-04-25 23:46:42 +01:00
Mic Bowman
133370f158 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-04-25 11:57:29 -07:00
Mic Bowman
a2d544c938 Add a configuration switch to turn on/off the use of the trash
folder when deleting objects from a scene. The use of the trash
folder causes assets to be created and stored everytime you delete
an object from the scene (slows down the delete and adds mostly useless
assets to your database).

Default is on (use the trash folder) which is the standard behavior.
2012-04-25 11:54:57 -07:00
Melanie
88553bb884 Port Avination link order to make OpenSim behave like SL. Make Primstar scripts work. Fixes Mantis #5990 2012-04-25 19:09:22 +01:00
Mic Bowman
1afae01311 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-04-25 09:52:44 -07:00
Mic Bowman
bec100a662 Add try/catch around Json script method registration to avoild some issues
with .NET 3.5 vs 4.0 differences.

See http://opensimulator.org/mantis/view.php?id=5971
2012-04-25 09:51:30 -07:00
Diva Canto
7aa25c6762 Slight rewording of output messages. 2012-04-24 22:40:07 -07:00
Diva Canto
fd281ded3f Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-04-24 22:17:52 -07:00
Diva Canto
cf1c34605b HG: Moved User-level code down to the HGEntityTransferModule where it belongs. 2012-04-24 22:17:10 -07:00
Melanie
550ff3b4da Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-04-25 04:01:55 +01:00
Melanie
3be3189ee0 Commit the avination Teleport() methods (adaptedto justincc's changes) 2012-04-25 04:00:01 +01:00
Justin Clark-Casey (justincc)
af86e2939c zero out SP velocity before calling SP.Teleport(), as the client expects (though this is also effectively done by physics at the moment) 2012-04-25 03:47:26 +01:00
Justin Clark-Casey (justincc)
683cfc6f82 refactor: Combine ScenePresence.Teleport() and TeleportWithMomentum()
These are identical apart from setting Velocity = zero, which has no practical effect anyway since this is zeroed when the avatar is added back to the physics scene.
2012-04-25 02:07:55 +01:00
Justin Clark-Casey (justincc)
a65ca24701 Add regression test TestSameRegionTeleport() 2012-04-25 01:51:40 +01:00
Justin Clark-Casey (justincc)
f24289c47f Comment out AvatarService.SetAvatar debug log line for now 2012-04-25 01:09:23 +01:00
Justin Clark-Casey (justincc)
6b299a4287 Comment out some debug ATTACHMENTS log messages for now. 2012-04-25 00:52:33 +01:00
Justin Clark-Casey (justincc)
39a6d7cab4 Comment out the noisier AVFACTORY log messages for now.
Permanently comment out warnings about ScenePresence not being found - this is entirely expected if the avatar has alraedy logged out or left the scene.
2012-04-25 00:47:32 +01:00
Justin Clark-Casey (justincc)
0f470326aa Improve teleport log debug and error messages to tell us who is teleporting. 2012-04-25 00:19:38 +01:00
Justin Clark-Casey (justincc)
54d5ff6774 Go back to always using the local timezone for now - not all machines have US/Pacific or Olsen Amercia/Los_Angeles and this introduces variability that the server operator cannot control
Please see http://opensimulator.org/mantis/view.php?id=5972 soon for more comments.
2012-04-24 23:00:50 +01:00
Justin Clark-Casey (justincc)
ef1668adb3 Revert "Refactored how asset/inventory types are associated with content types: gathered all the knowledge into a single class. Added the Mesh content type."
This reverts commit d3a4d67a20.

Accidentally committed this when I didn't mean to yet.
2012-04-24 21:42:32 +01:00
Oren Hurvitz
2f398231ac Minor improvements to logging
Eliminated an extra newline in the console if the log line doesn't contain a category (example of a category: "[ASSETS]").
2012-04-24 21:38:09 +01:00
Oren Hurvitz
d3a4d67a20 Refactored how asset/inventory types are associated with content types: gathered all the knowledge into a single class. Added the Mesh content type. 2012-04-24 20:52:18 +01:00
Oren Hurvitz
da5fd53702 Fixed problem with MySQL: it was possible for one thread to use an incomplete list of column names if another thread was creating the list at the same time. Now this is thread-safe. 2012-04-24 20:49:28 +01:00
Oren Hurvitz
c70e85a327 When reading a region, use null objects to represent NULL fields.
Previously NULL fields were converted to an empty string due to the use of ToString(). But if the field was an Int (e.g., "locZ"), then the subsequent attempt to convert an empty string to an int caused an exception. Now the field is null so we don't try to convert it, so there's no exception.
2012-04-24 20:46:31 +01:00
Oren Hurvitz
6011bfa5e3 OSSL: fixed the threat level check for osParseJSONNew 2012-04-24 20:41:29 +01:00
Justin Clark-Casey (justincc)
cbe889e10b minor: formatting changes to top of LLLoginResponse.SetDefaultValues(), chiefly some break up of the long line. 2012-04-24 20:30:19 +01:00
Olivier van Helden and Gudule Lapointe (Speculoos.net)
0e3053e4c9 DST settings to match client default Pacific Time (mantis #5972) 2012-04-24 20:22:34 +01:00
Justin Clark-Casey (justincc)
c6f30e044b Restore _parent_scene.actor_name_map[prim_geom] = this; accidentally removed from ODEPrim.SetGeom.
This occurred in 7a574be3fd from Sat 21 Apr 2012.
This should fix collision detection.
Mnay thanks to tglion for the spot and the fix in http://opensimulator.org/mantis/view.php?id=5988
2012-04-24 20:15:10 +01:00
Diva Canto
fd27988978 Changed the Map-related messages from Info to Debug. They're debug messages. 2012-04-23 21:29:18 -07:00
Justin Clark-Casey (justincc)
6c21e15cb9 Add online/offline indicator to "friends show" region console command.
Improve output table formatting.
2012-04-24 00:32:01 +01:00
Justin Clark-Casey (justincc)
40e37d8b78 Add osForceAttachToAvatar() and osForceDetachFromAvatar()
These behave identically to llAttachToAvatar() and llDetachFromAvatar() except that they do not enforce the PERMISSION_ATTACH check
Intended for use in completely controlled dedicated environments where these checks are more a UI hinderance than a help.
Threat level high.
2012-04-24 00:03:57 +01:00
Justin Clark-Casey (justincc)
b798b32b19 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-04-23 22:54:11 +01:00
Justin Clark-Casey (justincc)
1f8d1bcdcf Replace common code to fetch self inventory item (as opposed to uuid) with GetSelfInventoryItem()
However, at some point it would be far more convenient to receive the TaskInventoryItem in the constructor rather than just the item UUID, so we don't have to constantly refetch our self item.
2012-04-23 22:52:46 +01:00
Justin Clark-Casey (justincc)
60065f06b3 refactor: Replace calls to InventorySelf() with existing m_itemID in LSL_Api
There's no point look up an item ID that we already have.
2012-04-23 22:23:47 +01:00
Talun
679da63da6 Mantis 5977 Corrections to llRegionSayTo
Signed-off-by: BlueWall <jamesh@bluewallgroup.com>
2012-04-23 07:16:33 -04:00
Justin Clark-Casey (justincc)
49ed68e98c refactor: simply some properties code in BasicPhysicsPlugin 2012-04-22 20:28:12 +01:00
Justin Clark-Casey (justincc)
58c890df5d Make TestSetPhysicsSinglePrim() actually add the object to the scene in order to test more code paths. 2012-04-22 20:03:34 +01:00
Justin Clark-Casey (justincc)
8205fe79ce Fix bug where setting phantom on a prim would result in a server log message rather than setting phantom.
This was an oversight when removing some race conditions from PhysicsActor setting recently.
Regression tests extended to probe this code path.
Extending regression tests required implementation of a BasicPhysicsPrim (there was none before).  However, BasicPhysics plugin is still of no current practical use other than to fill in as a component for other parts of regression testing.
2012-04-22 19:51:51 +01:00
Justin Clark-Casey (justincc)
ae2b8f7007 Comment out spurious Body != IntPtr.Zero code after disableBody(), since disableBody() sets Body == IntPtr.Zero on all code paths. 2012-04-21 03:42:54 +01:00
Justin Clark-Casey (justincc)
f609594595 refactor: Simplify ODEPrim.AddChildPrim() by returning early where appropriate. 2012-04-21 03:23:51 +01:00
Justin Clark-Casey (justincc)
77a7de87e1 Add test for setting physics in a linkset 2012-04-21 02:45:16 +01:00
Justin Clark-Casey (justincc)
d5c724e5b8 Add regression test for prim status when root prim in a new linkset is non-physical 2012-04-21 01:51:57 +01:00
Justin Clark-Casey (justincc)
9ac48b2aff Fix a bug where linking a non-physical prim with a physical prim as root would make the non-physical prim phantom rather than part of the physics object.
On region restart, the whole object would become physical as expected.
Observed behaviour from elsewhere is that all prims in a new linkset should take on the status of the root prim.
Add regression test for this behaviour.
2012-04-21 01:43:09 +01:00
Justin Clark-Casey (justincc)
17bf2a62db Add test for correct physics status on linking two physics objects
Also fixes last build break.
2012-04-21 01:09:42 +01:00
Justin Clark-Casey (justincc)
71900968b2 refactor: extract common setup code in SceneObjectStatusTests 2012-04-21 01:01:24 +01:00
Justin Clark-Casey (justincc)
ae789f6c16 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-04-21 00:55:27 +01:00
Justin Clark-Casey (justincc)
06552f217e Add TestSetPhysics() to SOP status tests 2012-04-21 00:54:48 +01:00
Justin Clark-Casey (justincc)
7a574be3fd Remove redundant prim_geom != IntPtr.Zero checks in ODEPrim.
prim_geom == IntPtr.Zero only before a new add prim taint is processed (which is the first taint) or in operations such as scale change which are done in taint or under lock.
Therefore, we can remove these checks which were not consistently applied anyway.
If there is a genuine problem, better to see it quickly in a NullReferenceException than hide the bug.
2012-04-21 00:12:07 +01:00
Justin Clark-Casey (justincc)
c8307cdf1e Improve bitmap disposal to do null checks and not to potentially try disposal of uninitialized variables.
This issue doesn't cause the mono 2.10.5 compiler to fail but appears to cause the windows compiler to fail.
Resolves http://opensimulator.org/mantis/view.php?id=5973
2012-04-20 23:35:11 +01:00
Justin Clark-Casey (justincc)
566327a948 If a physical prim is manually moved (e.g. by a user) then set the geometry position as well as the body position
This is necessary to stop the moved prim snapping back to the original position on deselection if moved only once
This resolves http://opensimulator.org/mantis/view.php?id=5966
2012-04-20 23:24:24 +01:00
Justin Clark-Casey (justincc)
75f117484b Always dispose of existing opened bitmap from file in SaveFile(), instead of simply dropping the reference if the existing file didn't contain a bitmap of the same size. 2012-04-20 03:57:22 +01:00
432 changed files with 16175 additions and 8791 deletions

View File

@@ -143,8 +143,11 @@ what it is today.
* sempuki
* SignpostMarv
* SpotOn3D
* Stefan_Boom / stoehr
* Strawberry Fride
* Talun
* TechplexEngineer (Blake Bourque)
* TBG Renfold
* tglion
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
* tyre
@@ -203,3 +206,4 @@ In addition, we would like to thank:
* The Mono Project
* The NANT Developers
* Microsoft (.NET, MSSQL-Adapters)
*x

View File

@@ -122,9 +122,10 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
Thread.CurrentThread.ManagedThreadId.ToString() +
")");
m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]);
bool changed = m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]);
m_openSim.CreateRegion(regionsToLoad[i], true, out scene);
regionsToLoad[i].EstateSettings.Save();
if (changed)
regionsToLoad[i].EstateSettings.Save();
if (scene != null)
{

View File

@@ -539,7 +539,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
/// path has not already been registered, the method is added to the active
/// handler table.
/// </summary>
public void AddStreamHandler(string httpMethod, string path, RestMethod method)
{
if (!IsEnabled)

View File

@@ -101,18 +101,8 @@ namespace OpenSim.Capabilities.Handlers
llsdItem.item_id = invItem.ID;
llsdItem.name = invItem.Name;
llsdItem.parent_id = invItem.Folder;
try
{
llsdItem.type = Utils.AssetTypeToString((AssetType)invItem.AssetType);
llsdItem.inv_type = Utils.InventoryTypeToString((InventoryType)invItem.InvType);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[WEB FETCH INV DESC HANDLER]: Problem setting asset {0} inventory {1} types while converting inventory item {2}: {3}",
invItem.AssetType, invItem.InvType, invItem.Name, e.Message);
}
llsdItem.type = invItem.AssetType;
llsdItem.inv_type = invItem.InvType;
llsdItem.permissions = new LLSDPermissions();
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
@@ -126,21 +116,7 @@ namespace OpenSim.Capabilities.Handlers
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
llsdItem.sale_info = new LLSDSaleInfo();
llsdItem.sale_info.sale_price = invItem.SalePrice;
switch (invItem.SaleType)
{
default:
llsdItem.sale_info.sale_type = "not";
break;
case 1:
llsdItem.sale_info.sale_type = "original";
break;
case 2:
llsdItem.sale_info.sale_type = "copy";
break;
case 3:
llsdItem.sale_info.sale_type = "contents";
break;
}
llsdItem.sale_info.sale_type = invItem.SaleType;
return llsdItem;
}

View File

@@ -63,7 +63,8 @@ namespace OpenSim.Capabilities.Handlers
FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService);
IRequestHandler reqHandler
= new RestStreamHandler("POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest);
= new RestStreamHandler(
"POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest, "FetchInventory", null);
server.AddStreamHandler(reqHandler);
}
}

View File

@@ -66,13 +66,14 @@ namespace OpenSim.Capabilities.Handlers
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(),
delegate(Hashtable m_dhttpMethod)
{
return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null);
});
IRequestHandler reqHandler
= new RestHTTPHandler(
"GET",
"/CAPS/" + UUID.Random(),
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
"GetMesh",
null);
server.AddStreamHandler(reqHandler);
}
}
}
}

View File

@@ -58,8 +58,8 @@ namespace OpenSim.Capabilities.Handlers
// TODO: Change this to a config option
const string REDIRECT_URL = null;
public GetTextureHandler(string path, IAssetService assService) :
base("GET", path)
public GetTextureHandler(string path, IAssetService assService, string name, string description)
: base("GET", path, name, description)
{
m_assetService = assService;
}
@@ -77,7 +77,6 @@ namespace OpenSim.Capabilities.Handlers
{
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return null;
}
UUID textureID;
@@ -115,7 +114,6 @@ namespace OpenSim.Capabilities.Handlers
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
httpResponse.Send();
return null;
}

View File

@@ -62,8 +62,8 @@ namespace OpenSim.Capabilities.Handlers
if (m_AssetService == null)
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
server.AddStreamHandler(new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService));
server.AddStreamHandler(
new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null));
}
}
}
}

View File

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

View File

@@ -85,8 +85,8 @@ namespace OpenSim.Capabilities.Handlers
uploader.OnUpLoad += BakedTextureUploaded;
m_HostCapsObj.HttpListener.AddStreamHandler(
new BinaryStreamHandler("POST", capsBase + uploaderPath,
uploader.uploaderCaps));
new BinaryStreamHandler(
"POST", capsBase + uploaderPath, uploader.uploaderCaps, "UploadBakedTexture", null));
string protocol = "http://";

View File

@@ -156,11 +156,12 @@ namespace OpenSim.Capabilities.Handlers
inv.Folders = new List<InventoryFolderBase>();
inv.Items = new List<InventoryItemBase>();
int version = 0;
int descendents = 0;
inv
= Fetch(
invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version);
invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version, out descendents);
if (inv != null && inv.Folders != null)
{
@@ -168,6 +169,8 @@ namespace OpenSim.Capabilities.Handlers
{
contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
}
descendents += inv.Folders.Count;
}
if (inv != null && inv.Items != null)
@@ -178,7 +181,7 @@ namespace OpenSim.Capabilities.Handlers
}
}
contents.descendents = contents.items.Array.Count + contents.categories.Array.Count;
contents.descendents = descendents;
contents.version = version;
// m_log.DebugFormat(
@@ -206,7 +209,7 @@ namespace OpenSim.Capabilities.Handlers
/// <returns>An empty InventoryCollection if the inventory look up failed</returns>
private InventoryCollection Fetch(
UUID agentID, UUID folderID, UUID ownerID,
bool fetchFolders, bool fetchItems, int sortOrder, out int version)
bool fetchFolders, bool fetchItems, int sortOrder, out int version, out int descendents)
{
// m_log.DebugFormat(
// "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
@@ -215,6 +218,8 @@ namespace OpenSim.Capabilities.Handlers
// FIXME MAYBE: We're not handling sortOrder!
version = 0;
descendents = 0;
InventoryFolderImpl fold;
if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner)
{
@@ -223,6 +228,7 @@ namespace OpenSim.Capabilities.Handlers
InventoryCollection ret = new InventoryCollection();
ret.Folders = new List<InventoryFolderBase>();
ret.Items = fold.RequestListOfItems();
descendents = ret.Folders.Count + ret.Items.Count;
return ret;
}
@@ -246,24 +252,72 @@ namespace OpenSim.Capabilities.Handlers
version = containingFolder.Version;
// if (fetchItems)
if (fetchItems)
{
List<InventoryItemBase> itemsToReturn = contents.Items;
List<InventoryItemBase> originalItems = new List<InventoryItemBase>(itemsToReturn);
// descendents must only include the links, not the linked items we add
descendents = originalItems.Count;
// Add target items for links in this folder before the links themselves.
foreach (InventoryItemBase item in originalItems)
{
if (item.AssetType == (int)AssetType.Link)
{
InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
// Take care of genuinely broken links where the target doesn't exist
// HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
// but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
// rather than having to keep track of every folder requested in the recursion.
if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
itemsToReturn.Insert(0, linkedItem);
}
}
// Now scan for folder links and insert the items they target and those links at the head of the return data
foreach (InventoryItemBase item in originalItems)
{
if (item.AssetType == (int)AssetType.LinkFolder)
{
InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID);
List<InventoryItemBase> links = linkedFolderContents.Items;
itemsToReturn.InsertRange(0, links);
foreach (InventoryItemBase link in linkedFolderContents.Items)
{
// Take care of genuinely broken links where the target doesn't exist
// HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
// but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
// rather than having to keep track of every folder requested in the recursion.
if (link != null)
{
// m_log.DebugFormat(
// "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}",
// link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name);
InventoryItemBase linkedItem
= m_InventoryService.GetItem(new InventoryItemBase(link.AssetID));
if (linkedItem != null)
itemsToReturn.Insert(0, linkedItem);
}
}
}
}
}
// foreach (InventoryItemBase item in contents.Items)
// {
// List<InventoryItemBase> linkedItemsToAdd = new List<InventoryItemBase>();
//
// foreach (InventoryItemBase item in contents.Items)
// {
// if (item.AssetType == (int)AssetType.Link)
// {
// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
//
// // Take care of genuinely broken links where the target doesn't exist
// // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
// // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
// // rather than having to keep track of every folder requested in the recursion.
// if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
// linkedItemsToAdd.Insert(0, linkedItem);
// }
// }
// m_log.DebugFormat(
// "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}",
// item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID);
// }
// =====
//
// foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
// {
@@ -340,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;
}
@@ -365,18 +415,8 @@ namespace OpenSim.Capabilities.Handlers
llsdItem.item_id = invItem.ID;
llsdItem.name = invItem.Name;
llsdItem.parent_id = invItem.Folder;
try
{
llsdItem.type = Utils.AssetTypeToString((AssetType)invItem.AssetType);
llsdItem.inv_type = Utils.InventoryTypeToString((InventoryType)invItem.InvType);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[WEB FETCH INV DESC HANDLER]: Problem setting asset {0} inventory {1} types while converting inventory item {2}: {3}",
invItem.AssetType, invItem.InvType, invItem.Name, e.Message);
}
llsdItem.type = invItem.AssetType;
llsdItem.inv_type = invItem.InvType;
llsdItem.permissions = new LLSDPermissions();
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
@@ -390,21 +430,7 @@ namespace OpenSim.Capabilities.Handlers
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
llsdItem.sale_info = new LLSDSaleInfo();
llsdItem.sale_info.sale_price = invItem.SalePrice;
switch (invItem.SaleType)
{
default:
llsdItem.sale_info.sale_type = "not";
break;
case 1:
llsdItem.sale_info.sale_type = "original";
break;
case 2:
llsdItem.sale_info.sale_type = "copy";
break;
case 3:
llsdItem.sale_info.sale_type = "contents";
break;
}
llsdItem.sale_info.sale_type = invItem.SaleType;
return llsdItem;
}

View File

@@ -68,7 +68,13 @@ namespace OpenSim.Capabilities.Handlers
ServerUtils.LoadPlugin<ILibraryService>(libService, args);
WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
IRequestHandler reqHandler = new RestStreamHandler("POST", "/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/, webFetchHandler.FetchInventoryDescendentsRequest);
IRequestHandler reqHandler
= new RestStreamHandler(
"POST",
"/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/,
webFetchHandler.FetchInventoryDescendentsRequest,
"WebFetchInvDesc",
null);
server.AddStreamHandler(reqHandler);
}

View File

@@ -0,0 +1,68 @@
/*
* 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 OpenMetaverse;
namespace OpenSim.Framework.Capabilities
{
[OSDMap]
public class LLSDEnvironmentRequest
{
public UUID messageID;
public UUID regionID;
}
[OSDMap]
public class LLSDEnvironmentSetResponse
{
public UUID regionID;
public UUID messageID;
public Boolean success;
public String fail_reason;
}
public class EnvironmentSettings
{
/// <summary>
/// generates a empty llsd settings response for viewer
/// </summary>
/// <param name="messageID">the message UUID</param>
/// <param name="regionID">the region UUID</param>
public static string EmptySettings(UUID messageID, UUID regionID)
{
OSDArray arr = new OSDArray();
LLSDEnvironmentRequest msg = new LLSDEnvironmentRequest();
msg.messageID = messageID;
msg.regionID = regionID;
arr.Array.Add(msg);
return LLSDHelpers.SerialiseLLSDReply(arr);
}
}
}

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

@@ -37,8 +37,8 @@ namespace OpenSim.Framework.Capabilities
public UUID asset_id;
public UUID item_id;
public LLSDPermissions permissions;
public string type;
public string inv_type;
public int type;
public int inv_type;
public int flags;
public LLSDSaleInfo sale_info;
@@ -65,7 +65,7 @@ namespace OpenSim.Framework.Capabilities
public class LLSDSaleInfo
{
public int sale_price;
public string sale_type;
public int sale_type;
}
[OSDMap]

View File

@@ -39,7 +39,11 @@ namespace OpenSim.Framework.Capabilities
private LLSDMethod<TRequest, TResponse> m_method;
public LLSDStreamhandler(string httpMethod, string path, LLSDMethod<TRequest, TResponse> method)
: base(httpMethod, path)
: this(httpMethod, path, method, null, null) {}
public LLSDStreamhandler(
string httpMethod, string path, LLSDMethod<TRequest, TResponse> method, string name, string description)
: base(httpMethod, path, name, description)
{
m_method = method;
}
@@ -62,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

@@ -1181,6 +1181,72 @@ VALUES
// }
#endregion
}
#region Environment Settings
public string LoadRegionEnvironmentSettings(UUID regionUUID)
{
string sql = "select * from [regionenvironment] where region_id = @region_id";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID));
conn.Open();
using (SqlDataReader result = cmd.ExecuteReader())
{
if (!result.Read())
{
return String.Empty;
}
else
{
return Convert.ToString(result["llsd_settings"]);
}
}
}
}
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
{
{
string sql = "DELETE FROM [regionenvironment] WHERE region_id = @region_id";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID));
conn.Open();
cmd.ExecuteNonQuery();
}
sql = "INSERT INTO [regionenvironment] (region_id, llsd_settings) VALUES (@region_id, @llsd_settings)";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID));
cmd.Parameters.Add(_Database.CreateParameter("@llsd_settings", settings));
conn.Open();
cmd.ExecuteNonQuery();
}
}
}
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
{
string sql = "delete from [regionenvironment] where region_id = @region_id";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID));
conn.Open();
cmd.ExecuteNonQuery();
}
}
#endregion
/// <summary>
/// Loads the settings of a region.
/// </summary>

View File

@@ -1134,3 +1134,17 @@ ALTER TABLE landaccesslist ADD Expires integer NOT NULL DEFAULT 0;
COMMIT
:VERSION 37 #---------------- Environment Settings
BEGIN TRANSACTION
CREATE TABLE [dbo].[regionenvironment](
[region_id] [uniqueidentifier] NOT NULL,
[llsd_settings] [varchar](max) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
PRIMARY KEY CLUSTERED
(
[region_id] ASC
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
COMMIT

View File

@@ -163,52 +163,51 @@ namespace OpenSim.Data.MySQL
{
dbcon.Open();
MySqlCommand cmd =
using (MySqlCommand cmd =
new MySqlCommand(
"replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" +
"VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)",
dbcon);
string assetName = asset.Name;
if (asset.Name.Length > 64)
dbcon))
{
assetName = asset.Name.Substring(0, 64);
m_log.Warn("[ASSET DB]: Name field truncated from " + asset.Name.Length + " to " + assetName.Length + " characters on add");
}
string assetDescription = asset.Description;
if (asset.Description.Length > 64)
{
assetDescription = asset.Description.Substring(0, 64);
m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add");
}
// need to ensure we dispose
try
{
using (cmd)
string assetName = asset.Name;
if (asset.Name.Length > 64)
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?name", assetName);
cmd.Parameters.AddWithValue("?description", assetDescription);
cmd.Parameters.AddWithValue("?assetType", asset.Type);
cmd.Parameters.AddWithValue("?local", asset.Local);
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
cmd.Parameters.AddWithValue("?create_time", now);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery();
cmd.Dispose();
assetName = asset.Name.Substring(0, 64);
m_log.Warn("[ASSET DB]: Name field truncated from " + asset.Name.Length + " to " + assetName.Length + " characters on add");
}
string assetDescription = asset.Description;
if (asset.Description.Length > 64)
{
assetDescription = asset.Description.Substring(0, 64);
m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add");
}
try
{
using (cmd)
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?name", assetName);
cmd.Parameters.AddWithValue("?description", assetDescription);
cmd.Parameters.AddWithValue("?assetType", asset.Type);
cmd.Parameters.AddWithValue("?local", asset.Local);
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
cmd.Parameters.AddWithValue("?create_time", now);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
asset.FullID, asset.Name, e.Message);
}
}
catch (Exception e)
{
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
asset.FullID, asset.Name, e.Message);
}
}
}
@@ -221,33 +220,31 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd =
new MySqlCommand("update assets set access_time=?access_time where id=?id",
dbcon);
// need to ensure we dispose
try
using (MySqlCommand cmd
= new MySqlCommand("update assets set access_time=?access_time where id=?id", dbcon))
{
using (cmd)
try
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.ExecuteNonQuery();
cmd.Dispose();
using (cmd)
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.ErrorFormat(
"[ASSETS DB]: " +
"MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString()
+ Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name);
}
}
catch (Exception e)
{
m_log.ErrorFormat(
"[ASSETS DB]: " +
"MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString()
+ Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name);
}
}
}
}
/// <summary>
@@ -310,35 +307,41 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand("SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count", dbcon);
cmd.Parameters.AddWithValue("?start", start);
cmd.Parameters.AddWithValue("?count", count);
try
using (MySqlCommand cmd
= new MySqlCommand(
"SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count",
dbcon))
{
using (MySqlDataReader dbReader = cmd.ExecuteReader())
cmd.Parameters.AddWithValue("?start", start);
cmd.Parameters.AddWithValue("?count", count);
try
{
while (dbReader.Read())
using (MySqlDataReader dbReader = cmd.ExecuteReader())
{
AssetMetadata metadata = new AssetMetadata();
metadata.Name = (string)dbReader["name"];
metadata.Description = (string)dbReader["description"];
metadata.Type = (sbyte)dbReader["assetType"];
metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct.
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
metadata.FullID = DBGuid.FromDB(dbReader["id"]);
metadata.CreatorID = dbReader["CreatorID"].ToString();
// Current SHA1s are not stored/computed.
metadata.SHA1 = new byte[] { };
retList.Add(metadata);
while (dbReader.Read())
{
AssetMetadata metadata = new AssetMetadata();
metadata.Name = (string)dbReader["name"];
metadata.Description = (string)dbReader["description"];
metadata.Type = (sbyte)dbReader["assetType"];
metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct.
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
metadata.FullID = DBGuid.FromDB(dbReader["id"]);
metadata.CreatorID = dbReader["CreatorID"].ToString();
// Current SHA1s are not stored/computed.
metadata.SHA1 = new byte[] { };
retList.Add(metadata);
}
}
}
}
catch (Exception e)
{
m_log.Error("[ASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
catch (Exception e)
{
m_log.Error("[ASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
}
}
}
}
@@ -353,11 +356,12 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon);
cmd.Parameters.AddWithValue("?id", id);
cmd.ExecuteNonQuery();
cmd.Dispose();
using (MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon))
{
cmd.Parameters.AddWithValue("?id", id);
cmd.ExecuteNonQuery();
}
}
}
@@ -366,4 +370,4 @@ namespace OpenSim.Data.MySQL
#endregion
}
}
}

View File

@@ -70,41 +70,52 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand("select * from `" + m_Realm + "` where UUID = ?principalID", dbcon);
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
IDataReader result = cmd.ExecuteReader();
if (result.Read())
using (MySqlCommand cmd
= new MySqlCommand("select * from `" + m_Realm + "` where UUID = ?principalID", dbcon))
{
ret.PrincipalID = principalID;
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
if (m_ColumnNames == null)
IDataReader result = cmd.ExecuteReader();
if (result.Read())
{
m_ColumnNames = new List<string>();
DataTable schemaTable = result.GetSchemaTable();
foreach (DataRow row in schemaTable.Rows)
m_ColumnNames.Add(row["ColumnName"].ToString());
ret.PrincipalID = principalID;
CheckColumnNames(result);
foreach (string s in m_ColumnNames)
{
if (s == "UUID")
continue;
ret.Data[s] = result[s].ToString();
}
return ret;
}
foreach (string s in m_ColumnNames)
else
{
if (s == "UUID")
continue;
ret.Data[s] = result[s].ToString();
return null;
}
return ret;
}
else
{
return null;
}
}
}
private void CheckColumnNames(IDataReader result)
{
if (m_ColumnNames != null)
return;
List<string> columnNames = new List<string>();
DataTable schemaTable = result.GetSchemaTable();
foreach (DataRow row in schemaTable.Rows)
columnNames.Add(row["ColumnName"].ToString());
m_ColumnNames = columnNames;
}
public bool Store(AuthenticationData data)
{
if (data.Data.ContainsKey("UUID"))
@@ -112,57 +123,53 @@ namespace OpenSim.Data.MySQL
string[] fields = new List<string>(data.Data.Keys).ToArray();
MySqlCommand cmd = new MySqlCommand();
string update = "update `"+m_Realm+"` set ";
bool first = true;
foreach (string field in fields)
using (MySqlCommand cmd = new MySqlCommand())
{
if (!first)
update += ", ";
update += "`" + field + "` = ?"+field;
first = false;
cmd.Parameters.AddWithValue("?"+field, data.Data[field]);
}
update += " where UUID = ?principalID";
cmd.CommandText = update;
cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString());
if (ExecuteNonQuery(cmd) < 1)
{
string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
String.Join("`, `", fields) +
"`) values (?principalID, ?" + String.Join(", ?", fields) + ")";
cmd.CommandText = insert;
string update = "update `"+m_Realm+"` set ";
bool first = true;
foreach (string field in fields)
{
if (!first)
update += ", ";
update += "`" + field + "` = ?"+field;
first = false;
cmd.Parameters.AddWithValue("?"+field, data.Data[field]);
}
update += " where UUID = ?principalID";
cmd.CommandText = update;
cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString());
if (ExecuteNonQuery(cmd) < 1)
{
cmd.Dispose();
return false;
string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
String.Join("`, `", fields) +
"`) values (?principalID, ?" + String.Join(", ?", fields) + ")";
cmd.CommandText = insert;
if (ExecuteNonQuery(cmd) < 1)
return false;
}
}
cmd.Dispose();
return true;
}
public bool SetDataItem(UUID principalID, string item, string value)
{
MySqlCommand cmd = new MySqlCommand("update `" + m_Realm +
"` set `" + item + "` = ?" + item + " where UUID = ?UUID");
cmd.Parameters.AddWithValue("?"+item, value);
cmd.Parameters.AddWithValue("?UUID", principalID.ToString());
if (ExecuteNonQuery(cmd) > 0)
return true;
using (MySqlCommand cmd
= new MySqlCommand("update `" + m_Realm + "` set `" + item + "` = ?" + item + " where UUID = ?UUID"))
{
cmd.Parameters.AddWithValue("?"+item, value);
cmd.Parameters.AddWithValue("?UUID", principalID.ToString());
if (ExecuteNonQuery(cmd) > 0)
return true;
}
return false;
}
@@ -172,18 +179,18 @@ namespace OpenSim.Data.MySQL
if (System.Environment.TickCount - m_LastExpire > 30000)
DoExpire();
MySqlCommand cmd = new MySqlCommand("insert into tokens (UUID, token, validity) values (?principalID, ?token, date_add(now(), interval ?lifetime minute))");
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
cmd.Parameters.AddWithValue("?token", token);
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
if (ExecuteNonQuery(cmd) > 0)
using (MySqlCommand cmd
= new MySqlCommand(
"insert into tokens (UUID, token, validity) values (?principalID, ?token, date_add(now(), interval ?lifetime minute))"))
{
cmd.Dispose();
return true;
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
cmd.Parameters.AddWithValue("?token", token);
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
if (ExecuteNonQuery(cmd) > 0)
return true;
}
cmd.Dispose();
return false;
}
@@ -192,30 +199,29 @@ namespace OpenSim.Data.MySQL
if (System.Environment.TickCount - m_LastExpire > 30000)
DoExpire();
MySqlCommand cmd = new MySqlCommand("update tokens set validity = date_add(now(), interval ?lifetime minute) where UUID = ?principalID and token = ?token and validity > now()");
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
cmd.Parameters.AddWithValue("?token", token);
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
if (ExecuteNonQuery(cmd) > 0)
using (MySqlCommand cmd
= new MySqlCommand(
"update tokens set validity = date_add(now(), interval ?lifetime minute) where UUID = ?principalID and token = ?token and validity > now()"))
{
cmd.Dispose();
return true;
}
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
cmd.Parameters.AddWithValue("?token", token);
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
cmd.Dispose();
if (ExecuteNonQuery(cmd) > 0)
return true;
}
return false;
}
private void DoExpire()
{
MySqlCommand cmd = new MySqlCommand("delete from tokens where validity < now()");
ExecuteNonQuery(cmd);
cmd.Dispose();
using (MySqlCommand cmd = new MySqlCommand("delete from tokens where validity < now()"))
{
ExecuteNonQuery(cmd);
}
m_LastExpire = System.Environment.TickCount;
}
}
}
}

View File

@@ -52,14 +52,15 @@ namespace OpenSim.Data.MySQL
public bool Delete(UUID principalID, string name)
{
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = ?PrincipalID and `Name` = ?Name", m_Realm);
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
cmd.Parameters.AddWithValue("?Name", name);
if (ExecuteNonQuery(cmd) > 0)
return true;
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = ?PrincipalID and `Name` = ?Name", m_Realm);
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
cmd.Parameters.AddWithValue("?Name", name);
if (ExecuteNonQuery(cmd) > 0)
return true;
}
return false;
}

View File

@@ -49,34 +49,38 @@ namespace OpenSim.Data.MySQL
public bool Delete(string principalID, string friend)
{
MySqlCommand cmd = new MySqlCommand();
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm);
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
cmd.Parameters.AddWithValue("?Friend", friend);
cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm);
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
cmd.Parameters.AddWithValue("?Friend", friend);
ExecuteNonQuery(cmd);
ExecuteNonQuery(cmd);
}
return true;
}
public FriendsData[] GetFriends(UUID principalID)
{
MySqlCommand cmd = new MySqlCommand();
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = ?PrincipalID", m_Realm);
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = ?PrincipalID", m_Realm);
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
return DoQuery(cmd);
return DoQuery(cmd);
}
}
public FriendsData[] GetFriends(string principalID)
{
MySqlCommand cmd = new MySqlCommand();
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID LIKE ?PrincipalID", m_Realm);
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%');
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID LIKE ?PrincipalID", m_Realm);
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%');
return DoQuery(cmd);
return DoQuery(cmd);
}
}
}
}
}

View File

@@ -91,15 +91,17 @@ namespace OpenSim.Data.MySQL
if (m_ColumnNames != null)
return;
m_ColumnNames = new List<string>();
List<string> columnNames = new List<string>();
DataTable schemaTable = reader.GetSchemaTable();
foreach (DataRow row in schemaTable.Rows)
{
if (row["ColumnName"] != null &&
(!m_Fields.ContainsKey(row["ColumnName"].ToString())))
m_ColumnNames.Add(row["ColumnName"].ToString());
columnNames.Add(row["ColumnName"].ToString());
}
m_ColumnNames = columnNames;
}
public virtual T[] Get(string field, string key)

View File

@@ -467,43 +467,43 @@ namespace OpenSim.Data.MySQL
{
dbcon.Open();
MySqlCommand result = new MySqlCommand(sql, dbcon);
result.Parameters.AddWithValue("?inventoryID", item.ID.ToString());
result.Parameters.AddWithValue("?assetID", item.AssetID.ToString());
result.Parameters.AddWithValue("?assetType", item.AssetType.ToString());
result.Parameters.AddWithValue("?parentFolderID", item.Folder.ToString());
result.Parameters.AddWithValue("?avatarID", item.Owner.ToString());
result.Parameters.AddWithValue("?inventoryName", itemName);
result.Parameters.AddWithValue("?inventoryDescription", itemDesc);
result.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions.ToString());
result.Parameters.AddWithValue("?inventoryCurrentPermissions",
item.CurrentPermissions.ToString());
result.Parameters.AddWithValue("?invType", item.InvType);
result.Parameters.AddWithValue("?creatorID", item.CreatorId);
result.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions);
result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions);
result.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions);
result.Parameters.AddWithValue("?salePrice", item.SalePrice);
result.Parameters.AddWithValue("?saleType", unchecked((sbyte)item.SaleType));
result.Parameters.AddWithValue("?creationDate", item.CreationDate);
result.Parameters.AddWithValue("?groupID", item.GroupID);
result.Parameters.AddWithValue("?groupOwned", item.GroupOwned);
result.Parameters.AddWithValue("?flags", item.Flags);
lock (m_dbLock)
using (MySqlCommand result = new MySqlCommand(sql, dbcon))
{
result.ExecuteNonQuery();
result.Parameters.AddWithValue("?inventoryID", item.ID.ToString());
result.Parameters.AddWithValue("?assetID", item.AssetID.ToString());
result.Parameters.AddWithValue("?assetType", item.AssetType.ToString());
result.Parameters.AddWithValue("?parentFolderID", item.Folder.ToString());
result.Parameters.AddWithValue("?avatarID", item.Owner.ToString());
result.Parameters.AddWithValue("?inventoryName", itemName);
result.Parameters.AddWithValue("?inventoryDescription", itemDesc);
result.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions.ToString());
result.Parameters.AddWithValue("?inventoryCurrentPermissions",
item.CurrentPermissions.ToString());
result.Parameters.AddWithValue("?invType", item.InvType);
result.Parameters.AddWithValue("?creatorID", item.CreatorId);
result.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions);
result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions);
result.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions);
result.Parameters.AddWithValue("?salePrice", item.SalePrice);
result.Parameters.AddWithValue("?saleType", unchecked((sbyte)item.SaleType));
result.Parameters.AddWithValue("?creationDate", item.CreationDate);
result.Parameters.AddWithValue("?groupID", item.GroupID);
result.Parameters.AddWithValue("?groupOwned", item.GroupOwned);
result.Parameters.AddWithValue("?flags", item.Flags);
lock (m_dbLock)
result.ExecuteNonQuery();
result.Dispose();
}
result.Dispose();
result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", dbcon);
result.Parameters.AddWithValue("?folderID", item.Folder.ToString());
lock (m_dbLock)
using (MySqlCommand result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", dbcon))
{
result.ExecuteNonQuery();
result.Parameters.AddWithValue("?folderID", item.Folder.ToString());
lock (m_dbLock)
result.ExecuteNonQuery();
}
result.Dispose();
}
}
catch (MySqlException e)
@@ -533,12 +533,12 @@ namespace OpenSim.Data.MySQL
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", dbcon);
cmd.Parameters.AddWithValue("?uuid", itemID.ToString());
lock (m_dbLock)
using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", dbcon))
{
cmd.ExecuteNonQuery();
cmd.Parameters.AddWithValue("?uuid", itemID.ToString());
lock (m_dbLock)
cmd.ExecuteNonQuery();
}
}
}
@@ -579,24 +579,26 @@ namespace OpenSim.Data.MySQL
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand(sql, dbcon);
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString());
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
cmd.Parameters.AddWithValue("?folderName", folderName);
cmd.Parameters.AddWithValue("?type", folder.Type);
cmd.Parameters.AddWithValue("?version", folder.Version);
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
{
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString());
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
cmd.Parameters.AddWithValue("?folderName", folderName);
cmd.Parameters.AddWithValue("?type", folder.Type);
cmd.Parameters.AddWithValue("?version", folder.Version);
try
{
lock (m_dbLock)
try
{
cmd.ExecuteNonQuery();
lock (m_dbLock)
{
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.Error(e.ToString());
}
}
catch (Exception e)
{
m_log.Error(e.ToString());
}
}
}
@@ -624,20 +626,22 @@ namespace OpenSim.Data.MySQL
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand(sql, dbcon);
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
try
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
{
lock (m_dbLock)
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
try
{
cmd.ExecuteNonQuery();
lock (m_dbLock)
{
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.Error(e.ToString());
}
}
catch (Exception e)
{
m_log.Error(e.ToString());
}
}
}

View File

@@ -63,13 +63,14 @@ namespace OpenSim.Data.MySQL
public void LogoutRegionAgents(UUID regionID)
{
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm);
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
ExecuteNonQuery(cmd);
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm);
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
ExecuteNonQuery(cmd);
}
}
public bool ReportAgent(UUID sessionID, UUID regionID)
@@ -81,17 +82,18 @@ namespace OpenSim.Data.MySQL
if (regionID == UUID.Zero)
return false;
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm);
cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString());
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
if (ExecuteNonQuery(cmd) == 0)
return false;
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm);
cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString());
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
if (ExecuteNonQuery(cmd) == 0)
return false;
}
return true;
}
}
}
}

View File

@@ -162,17 +162,7 @@ namespace OpenSim.Data.MySQL
ret.sizeX = Convert.ToInt32(result["sizeX"]);
ret.sizeY = Convert.ToInt32(result["sizeY"]);
if (m_ColumnNames == null)
{
m_ColumnNames = new List<string>();
DataTable schemaTable = result.GetSchemaTable();
foreach (DataRow row in schemaTable.Rows)
{
if (row["ColumnName"] != null)
m_ColumnNames.Add(row["ColumnName"].ToString());
}
}
CheckColumnNames(result);
foreach (string s in m_ColumnNames)
{
@@ -187,7 +177,11 @@ namespace OpenSim.Data.MySQL
if (s == "locY")
continue;
ret.Data[s] = result[s].ToString();
object value = result[s];
if (value is DBNull)
ret.Data[s] = null;
else
ret.Data[s] = result[s].ToString();
}
retList.Add(ret);
@@ -198,6 +192,23 @@ namespace OpenSim.Data.MySQL
return retList;
}
private void CheckColumnNames(IDataReader result)
{
if (m_ColumnNames != null)
return;
List<string> columnNames = new List<string>();
DataTable schemaTable = result.GetSchemaTable();
foreach (DataRow row in schemaTable.Rows)
{
if (row["ColumnName"] != null)
columnNames.Add(row["ColumnName"].ToString());
}
m_ColumnNames = columnNames;
}
public bool Store(RegionData data)
{
if (data.Data.ContainsKey("uuid"))
@@ -318,11 +329,12 @@ namespace OpenSim.Data.MySQL
if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID";
MySqlCommand cmd = new MySqlCommand(command);
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
return RunCommand(cmd);
using (MySqlCommand cmd = new MySqlCommand(command))
{
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
return RunCommand(cmd);
}
}
}
}
}

View File

@@ -129,114 +129,114 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd = dbcon.CreateCommand();
foreach (SceneObjectPart prim in obj.Parts)
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.Parameters.Clear();
cmd.CommandText = "replace into prims (" +
"UUID, CreationDate, " +
"Name, Text, Description, " +
"SitName, TouchName, ObjectFlags, " +
"OwnerMask, NextOwnerMask, GroupMask, " +
"EveryoneMask, BaseMask, PositionX, " +
"PositionY, PositionZ, GroupPositionX, " +
"GroupPositionY, GroupPositionZ, VelocityX, " +
"VelocityY, VelocityZ, AngularVelocityX, " +
"AngularVelocityY, AngularVelocityZ, " +
"AccelerationX, AccelerationY, " +
"AccelerationZ, RotationX, " +
"RotationY, RotationZ, " +
"RotationW, SitTargetOffsetX, " +
"SitTargetOffsetY, SitTargetOffsetZ, " +
"SitTargetOrientW, SitTargetOrientX, " +
"SitTargetOrientY, SitTargetOrientZ, " +
"RegionUUID, CreatorID, " +
"OwnerID, GroupID, " +
"LastOwnerID, SceneGroupID, " +
"PayPrice, PayButton1, " +
"PayButton2, PayButton3, " +
"PayButton4, LoopedSound, " +
"LoopedSoundGain, TextureAnimation, " +
"OmegaX, OmegaY, OmegaZ, " +
"CameraEyeOffsetX, CameraEyeOffsetY, " +
"CameraEyeOffsetZ, CameraAtOffsetX, " +
"CameraAtOffsetY, CameraAtOffsetZ, " +
"ForceMouselook, ScriptAccessPin, " +
"AllowedDrop, DieAtEdge, " +
"SalePrice, SaleType, " +
"ColorR, ColorG, ColorB, ColorA, " +
"ParticleSystem, ClickAction, Material, " +
"CollisionSound, CollisionSoundVolume, " +
"PassTouches, " +
"LinkNumber, MediaURL) values (" + "?UUID, " +
"?CreationDate, ?Name, ?Text, " +
"?Description, ?SitName, ?TouchName, " +
"?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " +
"?GroupMask, ?EveryoneMask, ?BaseMask, " +
"?PositionX, ?PositionY, ?PositionZ, " +
"?GroupPositionX, ?GroupPositionY, " +
"?GroupPositionZ, ?VelocityX, " +
"?VelocityY, ?VelocityZ, ?AngularVelocityX, " +
"?AngularVelocityY, ?AngularVelocityZ, " +
"?AccelerationX, ?AccelerationY, " +
"?AccelerationZ, ?RotationX, " +
"?RotationY, ?RotationZ, " +
"?RotationW, ?SitTargetOffsetX, " +
"?SitTargetOffsetY, ?SitTargetOffsetZ, " +
"?SitTargetOrientW, ?SitTargetOrientX, " +
"?SitTargetOrientY, ?SitTargetOrientZ, " +
"?RegionUUID, ?CreatorID, ?OwnerID, " +
"?GroupID, ?LastOwnerID, ?SceneGroupID, " +
"?PayPrice, ?PayButton1, ?PayButton2, " +
"?PayButton3, ?PayButton4, ?LoopedSound, " +
"?LoopedSoundGain, ?TextureAnimation, " +
"?OmegaX, ?OmegaY, ?OmegaZ, " +
"?CameraEyeOffsetX, ?CameraEyeOffsetY, " +
"?CameraEyeOffsetZ, ?CameraAtOffsetX, " +
"?CameraAtOffsetY, ?CameraAtOffsetZ, " +
"?ForceMouselook, ?ScriptAccessPin, " +
"?AllowedDrop, ?DieAtEdge, ?SalePrice, " +
"?SaleType, ?ColorR, ?ColorG, " +
"?ColorB, ?ColorA, ?ParticleSystem, " +
"?ClickAction, ?Material, ?CollisionSound, " +
"?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)";
FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
ExecuteNonQuery(cmd);
cmd.Parameters.Clear();
cmd.CommandText = "replace into primshapes (" +
"UUID, Shape, ScaleX, ScaleY, " +
"ScaleZ, PCode, PathBegin, PathEnd, " +
"PathScaleX, PathScaleY, PathShearX, " +
"PathShearY, PathSkew, PathCurve, " +
"PathRadiusOffset, PathRevolutions, " +
"PathTaperX, PathTaperY, PathTwist, " +
"PathTwistBegin, ProfileBegin, ProfileEnd, " +
"ProfileCurve, ProfileHollow, Texture, " +
"ExtraParams, State, Media) values (?UUID, " +
"?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
"?PCode, ?PathBegin, ?PathEnd, " +
"?PathScaleX, ?PathScaleY, " +
"?PathShearX, ?PathShearY, " +
"?PathSkew, ?PathCurve, ?PathRadiusOffset, " +
"?PathRevolutions, ?PathTaperX, " +
"?PathTaperY, ?PathTwist, " +
"?PathTwistBegin, ?ProfileBegin, " +
"?ProfileEnd, ?ProfileCurve, " +
"?ProfileHollow, ?Texture, ?ExtraParams, " +
"?State, ?Media)";
FillShapeCommand(cmd, prim);
ExecuteNonQuery(cmd);
foreach (SceneObjectPart prim in obj.Parts)
{
cmd.Parameters.Clear();
cmd.CommandText = "replace into prims (" +
"UUID, CreationDate, " +
"Name, Text, Description, " +
"SitName, TouchName, ObjectFlags, " +
"OwnerMask, NextOwnerMask, GroupMask, " +
"EveryoneMask, BaseMask, PositionX, " +
"PositionY, PositionZ, GroupPositionX, " +
"GroupPositionY, GroupPositionZ, VelocityX, " +
"VelocityY, VelocityZ, AngularVelocityX, " +
"AngularVelocityY, AngularVelocityZ, " +
"AccelerationX, AccelerationY, " +
"AccelerationZ, RotationX, " +
"RotationY, RotationZ, " +
"RotationW, SitTargetOffsetX, " +
"SitTargetOffsetY, SitTargetOffsetZ, " +
"SitTargetOrientW, SitTargetOrientX, " +
"SitTargetOrientY, SitTargetOrientZ, " +
"RegionUUID, CreatorID, " +
"OwnerID, GroupID, " +
"LastOwnerID, SceneGroupID, " +
"PayPrice, PayButton1, " +
"PayButton2, PayButton3, " +
"PayButton4, LoopedSound, " +
"LoopedSoundGain, TextureAnimation, " +
"OmegaX, OmegaY, OmegaZ, " +
"CameraEyeOffsetX, CameraEyeOffsetY, " +
"CameraEyeOffsetZ, CameraAtOffsetX, " +
"CameraAtOffsetY, CameraAtOffsetZ, " +
"ForceMouselook, ScriptAccessPin, " +
"AllowedDrop, DieAtEdge, " +
"SalePrice, SaleType, " +
"ColorR, ColorG, ColorB, ColorA, " +
"ParticleSystem, ClickAction, Material, " +
"CollisionSound, CollisionSoundVolume, " +
"PassTouches, " +
"LinkNumber, MediaURL) values (" + "?UUID, " +
"?CreationDate, ?Name, ?Text, " +
"?Description, ?SitName, ?TouchName, " +
"?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " +
"?GroupMask, ?EveryoneMask, ?BaseMask, " +
"?PositionX, ?PositionY, ?PositionZ, " +
"?GroupPositionX, ?GroupPositionY, " +
"?GroupPositionZ, ?VelocityX, " +
"?VelocityY, ?VelocityZ, ?AngularVelocityX, " +
"?AngularVelocityY, ?AngularVelocityZ, " +
"?AccelerationX, ?AccelerationY, " +
"?AccelerationZ, ?RotationX, " +
"?RotationY, ?RotationZ, " +
"?RotationW, ?SitTargetOffsetX, " +
"?SitTargetOffsetY, ?SitTargetOffsetZ, " +
"?SitTargetOrientW, ?SitTargetOrientX, " +
"?SitTargetOrientY, ?SitTargetOrientZ, " +
"?RegionUUID, ?CreatorID, ?OwnerID, " +
"?GroupID, ?LastOwnerID, ?SceneGroupID, " +
"?PayPrice, ?PayButton1, ?PayButton2, " +
"?PayButton3, ?PayButton4, ?LoopedSound, " +
"?LoopedSoundGain, ?TextureAnimation, " +
"?OmegaX, ?OmegaY, ?OmegaZ, " +
"?CameraEyeOffsetX, ?CameraEyeOffsetY, " +
"?CameraEyeOffsetZ, ?CameraAtOffsetX, " +
"?CameraAtOffsetY, ?CameraAtOffsetZ, " +
"?ForceMouselook, ?ScriptAccessPin, " +
"?AllowedDrop, ?DieAtEdge, ?SalePrice, " +
"?SaleType, ?ColorR, ?ColorG, " +
"?ColorB, ?ColorA, ?ParticleSystem, " +
"?ClickAction, ?Material, ?CollisionSound, " +
"?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)";
FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
ExecuteNonQuery(cmd);
cmd.Parameters.Clear();
cmd.CommandText = "replace into primshapes (" +
"UUID, Shape, ScaleX, ScaleY, " +
"ScaleZ, PCode, PathBegin, PathEnd, " +
"PathScaleX, PathScaleY, PathShearX, " +
"PathShearY, PathSkew, PathCurve, " +
"PathRadiusOffset, PathRevolutions, " +
"PathTaperX, PathTaperY, PathTwist, " +
"PathTwistBegin, ProfileBegin, ProfileEnd, " +
"ProfileCurve, ProfileHollow, Texture, " +
"ExtraParams, State, Media) values (?UUID, " +
"?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
"?PCode, ?PathBegin, ?PathEnd, " +
"?PathScaleX, ?PathScaleY, " +
"?PathShearX, ?PathShearY, " +
"?PathSkew, ?PathCurve, ?PathRadiusOffset, " +
"?PathRevolutions, ?PathTaperX, " +
"?PathTaperY, ?PathTwist, " +
"?PathTwistBegin, ?ProfileBegin, " +
"?ProfileEnd, ?ProfileCurve, " +
"?ProfileHollow, ?Texture, ?ExtraParams, " +
"?State, ?Media)";
FillShapeCommand(cmd, prim);
ExecuteNonQuery(cmd);
}
}
cmd.Dispose();
}
}
}
@@ -969,6 +969,68 @@ namespace OpenSim.Data.MySQL
}
}
#region RegionEnvironmentSettings
public string LoadRegionEnvironmentSettings(UUID regionUUID)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
string command = "select * from `regionenvironment` where region_id = ?region_id";
using (MySqlCommand cmd = new MySqlCommand(command))
{
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"]);
}
}
}
}
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
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))
{
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);
}
}
}
#endregion
public void StoreRegionSettings(RegionSettings rs)
{
lock (m_dbLock)
@@ -1800,41 +1862,40 @@ namespace OpenSim.Data.MySQL
{
RemoveItems(primID);
if (items.Count == 0)
return;
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd = dbcon.CreateCommand();
if (items.Count == 0)
return;
cmd.CommandText = "insert into primitems (" +
"invType, assetType, name, " +
"description, creationDate, nextPermissions, " +
"currentPermissions, basePermissions, " +
"everyonePermissions, groupPermissions, " +
"flags, itemID, primID, assetID, " +
"parentFolderID, creatorID, ownerID, " +
"groupID, lastOwnerID) values (?invType, " +
"?assetType, ?name, ?description, " +
"?creationDate, ?nextPermissions, " +
"?currentPermissions, ?basePermissions, " +
"?everyonePermissions, ?groupPermissions, " +
"?flags, ?itemID, ?primID, ?assetID, " +
"?parentFolderID, ?creatorID, ?ownerID, " +
"?groupID, ?lastOwnerID)";
foreach (TaskInventoryItem item in items)
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.Parameters.Clear();
FillItemCommand(cmd, item);
ExecuteNonQuery(cmd);
cmd.CommandText = "insert into primitems (" +
"invType, assetType, name, " +
"description, creationDate, nextPermissions, " +
"currentPermissions, basePermissions, " +
"everyonePermissions, groupPermissions, " +
"flags, itemID, primID, assetID, " +
"parentFolderID, creatorID, ownerID, " +
"groupID, lastOwnerID) values (?invType, " +
"?assetType, ?name, ?description, " +
"?creationDate, ?nextPermissions, " +
"?currentPermissions, ?basePermissions, " +
"?everyonePermissions, ?groupPermissions, " +
"?flags, ?itemID, ?primID, ?assetID, " +
"?parentFolderID, ?creatorID, ?ownerID, " +
"?groupID, ?lastOwnerID)";
foreach (TaskInventoryItem item in items)
{
cmd.Parameters.Clear();
FillItemCommand(cmd, item);
ExecuteNonQuery(cmd);
}
}
cmd.Dispose();
}
}
}

View File

@@ -62,23 +62,24 @@ namespace OpenSim.Data.MySQL
if (words.Length > 2)
return new UserAccountData[0];
MySqlCommand cmd = new MySqlCommand();
if (words.Length == 1)
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search)", m_Realm);
cmd.Parameters.AddWithValue("?search", "%" + words[0] + "%");
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
}
else
{
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst or LastName like ?searchLast)", m_Realm);
cmd.Parameters.AddWithValue("?searchFirst", "%" + words[0] + "%");
cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%");
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
}
if (words.Length == 1)
{
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search)", m_Realm);
cmd.Parameters.AddWithValue("?search", "%" + words[0] + "%");
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
}
else
{
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst or LastName like ?searchLast)", m_Realm);
cmd.Parameters.AddWithValue("?searchFirst", "%" + words[0] + "%");
cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%");
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
}
return DoQuery(cmd);
return DoQuery(cmd);
}
}
}
}
}

View File

@@ -883,4 +883,15 @@ ALTER TABLE `regionsettings` MODIFY COLUMN `TelehubObject` VARCHAR(36) NOT NULL
COMMIT;
:VERSION 44 #--------------------- Environment Settings
BEGIN;
CREATE TABLE `regionenvironment` (
`region_id` varchar(36) NOT NULL,
`llsd_settings` TEXT NOT NULL,
PRIMARY KEY (`region_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
COMMIT;

View File

@@ -76,9 +76,27 @@ namespace OpenSim.Data.Null
//This connector doesn't support the windlight module yet
}
#region Environment Settings
public string LoadRegionEnvironmentSettings(UUID regionUUID)
{
//This connector doesn't support the Environment module yet
return string.Empty;
}
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
{
//This connector doesn't support the Environment module yet
}
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
{
//This connector doesn't support the Environment module yet
}
#endregion
public RegionSettings LoadRegionSettings(UUID regionUUID)
{
RegionSettings rs = new RegionSettings();
{
RegionSettings rs = new RegionSettings();
rs.RegionUUID = regionUUID;
return rs;
}

View File

@@ -564,3 +564,14 @@ COMMIT;
BEGIN;
ALTER TABLE `regionsettings` ADD COLUMN `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
COMMIT;
:VERSION 26
BEGIN;
CREATE TABLE `regionenvironment` (
`region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000' PRIMARY KEY,
`llsd_settings` TEXT NOT NULL
);
COMMIT;

View File

@@ -61,6 +61,7 @@ namespace OpenSim.Data.SQLite
private const string regionbanListSelect = "select * from regionban";
private const string regionSettingsSelect = "select * from regionsettings";
private const string regionWindlightSelect = "select * from regionwindlight";
private const string regionEnvironmentSelect = "select * from regionenvironment";
private const string regionSpawnPointsSelect = "select * from spawn_points";
private DataSet ds;
@@ -72,6 +73,7 @@ namespace OpenSim.Data.SQLite
private SqliteDataAdapter landAccessListDa;
private SqliteDataAdapter regionSettingsDa;
private SqliteDataAdapter regionWindlightDa;
private SqliteDataAdapter regionEnvironmentDa;
private SqliteDataAdapter regionSpawnPointsDa;
private SqliteConnection m_conn;
@@ -146,6 +148,9 @@ namespace OpenSim.Data.SQLite
SqliteCommand regionWindlightSelectCmd = new SqliteCommand(regionWindlightSelect, m_conn);
regionWindlightDa = new SqliteDataAdapter(regionWindlightSelectCmd);
SqliteCommand regionEnvironmentSelectCmd = new SqliteCommand(regionEnvironmentSelect, m_conn);
regionEnvironmentDa = new SqliteDataAdapter(regionEnvironmentSelectCmd);
SqliteCommand regionSpawnPointsSelectCmd = new SqliteCommand(regionSpawnPointsSelect, m_conn);
regionSpawnPointsDa = new SqliteDataAdapter(regionSpawnPointsSelectCmd);
@@ -179,6 +184,9 @@ namespace OpenSim.Data.SQLite
ds.Tables.Add(createRegionWindlightTable());
setupRegionWindlightCommands(regionWindlightDa, m_conn);
ds.Tables.Add(createRegionEnvironmentTable());
setupRegionEnvironmentCommands(regionEnvironmentDa, m_conn);
ds.Tables.Add(createRegionSpawnPointsTable());
setupRegionSpawnPointsCommands(regionSpawnPointsDa, m_conn);
@@ -258,6 +266,15 @@ namespace OpenSim.Data.SQLite
m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on regionwindlight table :{0}", e.Message);
}
try
{
regionEnvironmentDa.Fill(ds.Tables["regionenvironment"]);
}
catch (Exception e)
{
m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on regionenvironment table :{0}", e.Message);
}
try
{
regionSpawnPointsDa.Fill(ds.Tables["spawn_points"]);
@@ -278,12 +295,13 @@ namespace OpenSim.Data.SQLite
CreateDataSetMapping(landAccessListDa, "landaccesslist");
CreateDataSetMapping(regionSettingsDa, "regionsettings");
CreateDataSetMapping(regionWindlightDa, "regionwindlight");
CreateDataSetMapping(regionEnvironmentDa, "regionenvironment");
CreateDataSetMapping(regionSpawnPointsDa, "spawn_points");
}
}
catch (Exception e)
{
m_log.ErrorFormat("[SQLITE REGION DB]: ", e);
m_log.ErrorFormat("[SQLITE REGION DB]: {0} - {1}", e.Message, e.StackTrace);
Environment.Exit(23);
}
return;
@@ -341,6 +359,11 @@ namespace OpenSim.Data.SQLite
regionWindlightDa.Dispose();
regionWindlightDa = null;
}
if (regionEnvironmentDa != null)
{
regionEnvironmentDa.Dispose();
regionEnvironmentDa = null;
}
if (regionSpawnPointsDa != null)
{
regionSpawnPointsDa.Dispose();
@@ -474,6 +497,63 @@ namespace OpenSim.Data.SQLite
}
}
#region Region Environment Settings
public string LoadRegionEnvironmentSettings(UUID regionUUID)
{
lock (ds)
{
DataTable environmentTable = ds.Tables["regionenvironment"];
DataRow row = environmentTable.Rows.Find(regionUUID.ToString());
if (row == null)
{
return String.Empty;
}
return (String)row["llsd_settings"];
}
}
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
{
lock (ds)
{
DataTable environmentTable = ds.Tables["regionenvironment"];
DataRow row = environmentTable.Rows.Find(regionUUID.ToString());
if (row == null)
{
row = environmentTable.NewRow();
row["region_id"] = regionUUID.ToString();
row["llsd_settings"] = settings;
environmentTable.Rows.Add(row);
}
else
{
row["llsd_settings"] = settings;
}
regionEnvironmentDa.Update(ds, "regionenvironment");
}
}
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
{
lock (ds)
{
DataTable environmentTable = ds.Tables["regionenvironment"];
DataRow row = environmentTable.Rows.Find(regionUUID.ToString());
if (row != null)
{
row.Delete();
}
regionEnvironmentDa.Update(ds, "regionenvironment");
}
}
#endregion
public RegionSettings LoadRegionSettings(UUID regionUUID)
{
lock (ds)
@@ -1430,6 +1510,17 @@ namespace OpenSim.Data.SQLite
return regionwindlight;
}
private static DataTable createRegionEnvironmentTable()
{
DataTable regionEnvironment = new DataTable("regionenvironment");
createCol(regionEnvironment, "region_id", typeof(String));
createCol(regionEnvironment, "llsd_settings", typeof(String));
regionEnvironment.PrimaryKey = new DataColumn[] { regionEnvironment.Columns["region_id"] };
return regionEnvironment;
}
private static DataTable createRegionSpawnPointsTable()
{
DataTable spawn_points = new DataTable("spawn_points");
@@ -2691,6 +2782,14 @@ namespace OpenSim.Data.SQLite
da.UpdateCommand.Connection = conn;
}
private void setupRegionEnvironmentCommands(SqliteDataAdapter da, SqliteConnection conn)
{
da.InsertCommand = createInsertCommand("regionenvironment", ds.Tables["regionenvironment"]);
da.InsertCommand.Connection = conn;
da.UpdateCommand = createUpdateCommand("regionenvironment", "region_id=:region_id", ds.Tables["regionenvironment"]);
da.UpdateCommand.Connection = conn;
}
private void setupRegionSpawnPointsCommands(SqliteDataAdapter da, SqliteConnection conn)
{
da.InsertCommand = createInsertCommand("spawn_points", ds.Tables["spawn_points"]);

View File

@@ -632,7 +632,6 @@ namespace OpenSim.Data.Tests
.IgnoreProperty(x=>x.RegionUUID)
.IgnoreProperty(x=>x.Scene)
.IgnoreProperty(x=>x.Parts)
.IgnoreProperty(x=>x.PassCollision)
.IgnoreProperty(x=>x.RootPart));
}
@@ -1070,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;
@@ -1082,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

@@ -79,7 +79,11 @@ namespace OpenSim.Framework.Console
public List<CommandDelegate> fn;
}
public const string GeneralHelpText = "For more information, type 'help <item>' where <item> is one of the following categories:";
public const string GeneralHelpText
= "To enter an argument that contains spaces, surround the argument with double quotes.\nFor example, show object name \"My long object name\"\n";
public const string ItemHelpText
= "For more information, type 'help <item>' where <item> is one of the following:";
/// <value>
/// Commands organized by keyword in a tree
@@ -108,7 +112,9 @@ namespace OpenSim.Framework.Console
// General help
if (helpParts.Count == 0)
{
help.Add(""); // Will become a newline.
help.Add(GeneralHelpText);
help.Add(ItemHelpText);
help.AddRange(CollectModulesHelp(tree));
}
else
@@ -132,7 +138,7 @@ namespace OpenSim.Framework.Console
// Check modules first to see if we just need to display a list of those commands
if (TryCollectModuleHelp(originalHelpRequest, help))
{
help.Insert(0, GeneralHelpText);
help.Insert(0, ItemHelpText);
return help;
}

View File

@@ -0,0 +1,112 @@
/*
* 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.Text;
namespace OpenSim.Framework.Console
{
/// <summary>
/// Used to generated a formatted table for the console.
/// </summary>
/// <remarks>
/// Currently subject to change. If you use this, be prepared to change your code when this class changes.
/// </remarks>
public class ConsoleDisplayList
{
/// <summary>
/// The default divider between key and value for a list item.
/// </summary>
public const string DefaultKeyValueDivider = " : ";
/// <summary>
/// The divider used between key and value for a list item.
/// </summary>
public string KeyValueDivider { get; set; }
/// <summary>
/// Table rows
/// </summary>
public List<KeyValuePair<string, string>> Rows { get; private set; }
/// <summary>
/// Number of spaces to indent the list.
/// </summary>
public int Indent { get; set; }
public ConsoleDisplayList()
{
Rows = new List<KeyValuePair<string, string>>();
KeyValueDivider = DefaultKeyValueDivider;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
AddToStringBuilder(sb);
return sb.ToString();
}
public void AddToStringBuilder(StringBuilder sb)
{
string formatString = GetFormatString();
// System.Console.WriteLine("FORMAT STRING [{0}]", formatString);
// rows
foreach (KeyValuePair<string, string> row in Rows)
sb.AppendFormat(formatString, row.Key, row.Value);
}
/// <summary>
/// Gets the format string for the table.
/// </summary>
private string GetFormatString()
{
StringBuilder formatSb = new StringBuilder();
int longestKey = -1;
foreach (KeyValuePair<string, string> row in Rows)
if (row.Key.Length > longestKey)
longestKey = row.Key.Length;
formatSb.Append(' ', Indent);
// Can only do left formatting for now
formatSb.AppendFormat("{{0,-{0}}}{1}{{1}}\n", longestKey, KeyValueDivider);
return formatSb.ToString();
}
public void AddRow(object key, object value)
{
Rows.Add(new KeyValuePair<string, string>(key.ToString(), value.ToString()));
}
}
}

View File

@@ -0,0 +1,154 @@
/*
* 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.Text;
namespace OpenSim.Framework.Console
{
/// <summary>
/// Used to generated a formatted table for the console.
/// </summary>
/// <remarks>
/// Currently subject to change. If you use this, be prepared to change your code when this class changes.
/// </remarks>
public class ConsoleDisplayTable
{
/// <summary>
/// Default number of spaces between table columns.
/// </summary>
public const int DefaultTableSpacing = 2;
/// <summary>
/// Table columns.
/// </summary>
public List<ConsoleDisplayTableColumn> Columns { get; private set; }
/// <summary>
/// Table rows
/// </summary>
public List<ConsoleDisplayTableRow> Rows { get; private set; }
/// <summary>
/// Number of spaces to indent the table.
/// </summary>
public int Indent { get; set; }
/// <summary>
/// Spacing between table columns
/// </summary>
public int TableSpacing { get; set; }
public ConsoleDisplayTable()
{
TableSpacing = DefaultTableSpacing;
Columns = new List<ConsoleDisplayTableColumn>();
Rows = new List<ConsoleDisplayTableRow>();
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
AddToStringBuilder(sb);
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();
// System.Console.WriteLine("FORMAT STRING [{0}]", formatString);
// columns
sb.AppendFormat(formatString, Columns.ConvertAll(c => c.Header).ToArray());
// rows
foreach (ConsoleDisplayTableRow row in Rows)
sb.AppendFormat(formatString, row.Cells.ToArray());
}
/// <summary>
/// Gets the format string for the table.
/// </summary>
private string GetFormatString()
{
StringBuilder formatSb = new StringBuilder();
formatSb.Append(' ', Indent);
for (int i = 0; i < Columns.Count; i++)
{
formatSb.Append(' ', TableSpacing);
// Can only do left formatting for now
formatSb.AppendFormat("{{{0},-{1}}}", i, Columns[i].Width);
}
formatSb.Append('\n');
return formatSb.ToString();
}
}
public struct ConsoleDisplayTableColumn
{
public string Header { get; set; }
public int Width { get; set; }
public ConsoleDisplayTableColumn(string header, int width) : this()
{
Header = header;
Width = width;
}
}
public struct ConsoleDisplayTableRow
{
public List<string> Cells { get; private set; }
public ConsoleDisplayTableRow(List<string> cells) : this()
{
Cells = cells;
}
public ConsoleDisplayTableRow(params string[] cells) : this()
{
Cells = new List<string>(cells);
}
}
}

View File

@@ -296,6 +296,10 @@ namespace OpenSim.Framework.Console
matches[0].Groups["Category"].Value);
System.Console.Write("]:");
}
else
{
outText = outText.Trim();
}
}
if (level == "error")

View File

@@ -740,14 +740,21 @@ namespace OpenSim.Framework
/// </summary>
string Name { get; }
/// <value>
/// Determines whether the client thread is doing anything or not.
/// </value>
/// <summary>
/// True if the client is active (sending and receiving new UDP messages). False if the client is being closed.
/// </summary>
bool IsActive { get; set; }
/// <value>
/// Determines whether the client is or has been removed from a given scene
/// </value>
/// <summary>
/// Set if the client is closing due to a logout request
/// </summary>
/// <remarks>
/// Do not use this flag if you want to know if the client is closing, since it will not be set in other
/// circumstances (e.g. if a child agent is closed or the agent is kicked off the simulator). Use IsActive
/// instead with a IClientAPI.SceneAgent.IsChildAgent check if necessary.
///
/// Only set for root agents.
/// </remarks>
bool IsLoggingOut { get; set; }
bool SendLogoutPacketWhenClosing { set; }
@@ -1346,7 +1353,6 @@ namespace OpenSim.Framework
void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message);
void SendLogoutPacket();
EndPoint GetClientEP();
// WARNING WARNING WARNING
//
@@ -1407,8 +1413,6 @@ namespace OpenSim.Framework
void SendGroupVoteHistory(UUID groupID, UUID transactionID, GroupVoteHistory[] Votes);
void KillEndDone();
bool AddGenericPacketHandler(string MethodName, GenericMessage handler);
void SendRebakeAvatarTextures(UUID textureID);

View File

@@ -56,6 +56,11 @@ namespace OpenSim.Framework
public interface IScene
{
/// <summary>
/// The name of this scene.
/// </summary>
string Name { get; }
RegionInfo RegionInfo { get; }
RegionStatus RegionStatus { get; set; }

View File

@@ -26,6 +26,7 @@
*/
using System;
using OpenMetaverse;
namespace OpenSim.Framework
{
@@ -71,5 +72,11 @@ namespace OpenSim.Framework
/// This includes scene object data and the appearance data of other avatars.
/// </remarks>
void SendInitialDataToMe();
/// <summary>
/// Direction in which the scene presence is looking.
/// </summary>
/// <remarks>Will be Vector3.Zero for a child agent.</remarks>
Vector3 Lookat { get; }
}
}

View File

@@ -51,10 +51,12 @@ namespace OpenSim.Framework
protected object m_senderObject;
protected ChatTypeEnum m_type;
protected UUID m_fromID;
protected UUID m_toID;
public OSChatMessage()
{
m_position = new Vector3();
m_toID = UUID.Zero;
}
/// <summary>
@@ -102,6 +104,15 @@ namespace OpenSim.Framework
set { m_from = value; }
}
/// <summary>
/// The name of the sender (needed for scripts)
/// </summary>
public string To
{
get { return m_from; }
set { m_from = value; }
}
#region IEventArgs Members
/// TODO: Sender and SenderObject should just be Sender and of
@@ -131,6 +142,15 @@ namespace OpenSim.Framework
set { m_fromID = value; }
}
/// <summary>
/// The single recipient or all if not set.
/// </summary>
public UUID TargetUUID
{
get { return m_toID; }
set { m_toID = value; }
}
/// <summary>
///
/// </summary>

View File

@@ -241,10 +241,14 @@ namespace OpenSim.Framework
m_textureEntry = prim.Textures.GetBytes();
SculptEntry = (prim.Sculpt.Type != OpenMetaverse.SculptType.None);
SculptData = prim.Sculpt.GetBytes();
SculptTexture = prim.Sculpt.SculptTexture;
SculptType = (byte)prim.Sculpt.Type;
if (prim.Sculpt != null)
{
SculptEntry = (prim.Sculpt.Type != OpenMetaverse.SculptType.None);
SculptData = prim.Sculpt.GetBytes();
SculptTexture = prim.Sculpt.SculptTexture;
SculptType = (byte)prim.Sculpt.Type;
}
else SculptType = (byte)OpenMetaverse.SculptType.None;
}
[XmlIgnore]

View File

@@ -29,6 +29,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using OpenMetaverse;
using System.Runtime.Serialization;
namespace OpenSim.Framework
{
@@ -71,6 +72,32 @@ namespace OpenSim.Framework
return pos + offset;
}
/// <summary>
/// Returns a string representation of this SpawnPoint.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return string.Format("{0},{1},{2}", Yaw, Pitch, Distance);
}
/// <summary>
/// Generate a SpawnPoint from a string
/// </summary>
/// <param name="str"></param>
public static SpawnPoint Parse(string str)
{
string[] parts = str.Split(',');
if (parts.Length != 3)
throw new ArgumentException("Invalid string: " + str);
SpawnPoint sp = new SpawnPoint();
sp.Yaw = float.Parse(parts[0]);
sp.Pitch = float.Parse(parts[1]);
sp.Distance = float.Parse(parts[2]);
return sp;
}
}
public class RegionSettings
@@ -456,7 +483,7 @@ namespace OpenSim.Framework
}
// Connected Telehub object
private UUID m_TelehubObject;
private UUID m_TelehubObject = UUID.Zero;
public UUID TelehubObject
{
get

View File

@@ -38,239 +38,189 @@ namespace OpenSim.Framework
public static class SLUtil
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#region SL / file extension / content-type conversions
private class TypeMapping
{
private sbyte assetType;
private InventoryType inventoryType;
private string contentType;
private string contentType2;
private string extension;
public sbyte AssetTypeCode
{
get { return assetType; }
}
public object AssetType
{
get {
if (Enum.IsDefined(typeof(OpenMetaverse.AssetType), assetType))
return (OpenMetaverse.AssetType)assetType;
else
return OpenMetaverse.AssetType.Unknown;
}
}
public InventoryType InventoryType
{
get { return inventoryType; }
}
public string ContentType
{
get { return contentType; }
}
public string ContentType2
{
get { return contentType2; }
}
public string Extension
{
get { return extension; }
}
private TypeMapping(sbyte assetType, InventoryType inventoryType, string contentType, string contentType2, string extension)
{
this.assetType = assetType;
this.inventoryType = inventoryType;
this.contentType = contentType;
this.contentType2 = contentType2;
this.extension = extension;
}
public TypeMapping(AssetType assetType, InventoryType inventoryType, string contentType, string contentType2, string extension)
: this((sbyte)assetType, inventoryType, contentType, contentType2, extension)
{
}
public TypeMapping(AssetType assetType, InventoryType inventoryType, string contentType, string extension)
: this((sbyte)assetType, inventoryType, contentType, null, extension)
{
}
}
/// <summary>
/// Maps between AssetType, InventoryType and Content-Type.
/// Where more than one possibility exists, the first one takes precedence. E.g.:
/// AssetType "AssetType.Texture" -> Content-Type "image-xj2c"
/// Content-Type "image/x-j2c" -> InventoryType "InventoryType.Texture"
/// </summary>
private static TypeMapping[] MAPPINGS = new TypeMapping[] {
new TypeMapping(AssetType.Unknown, InventoryType.Unknown, "application/octet-stream", "bin"),
new TypeMapping(AssetType.Texture, InventoryType.Texture, "image/x-j2c", "image/jp2", "j2c"),
new TypeMapping(AssetType.Texture, InventoryType.Snapshot, "image/x-j2c", "image/jp2", "j2c"),
new TypeMapping(AssetType.TextureTGA, InventoryType.Texture, "image/tga", "tga"),
new TypeMapping(AssetType.ImageTGA, InventoryType.Texture, "image/tga", "tga"),
new TypeMapping(AssetType.ImageJPEG, InventoryType.Texture, "image/jpeg", "jpg"),
new TypeMapping(AssetType.Sound, InventoryType.Sound, "audio/ogg", "application/ogg", "ogg"),
new TypeMapping(AssetType.SoundWAV, InventoryType.Sound, "audio/x-wav", "wav"),
new TypeMapping(AssetType.CallingCard, InventoryType.CallingCard, "application/vnd.ll.callingcard", "application/x-metaverse-callingcard", "callingcard"),
new TypeMapping(AssetType.Landmark, InventoryType.Landmark, "application/vnd.ll.landmark", "application/x-metaverse-landmark", "landmark"),
new TypeMapping(AssetType.Clothing, InventoryType.Wearable, "application/vnd.ll.clothing", "application/x-metaverse-clothing", "clothing"),
new TypeMapping(AssetType.Object, InventoryType.Object, "application/vnd.ll.primitive", "application/x-metaverse-primitive", "primitive"),
new TypeMapping(AssetType.Object, InventoryType.Attachment, "application/vnd.ll.primitive", "application/x-metaverse-primitive", "primitive"),
new TypeMapping(AssetType.Notecard, InventoryType.Notecard, "application/vnd.ll.notecard", "application/x-metaverse-notecard", "notecard"),
new TypeMapping(AssetType.Folder, InventoryType.Folder, "application/vnd.ll.folder", "folder"),
new TypeMapping(AssetType.RootFolder, InventoryType.RootCategory, "application/vnd.ll.rootfolder", "rootfolder"),
new TypeMapping(AssetType.LSLText, InventoryType.LSL, "application/vnd.ll.lsltext", "application/x-metaverse-lsl", "lsl"),
new TypeMapping(AssetType.LSLBytecode, InventoryType.LSL, "application/vnd.ll.lslbyte", "application/x-metaverse-lso", "lso"),
new TypeMapping(AssetType.Bodypart, InventoryType.Wearable, "application/vnd.ll.bodypart", "application/x-metaverse-bodypart", "bodypart"),
new TypeMapping(AssetType.TrashFolder, InventoryType.Folder, "application/vnd.ll.trashfolder", "trashfolder"),
new TypeMapping(AssetType.SnapshotFolder, InventoryType.Folder, "application/vnd.ll.snapshotfolder", "snapshotfolder"),
new TypeMapping(AssetType.LostAndFoundFolder, InventoryType.Folder, "application/vnd.ll.lostandfoundfolder", "lostandfoundfolder"),
new TypeMapping(AssetType.Animation, InventoryType.Animation, "application/vnd.ll.animation", "application/x-metaverse-animation", "animation"),
new TypeMapping(AssetType.Gesture, InventoryType.Gesture, "application/vnd.ll.gesture", "application/x-metaverse-gesture", "gesture"),
new TypeMapping(AssetType.Simstate, InventoryType.Snapshot, "application/x-metaverse-simstate", "simstate"),
new TypeMapping(AssetType.FavoriteFolder, InventoryType.Unknown, "application/vnd.ll.favoritefolder", "favoritefolder"),
new TypeMapping(AssetType.Link, InventoryType.Unknown, "application/vnd.ll.link", "link"),
new TypeMapping(AssetType.LinkFolder, InventoryType.Unknown, "application/vnd.ll.linkfolder", "linkfolder"),
new TypeMapping(AssetType.CurrentOutfitFolder, InventoryType.Unknown, "application/vnd.ll.currentoutfitfolder", "currentoutfitfolder"),
new TypeMapping(AssetType.OutfitFolder, InventoryType.Unknown, "application/vnd.ll.outfitfolder", "outfitfolder"),
new TypeMapping(AssetType.MyOutfitsFolder, InventoryType.Unknown, "application/vnd.ll.myoutfitsfolder", "myoutfitsfolder"),
new TypeMapping(AssetType.Mesh, InventoryType.Mesh, "application/vnd.ll.mesh", "llm")
};
private static Dictionary<sbyte, string> asset2Content;
private static Dictionary<sbyte, string> asset2Extension;
private static Dictionary<InventoryType, string> inventory2Content;
private static Dictionary<string, sbyte> content2Asset;
private static Dictionary<string, InventoryType> content2Inventory;
static SLUtil()
{
asset2Content = new Dictionary<sbyte, string>();
asset2Extension = new Dictionary<sbyte, string>();
inventory2Content = new Dictionary<InventoryType, string>();
content2Asset = new Dictionary<string, sbyte>();
content2Inventory = new Dictionary<string, InventoryType>();
foreach (TypeMapping mapping in MAPPINGS)
{
sbyte assetType = mapping.AssetTypeCode;
if (!asset2Content.ContainsKey(assetType))
asset2Content.Add(assetType, mapping.ContentType);
if (!asset2Extension.ContainsKey(assetType))
asset2Extension.Add(assetType, mapping.Extension);
if (!inventory2Content.ContainsKey(mapping.InventoryType))
inventory2Content.Add(mapping.InventoryType, mapping.ContentType);
if (!content2Asset.ContainsKey(mapping.ContentType))
content2Asset.Add(mapping.ContentType, assetType);
if (!content2Inventory.ContainsKey(mapping.ContentType))
content2Inventory.Add(mapping.ContentType, mapping.InventoryType);
if (mapping.ContentType2 != null)
{
if (!content2Asset.ContainsKey(mapping.ContentType2))
content2Asset.Add(mapping.ContentType2, assetType);
if (!content2Inventory.ContainsKey(mapping.ContentType2))
content2Inventory.Add(mapping.ContentType2, mapping.InventoryType);
}
}
}
public static string SLAssetTypeToContentType(int assetType)
{
switch ((AssetType)assetType)
{
case AssetType.Texture:
return "image/x-j2c";
case AssetType.Sound:
return "audio/ogg";
case AssetType.CallingCard:
return "application/vnd.ll.callingcard";
case AssetType.Landmark:
return "application/vnd.ll.landmark";
case AssetType.Clothing:
return "application/vnd.ll.clothing";
case AssetType.Object:
return "application/vnd.ll.primitive";
case AssetType.Notecard:
return "application/vnd.ll.notecard";
case AssetType.Folder:
return "application/vnd.ll.folder";
case AssetType.RootFolder:
return "application/vnd.ll.rootfolder";
case AssetType.LSLText:
return "application/vnd.ll.lsltext";
case AssetType.LSLBytecode:
return "application/vnd.ll.lslbyte";
case AssetType.TextureTGA:
case AssetType.ImageTGA:
return "image/tga";
case AssetType.Bodypart:
return "application/vnd.ll.bodypart";
case AssetType.TrashFolder:
return "application/vnd.ll.trashfolder";
case AssetType.SnapshotFolder:
return "application/vnd.ll.snapshotfolder";
case AssetType.LostAndFoundFolder:
return "application/vnd.ll.lostandfoundfolder";
case AssetType.SoundWAV:
return "audio/x-wav";
case AssetType.ImageJPEG:
return "image/jpeg";
case AssetType.Animation:
return "application/vnd.ll.animation";
case AssetType.Gesture:
return "application/vnd.ll.gesture";
case AssetType.Simstate:
return "application/x-metaverse-simstate";
case AssetType.FavoriteFolder:
return "application/vnd.ll.favoritefolder";
case AssetType.Link:
return "application/vnd.ll.link";
case AssetType.LinkFolder:
return "application/vnd.ll.linkfolder";
case AssetType.CurrentOutfitFolder:
return "application/vnd.ll.currentoutfitfolder";
case AssetType.OutfitFolder:
return "application/vnd.ll.outfitfolder";
case AssetType.MyOutfitsFolder:
return "application/vnd.ll.myoutfitsfolder";
case AssetType.Unknown:
default:
return "application/octet-stream";
}
string contentType;
if (!asset2Content.TryGetValue((sbyte)assetType, out contentType))
contentType = asset2Content[(sbyte)AssetType.Unknown];
return contentType;
}
public static string SLInvTypeToContentType(int invType)
{
switch ((InventoryType)invType)
{
case InventoryType.Animation:
return "application/vnd.ll.animation";
case InventoryType.CallingCard:
return "application/vnd.ll.callingcard";
case InventoryType.Folder:
return "application/vnd.ll.folder";
case InventoryType.Gesture:
return "application/vnd.ll.gesture";
case InventoryType.Landmark:
return "application/vnd.ll.landmark";
case InventoryType.LSL:
return "application/vnd.ll.lsltext";
case InventoryType.Notecard:
return "application/vnd.ll.notecard";
case InventoryType.Attachment:
case InventoryType.Object:
return "application/vnd.ll.primitive";
case InventoryType.Sound:
return "audio/ogg";
case InventoryType.Snapshot:
case InventoryType.Texture:
return "image/x-j2c";
case InventoryType.Wearable:
return "application/vnd.ll.clothing";
default:
return "application/octet-stream";
}
string contentType;
if (!inventory2Content.TryGetValue((InventoryType)invType, out contentType))
contentType = inventory2Content[InventoryType.Unknown];
return contentType;
}
public static sbyte ContentTypeToSLAssetType(string contentType)
{
switch (contentType)
{
case "image/x-j2c":
case "image/jp2":
return (sbyte)AssetType.Texture;
case "application/ogg":
case "audio/ogg":
return (sbyte)AssetType.Sound;
case "application/vnd.ll.callingcard":
case "application/x-metaverse-callingcard":
return (sbyte)AssetType.CallingCard;
case "application/vnd.ll.landmark":
case "application/x-metaverse-landmark":
return (sbyte)AssetType.Landmark;
case "application/vnd.ll.clothing":
case "application/x-metaverse-clothing":
return (sbyte)AssetType.Clothing;
case "application/vnd.ll.primitive":
case "application/x-metaverse-primitive":
return (sbyte)AssetType.Object;
case "application/vnd.ll.notecard":
case "application/x-metaverse-notecard":
return (sbyte)AssetType.Notecard;
case "application/vnd.ll.folder":
return (sbyte)AssetType.Folder;
case "application/vnd.ll.rootfolder":
return (sbyte)AssetType.RootFolder;
case "application/vnd.ll.lsltext":
case "application/x-metaverse-lsl":
return (sbyte)AssetType.LSLText;
case "application/vnd.ll.lslbyte":
case "application/x-metaverse-lso":
return (sbyte)AssetType.LSLBytecode;
case "image/tga":
// Note that AssetType.TextureTGA will be converted to AssetType.ImageTGA
return (sbyte)AssetType.ImageTGA;
case "application/vnd.ll.bodypart":
case "application/x-metaverse-bodypart":
return (sbyte)AssetType.Bodypart;
case "application/vnd.ll.trashfolder":
return (sbyte)AssetType.TrashFolder;
case "application/vnd.ll.snapshotfolder":
return (sbyte)AssetType.SnapshotFolder;
case "application/vnd.ll.lostandfoundfolder":
return (sbyte)AssetType.LostAndFoundFolder;
case "audio/x-wav":
return (sbyte)AssetType.SoundWAV;
case "image/jpeg":
return (sbyte)AssetType.ImageJPEG;
case "application/vnd.ll.animation":
case "application/x-metaverse-animation":
return (sbyte)AssetType.Animation;
case "application/vnd.ll.gesture":
case "application/x-metaverse-gesture":
return (sbyte)AssetType.Gesture;
case "application/x-metaverse-simstate":
return (sbyte)AssetType.Simstate;
case "application/vnd.ll.favoritefolder":
return (sbyte)AssetType.FavoriteFolder;
case "application/vnd.ll.link":
return (sbyte)AssetType.Link;
case "application/vnd.ll.linkfolder":
return (sbyte)AssetType.LinkFolder;
case "application/vnd.ll.currentoutfitfolder":
return (sbyte)AssetType.CurrentOutfitFolder;
case "application/vnd.ll.outfitfolder":
return (sbyte)AssetType.OutfitFolder;
case "application/vnd.ll.myoutfitsfolder":
return (sbyte)AssetType.MyOutfitsFolder;
case "application/octet-stream":
default:
return (sbyte)AssetType.Unknown;
}
sbyte assetType;
if (!content2Asset.TryGetValue(contentType, out assetType))
assetType = (sbyte)AssetType.Unknown;
return (sbyte)assetType;
}
public static sbyte ContentTypeToSLInvType(string contentType)
{
switch (contentType)
{
case "image/x-j2c":
case "image/jp2":
case "image/tga":
case "image/jpeg":
return (sbyte)InventoryType.Texture;
case "application/ogg":
case "audio/ogg":
case "audio/x-wav":
return (sbyte)InventoryType.Sound;
case "application/vnd.ll.callingcard":
case "application/x-metaverse-callingcard":
return (sbyte)InventoryType.CallingCard;
case "application/vnd.ll.landmark":
case "application/x-metaverse-landmark":
return (sbyte)InventoryType.Landmark;
case "application/vnd.ll.clothing":
case "application/x-metaverse-clothing":
case "application/vnd.ll.bodypart":
case "application/x-metaverse-bodypart":
return (sbyte)InventoryType.Wearable;
case "application/vnd.ll.primitive":
case "application/x-metaverse-primitive":
return (sbyte)InventoryType.Object;
case "application/vnd.ll.notecard":
case "application/x-metaverse-notecard":
return (sbyte)InventoryType.Notecard;
case "application/vnd.ll.folder":
return (sbyte)InventoryType.Folder;
case "application/vnd.ll.rootfolder":
return (sbyte)InventoryType.RootCategory;
case "application/vnd.ll.lsltext":
case "application/x-metaverse-lsl":
case "application/vnd.ll.lslbyte":
case "application/x-metaverse-lso":
return (sbyte)InventoryType.LSL;
case "application/vnd.ll.trashfolder":
case "application/vnd.ll.snapshotfolder":
case "application/vnd.ll.lostandfoundfolder":
return (sbyte)InventoryType.Folder;
case "application/vnd.ll.animation":
case "application/x-metaverse-animation":
return (sbyte)InventoryType.Animation;
case "application/vnd.ll.gesture":
case "application/x-metaverse-gesture":
return (sbyte)InventoryType.Gesture;
case "application/x-metaverse-simstate":
return (sbyte)InventoryType.Snapshot;
case "application/octet-stream":
default:
return (sbyte)InventoryType.Unknown;
}
InventoryType invType;
if (!content2Inventory.TryGetValue(contentType, out invType))
invType = InventoryType.Unknown;
return (sbyte)invType;
}
public static string SLAssetTypeToExtension(int assetType)
{
string extension;
if (!asset2Extension.TryGetValue((sbyte)assetType, out extension))
extension = asset2Extension[(sbyte)AssetType.Unknown];
return extension;
}
#endregion SL / file extension / content-type conversions
@@ -377,4 +327,4 @@ namespace OpenSim.Framework
return output;
}
}
}
}

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>>();
@@ -163,7 +161,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>

View File

@@ -30,6 +30,8 @@ using System.Text;
using System.Xml;
using OpenMetaverse;
using OpenSim.Framework;
using log4net;
using System.Reflection;
namespace OpenSim.Framework.Serialization.External
{
@@ -38,8 +40,6 @@ namespace OpenSim.Framework.Serialization.External
/// </summary>
public class RegionSettingsSerializer
{
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
/// <summary>
/// Deserialize settings
/// </summary>
@@ -48,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>
@@ -187,7 +187,29 @@ namespace OpenSim.Framework.Serialization.External
break;
}
}
xtr.ReadEndElement();
if (xtr.IsStartElement("Telehub"))
{
xtr.ReadStartElement("Telehub");
while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement)
{
switch (xtr.Name)
{
case "TelehubObject":
settings.TelehubObject = UUID.Parse(xtr.ReadElementContentAsString());
break;
case "SpawnPoint":
string str = xtr.ReadElementContentAsString();
SpawnPoint sp = SpawnPoint.Parse(str);
settings.AddSpawnPoint(sp);
break;
}
}
}
xtr.Close();
sr.Close();
@@ -243,7 +265,16 @@ namespace OpenSim.Framework.Serialization.External
xtw.WriteElementString("SunPosition", settings.SunPosition.ToString());
// Note: 'SunVector' isn't saved because this value is owned by the Sun Module, which
// calculates it automatically according to the date and other factors.
xtw.WriteEndElement();
xtw.WriteEndElement();
xtw.WriteStartElement("Telehub");
if (settings.TelehubObject != UUID.Zero)
{
xtw.WriteElementString("TelehubObject", settings.TelehubObject.ToString());
foreach (SpawnPoint sp in settings.SpawnPoints())
xtw.WriteElementString("SpawnPoint", sp.ToString());
}
xtw.WriteEndElement();
xtw.WriteEndElement();

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

@@ -78,6 +78,10 @@ namespace OpenSim.Framework.Serialization.Tests
<FixedSun>true</FixedSun>
<SunPosition>12</SunPosition>
</Terrain>
<Telehub>
<TelehubObject>00000000-0000-0000-0000-111111111111</TelehubObject>
<SpawnPoint>1,-2,0.33</SpawnPoint>
</Telehub>
</RegionSettings>";
private RegionSettings m_rs;
@@ -116,6 +120,8 @@ namespace OpenSim.Framework.Serialization.Tests
m_rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080");
m_rs.UseEstateSun = true;
m_rs.WaterHeight = 23;
m_rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111");
m_rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33"));
}
[Test]
@@ -129,6 +135,8 @@ namespace OpenSim.Framework.Serialization.Tests
Assert.That(deserRs.TerrainTexture2, Is.EqualTo(m_rs.TerrainTexture2));
Assert.That(deserRs.DisablePhysics, Is.EqualTo(m_rs.DisablePhysics));
Assert.That(deserRs.TerrainLowerLimit, Is.EqualTo(m_rs.TerrainLowerLimit));
Assert.That(deserRs.TelehubObject, Is.EqualTo(m_rs.TelehubObject));
Assert.That(deserRs.SpawnPoints()[0].ToString(), Is.EqualTo(m_rs.SpawnPoints()[0].ToString()));
}
}
}

View File

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

@@ -33,9 +33,9 @@ namespace OpenSim.Framework.Servers.HttpServer
{
public abstract Hashtable Handle(string path, Hashtable Request);
protected BaseHTTPHandler(string httpMethod, string path)
: base(httpMethod, path)
{
}
protected BaseHTTPHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
protected BaseHTTPHandler(string httpMethod, string path, string name, string description)
: base(httpMethod, path, name, description) {}
}
}
}

View File

@@ -53,6 +53,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 +81,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; }
@@ -156,7 +153,7 @@ namespace OpenSim.Framework.Servers.HttpServer
}
}
public List<string> GetStreamHandlerKeys()
public List<string> GetStreamHandlerKeys()
{
lock (m_streamHandlers)
return new List<string>(m_streamHandlers.Keys);
@@ -356,7 +353,7 @@ namespace OpenSim.Framework.Servers.HttpServer
}
catch (Exception e)
{
m_log.ErrorFormat("[BASE HTTP SERVER]: OnRequest() failed with {0}{1}", e.Message, e.StackTrace);
m_log.Error(String.Format("[BASE HTTP SERVER]: OnRequest() failed: {0} ", e.Message), e);
}
}
@@ -408,7 +405,12 @@ namespace OpenSim.Framework.Servers.HttpServer
string uriString = request.RawUrl;
// string reqnum = "unknown";
int tickstart = Environment.TickCount;
int requestStartTick = Environment.TickCount;
// Will be adjusted later on.
int requestEndTick = requestStartTick;
IRequestHandler requestHandler = null;
try
{
@@ -431,6 +433,7 @@ namespace OpenSim.Framework.Servers.HttpServer
{
if (HandleAgentRequest(agentHandler, request, response))
{
requestEndTick = Environment.TickCount;
return;
}
}
@@ -438,20 +441,16 @@ namespace OpenSim.Framework.Servers.HttpServer
//response.KeepAlive = true;
response.SendChunked = false;
IRequestHandler requestHandler;
string path = request.RawUrl;
string handlerKey = GetHandlerKey(request.HttpMethod, path);
byte[] buffer = null;
if (TryGetStreamHandler(handlerKey, out requestHandler))
{
if (DebugLevel >= 1)
if (DebugLevel >= 3)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found stream handler for {0} {1}",
request.HttpMethod, request.Url.PathAndQuery);
// Okay, so this is bad, but should be considered temporary until everything is IStreamHandler.
byte[] buffer = null;
"[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}",
request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description);
response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type.
@@ -507,8 +506,8 @@ namespace OpenSim.Framework.Servers.HttpServer
//m_log.Warn("[HTTP]: " + requestBody);
}
DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response);
return;
buffer = DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response);
}
else
{
@@ -521,133 +520,99 @@ namespace OpenSim.Framework.Servers.HttpServer
buffer = memoryStream.ToArray();
}
}
}
else
{
switch (request.ContentType)
{
case null:
case "text/html":
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);
buffer = HandleHTTPRequest(request, response);
break;
case "application/llsd+xml":
case "application/xml+llsd":
case "application/llsd+json":
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);
buffer = HandleLLSDRequests(request, response);
break;
case "text/xml":
case "application/xml":
case "application/json":
default:
//m_log.Info("[Debug BASE HTTP SERVER]: in default handler");
// Point of note.. the DoWeHaveA methods check for an EXACT path
// if (request.RawUrl.Contains("/CAPS/EQG"))
// {
// int i = 1;
// }
//m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler");
if (DoWeHaveALLSDHandler(request.RawUrl))
{
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);
buffer = HandleLLSDRequests(request, response);
}
// m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl);
else if (DoWeHaveAHTTPHandler(request.RawUrl))
{
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);
buffer = HandleHTTPRequest(request, response);
}
else
{
if (DebugLevel >= 3)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
request.HttpMethod, request.Url.PathAndQuery);
// generic login request.
buffer = HandleXmlRpcRequests(request, response);
}
break;
}
}
request.InputStream.Close();
// HTTP IN support. The script engine takes it from here
// Nothing to worry about for us.
//
if (buffer == null)
return;
request.InputStream.Close();
if (buffer != null)
{
if (!response.SendChunked)
response.ContentLength64 = buffer.LongLength;
try
{
response.OutputStream.Write(buffer, 0, buffer.Length);
//response.OutputStream.Close();
}
catch (HttpListenerException)
{
m_log.WarnFormat("[BASE HTTP SERVER]: HTTP request abnormally terminated.");
}
//response.OutputStream.Close();
try
{
response.Send();
//response.FreeContext();
}
catch (SocketException e)
{
// This has to be here to prevent a Linux/Mono crash
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
}
catch (IOException e)
{
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
}
return;
response.OutputStream.Write(buffer, 0, buffer.Length);
}
if (request.AcceptTypes != null && request.AcceptTypes.Length > 0)
{
foreach (string strAccept in request.AcceptTypes)
{
if (strAccept.Contains("application/llsd+xml") ||
strAccept.Contains("application/llsd+json"))
{
if (DebugLevel >= 1)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found application/llsd+xml accept header handler for {0} {1}",
request.HttpMethod, request.Url.PathAndQuery);
// Do not include the time taken to actually send the response to the caller in the measurement
// time. This is to avoid logging when it's the client that is slow to process rather than the
// server
requestEndTick = Environment.TickCount;
HandleLLSDRequests(request, response);
return;
}
}
}
response.Send();
switch (request.ContentType)
{
case null:
case "text/html":
//response.OutputStream.Close();
if (DebugLevel >= 1)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
HandleHTTPRequest(request, response);
return;
case "application/llsd+xml":
case "application/xml+llsd":
case "application/llsd+json":
if (DebugLevel >= 1)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
HandleLLSDRequests(request, response);
return;
case "text/xml":
case "application/xml":
case "application/json":
default:
//m_log.Info("[Debug BASE HTTP SERVER]: in default handler");
// Point of note.. the DoWeHaveA methods check for an EXACT path
// if (request.RawUrl.Contains("/CAPS/EQG"))
// {
// int i = 1;
// }
//m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler");
if (DoWeHaveALLSDHandler(request.RawUrl))
{
if (DebugLevel >= 1)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
HandleLLSDRequests(request, response);
return;
}
// m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl);
if (DoWeHaveAHTTPHandler(request.RawUrl))
{
if (DebugLevel >= 1)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
HandleHTTPRequest(request, response);
return;
}
if (DebugLevel >= 1)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
request.HttpMethod, request.Url.PathAndQuery);
// generic login request.
HandleXmlRpcRequests(request, response);
return;
}
//response.FreeContext();
}
catch (SocketException e)
{
@@ -658,25 +623,33 @@ namespace OpenSim.Framework.Servers.HttpServer
//
// An alternative may be to turn off all response write exceptions on the HttpListener, but let's go
// with the minimum first
m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e);
m_log.Warn(String.Format("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux ", e.Message), e);
}
catch (IOException e)
{
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}{1}", e.Message, e.StackTrace);
m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e);
}
catch (Exception e)
{
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}{1}", e.Message, e.StackTrace);
m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e);
SendHTML500(response);
}
finally
{
// Every month or so this will wrap and give bad numbers, not really a problem
// since its just for reporting, tickdiff limit can be adjusted
int tickdiff = Environment.TickCount - tickstart;
// since its just for reporting
int tickdiff = requestEndTick - requestStartTick;
if (tickdiff > 3000)
{
m_log.InfoFormat(
"[BASE HTTP SERVER]: slow {0} request for {1} from {2} took {3} ms", requestMethod, uriString, request.RemoteIPEndPoint.ToString(), tickdiff);
"[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms",
requestMethod,
uriString,
requestHandler != null ? requestHandler.Name : "",
requestHandler != null ? requestHandler.Description : "",
request.RemoteIPEndPoint.ToString(),
tickdiff);
}
}
}
@@ -797,7 +770,7 @@ namespace OpenSim.Framework.Servers.HttpServer
/// </summary>
/// <param name="request"></param>
/// <param name="response"></param>
private void HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response)
private byte[] HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response)
{
Stream requestStream = request.InputStream;
@@ -816,8 +789,23 @@ namespace OpenSim.Framework.Servers.HttpServer
{
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)
@@ -887,6 +875,7 @@ namespace OpenSim.Framework.Servers.HttpServer
String.Format("Requested method [{0}] not found", methodName));
}
response.ContentType = "text/xml";
responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse);
}
else
@@ -896,82 +885,25 @@ namespace OpenSim.Framework.Servers.HttpServer
response.StatusCode = 404;
response.StatusDescription = "Not Found";
response.ProtocolVersion = "HTTP/1.0";
byte[] buf = Encoding.UTF8.GetBytes("Not found");
responseString = "Not found";
response.KeepAlive = false;
m_log.ErrorFormat(
"[BASE HTTP SERVER]: Handler not found for http request {0} {1}",
request.HttpMethod, request.Url.PathAndQuery);
response.SendChunked = false;
response.ContentLength64 = buf.Length;
response.ContentEncoding = Encoding.UTF8;
try
{
response.OutputStream.Write(buf, 0, buf.Length);
}
catch (Exception ex)
{
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
}
finally
{
try
{
response.Send();
//response.FreeContext();
}
catch (SocketException e)
{
// This has to be here to prevent a Linux/Mono crash
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
}
catch (IOException e)
{
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
}
}
return;
//responseString = "Error";
}
}
response.ContentType = "text/xml";
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
response.SendChunked = false;
response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8;
try
{
response.OutputStream.Write(buffer, 0, buffer.Length);
}
catch (Exception ex)
{
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
}
finally
{
try
{
response.Send();
//response.FreeContext();
}
catch (SocketException e)
{
// This has to be here to prevent a Linux/Mono crash
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
}
catch (IOException e)
{
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
}
}
return buffer;
}
private void HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response)
private byte[] HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response)
{
//m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request");
Stream requestStream = request.InputStream;
@@ -1057,34 +989,7 @@ namespace OpenSim.Framework.Servers.HttpServer
response.ContentEncoding = Encoding.UTF8;
response.KeepAlive = true;
try
{
response.OutputStream.Write(buffer, 0, buffer.Length);
}
catch (Exception ex)
{
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
}
finally
{
//response.OutputStream.Close();
try
{
response.Send();
response.OutputStream.Flush();
//response.FreeContext();
//response.OutputStream.Close();
}
catch (IOException e)
{
m_log.WarnFormat("[BASE HTTP SERVER]: LLSD IOException {0}.", e);
}
catch (SocketException e)
{
// This has to be here to prevent a Linux/Mono crash
m_log.WarnFormat("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux.", e);
}
}
return buffer;
}
private byte[] BuildLLSDResponse(OSHttpRequest request, OSHttpResponse response, OSD llsdResponse)
@@ -1334,8 +1239,8 @@ namespace OpenSim.Framework.Servers.HttpServer
catch (SocketException f)
{
// This has to be here to prevent a Linux/Mono crash
m_log.WarnFormat(
"[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", f);
m_log.Warn(
String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", f.Message), f);
}
}
catch(Exception)
@@ -1349,7 +1254,7 @@ namespace OpenSim.Framework.Servers.HttpServer
}
public void HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response)
public byte[] HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response)
{
// m_log.DebugFormat(
// "[BASE HTTP SERVER]: HandleHTTPRequest for request to {0}, method {1}",
@@ -1359,15 +1264,14 @@ namespace OpenSim.Framework.Servers.HttpServer
{
case "OPTIONS":
response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
return;
return null;
default:
HandleContentVerbs(request, response);
return;
return HandleContentVerbs(request, response);
}
}
private void HandleContentVerbs(OSHttpRequest request, OSHttpResponse response)
private byte[] HandleContentVerbs(OSHttpRequest request, OSHttpResponse response)
{
// m_log.DebugFormat("[BASE HTTP SERVER]: HandleContentVerbs for request to {0}", request.RawUrl);
@@ -1383,6 +1287,8 @@ namespace OpenSim.Framework.Servers.HttpServer
// to display the form, or process it.
// a better way would be nifty.
byte[] buffer;
Stream requestStream = request.InputStream;
Encoding encoding = Encoding.UTF8;
@@ -1443,14 +1349,14 @@ namespace OpenSim.Framework.Servers.HttpServer
if (foundHandler)
{
Hashtable responsedata1 = requestprocessor(keysvals);
DoHTTPGruntWork(responsedata1,response);
buffer = DoHTTPGruntWork(responsedata1,response);
//SendHTML500(response);
}
else
{
// m_log.Warn("[BASE HTTP SERVER]: Handler Not Found");
SendHTML404(response, host);
buffer = SendHTML404(response, host);
}
}
else
@@ -1460,16 +1366,18 @@ namespace OpenSim.Framework.Servers.HttpServer
if (foundHandler)
{
Hashtable responsedata2 = requestprocessor(keysvals);
DoHTTPGruntWork(responsedata2, response);
buffer = DoHTTPGruntWork(responsedata2, response);
//SendHTML500(response);
}
else
{
// m_log.Warn("[BASE HTTP SERVER]: Handler Not Found2");
SendHTML404(response, host);
buffer = SendHTML404(response, host);
}
}
return buffer;
}
private bool TryGetHTTPHandlerPathBased(string path, out GenericHTTPMethod httpHandler)
@@ -1537,14 +1445,13 @@ namespace OpenSim.Framework.Servers.HttpServer
}
}
internal void DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
{
//m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
int responsecode = (int)responsedata["int_response_code"];
string responseString = (string)responsedata["str_response_string"];
string contentType = (string)responsedata["content_type"];
if (responsedata.ContainsKey("error_status_text"))
{
response.StatusDescription = (string)responsedata["error_status_text"];
@@ -1608,38 +1515,10 @@ namespace OpenSim.Framework.Servers.HttpServer
response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8;
try
{
response.OutputStream.Write(buffer, 0, buffer.Length);
}
catch (Exception ex)
{
m_log.Warn("[HTTPD]: Error - " + ex.Message);
}
finally
{
//response.OutputStream.Close();
try
{
response.OutputStream.Flush();
response.Send();
//if (!response.KeepAlive && response.ReuseContext)
// response.FreeContext();
}
catch (SocketException e)
{
// This has to be here to prevent a Linux/Mono crash
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
}
catch (IOException e)
{
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
}
}
return buffer;
}
public void SendHTML404(OSHttpResponse response, string host)
public byte[] SendHTML404(OSHttpResponse response, string host)
{
// I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
response.StatusCode = 404;
@@ -1652,31 +1531,10 @@ namespace OpenSim.Framework.Servers.HttpServer
response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8;
try
{
response.OutputStream.Write(buffer, 0, buffer.Length);
}
catch (Exception ex)
{
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
}
finally
{
//response.OutputStream.Close();
try
{
response.Send();
//response.FreeContext();
}
catch (SocketException e)
{
// This has to be here to prevent a Linux/Mono crash
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
}
}
return buffer;
}
public void SendHTML500(OSHttpResponse response)
public byte[] SendHTML500(OSHttpResponse response)
{
// I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
@@ -1688,28 +1546,8 @@ namespace OpenSim.Framework.Servers.HttpServer
response.SendChunked = false;
response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8;
try
{
response.OutputStream.Write(buffer, 0, buffer.Length);
}
catch (Exception ex)
{
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
}
finally
{
//response.OutputStream.Close();
try
{
response.Send();
//response.FreeContext();
}
catch (SocketException e)
{
// This has to be here to prevent a Linux/Mono crash
m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
}
}
return buffer;
}
public void Start()
@@ -1719,6 +1557,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();
@@ -1786,7 +1627,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public void httpServerException(object source, Exception exception)
{
m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString());
m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1} ", source.ToString(), exception.Message), exception);
/*
if (HTTPDRunning)// && NotSocketErrors > 5)
{

View File

@@ -45,8 +45,16 @@ namespace OpenSim.Framework.Servers.HttpServer
private readonly string m_path;
protected BaseRequestHandler(string httpMethod, string path)
public string Name { get; private set; }
public string Description { get; private set; }
protected BaseRequestHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
protected BaseRequestHandler(string httpMethod, string path, string name, string description)
{
Name = name;
Description = description;
m_httpMethod = httpMethod;
m_path = path;
}

View File

@@ -34,8 +34,9 @@ namespace OpenSim.Framework.Servers.HttpServer
public abstract byte[] Handle(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse);
protected BaseStreamHandler(string httpMethod, string path) : base(httpMethod, path)
{
}
protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
protected BaseStreamHandler(string httpMethod, string path, string name, string description)
: base(httpMethod, path, name, description) {}
}
}
}

View File

@@ -36,6 +36,15 @@ namespace OpenSim.Framework.Servers.HttpServer
{
private BinaryMethod m_method;
public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod)
: this(httpMethod, path, binaryMethod, null, null) {}
public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod, string name, string description)
: base(httpMethod, path, name, description)
{
m_method = binaryMethod;
}
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
byte[] data = ReadFully(request);
@@ -45,12 +54,6 @@ namespace OpenSim.Framework.Servers.HttpServer
return Encoding.UTF8.GetBytes(responseString);
}
public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod)
: base(httpMethod, path)
{
m_method = binaryMethod;
}
private static byte[] ReadFully(Stream stream)
{
byte[] buffer = new byte[1024];
@@ -70,4 +73,4 @@ namespace OpenSim.Framework.Servers.HttpServer
}
}
}
}
}

View File

@@ -128,11 +128,5 @@ namespace OpenSim.Framework.Servers.HttpServer
/// <param name="value">string containing the header field
/// value</param>
void AddHeader(string key, string value);
/// <summary>
/// Send the response back to the remote client
/// </summary>
void Send();
}
}
}

View File

@@ -32,6 +32,25 @@ namespace OpenSim.Framework.Servers.HttpServer
{
public interface IRequestHandler
{
/// <summary>
/// Name for this handler.
/// </summary>
/// <remarks>
/// Used for diagnostics. The path doesn't always describe what the handler does. Can be null if none
/// specified.
/// </remarks>
string Name { get; }
/// <summary>
/// Description for this handler.
/// </summary>
/// <remarks>
/// Used for diagnostics. The path doesn't always describe what the handler does. Can be null if none
/// specified.
/// </remarks>
string Description { get; }
// Return response content type
string ContentType { get; }
@@ -58,4 +77,4 @@ namespace OpenSim.Framework.Servers.HttpServer
{
Hashtable Handle(string path, Hashtable request);
}
}
}

View File

@@ -107,7 +107,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public bool IsSecured
{
get { return _context.Secured; }
get { return _context.IsSecured; }
}
public bool KeepAlive

View File

@@ -321,13 +321,12 @@ namespace OpenSim.Framework.Servers.HttpServer
{
_httpResponse.Body.Flush();
_httpResponse.Send();
}
public void FreeContext()
{
if (_httpClientContext != null)
_httpClientContext.Close();
}
}
}

View File

@@ -28,143 +28,252 @@
namespace OpenSim.Framework.Servers.HttpServer
{
/// <summary>
/// HTTP status codes (almost) as defined by W3C in
/// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
/// HTTP status codes (almost) as defined by W3C in http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html and IETF in http://tools.ietf.org/html/rfc6585
/// </summary>
public enum OSHttpStatusCode: int
public enum OSHttpStatusCode : int
{
// 1xx Informational status codes providing a provisional
// response.
// 100 Tells client that to keep on going sending its request
InfoContinue = 100,
// 101 Server understands request, proposes to switch to different
// application level protocol
InfoSwitchingProtocols = 101,
#region 1xx Informational status codes providing a provisional response.
/// <summary>
/// 100 Tells client that to keep on going sending its request
/// </summary>
InfoContinue = 100,
// 2xx Success codes
// 200 Request successful
SuccessOk = 200,
// 201 Request successful, new resource created
SuccessOkCreated = 201,
// 202 Request accepted, processing still on-going
SuccessOkAccepted = 202,
// 203 Request successful, meta information not authoritative
SuccessOkNonAuthoritativeInformation = 203,
// 204 Request successful, nothing to return in the body
SuccessOkNoContent = 204,
// 205 Request successful, reset displayed content
SuccessOkResetContent = 205,
// 206 Request successful, partial content returned
SuccessOkPartialContent = 206,
/// <summary>
/// 101 Server understands request, proposes to switch to different application level protocol
/// </summary>
InfoSwitchingProtocols = 101,
// 3xx Redirect code: user agent needs to go somewhere else
// 300 Redirect: different presentation forms available, take
// a pick
RedirectMultipleChoices = 300,
// 301 Redirect: requested resource has moved and now lives
// somewhere else
RedirectMovedPermanently = 301,
// 302 Redirect: Resource temporarily somewhere else, location
// might change
RedirectFound = 302,
// 303 Redirect: See other as result of a POST
RedirectSeeOther = 303,
// 304 Redirect: Resource still the same as before
RedirectNotModified = 304,
// 305 Redirect: Resource must be accessed via proxy provided
// in location field
RedirectUseProxy = 305,
// 307 Redirect: Resource temporarily somewhere else, location
// might change
RedirectMovedTemporarily = 307,
#endregion
// 4xx Client error: the client borked the request
// 400 Client error: bad request, server does not grok what
// the client wants
ClientErrorBadRequest = 400,
// 401 Client error: the client is not authorized, response
// provides WWW-Authenticate header field with a challenge
ClientErrorUnauthorized = 401,
// 402 Client error: Payment required (reserved for future use)
ClientErrorPaymentRequired = 402,
// 403 Client error: Server understood request, will not
// deliver, do not try again.
ClientErrorForbidden = 403,
// 404 Client error: Server cannot find anything matching the
// client request.
ClientErrorNotFound = 404,
// 405 Client error: The method specified by the client in the
// request is not allowed for the resource requested
ClientErrorMethodNotAllowed = 405,
// 406 Client error: Server cannot generate suitable response
// for the resource and content characteristics requested by
// the client
ClientErrorNotAcceptable = 406,
// 407 Client error: Similar to 401, Server requests that
// client authenticate itself with the proxy first
ClientErrorProxyAuthRequired = 407,
// 408 Client error: Server got impatient with client and
// decided to give up waiting for the client's request to
// arrive
ClientErrorRequestTimeout = 408,
// 409 Client error: Server could not fulfill the request for
// a resource as there is a conflict with the current state of
// the resource but thinks client can do something about this
ClientErrorConflict = 409,
// 410 Client error: The resource has moved somewhere else,
// but server has no clue where.
ClientErrorGone = 410,
// 411 Client error: The server is picky again and insists on
// having a content-length header field in the request
ClientErrorLengthRequired = 411,
// 412 Client error: one or more preconditions supplied in the
// client's request is false
ClientErrorPreconditionFailed = 412,
// 413 Client error: For fear of reflux, the server refuses to
// swallow that much data.
ClientErrorRequestEntityToLarge = 413,
// 414 Client error: The server considers the Request-URI to
// be indecently long and refuses to even look at it.
ClientErrorRequestURITooLong = 414,
// 415 Client error: The server has no clue about the media
// type requested by the client (contrary to popular belief it
// is not a warez server)
ClientErrorUnsupportedMediaType = 415,
// 416 Client error: The requested range cannot be delivered
// by the server.
#region 2xx Success codes
/// <summary>
/// 200 Request successful
/// </summary>
SuccessOk = 200,
/// <summary>
/// 201 Request successful, new resource created
/// </summary>
SuccessOkCreated = 201,
/// <summary>
/// 202 Request accepted, processing still on-going
/// </summary>
SuccessOkAccepted = 202,
/// <summary>
/// 203 Request successful, meta information not authoritative
/// </summary>
SuccessOkNonAuthoritativeInformation = 203,
/// <summary>
/// 204 Request successful, nothing to return in the body
/// </summary>
SuccessOkNoContent = 204,
/// <summary>
/// 205 Request successful, reset displayed content
/// </summary>
SuccessOkResetContent = 205,
/// <summary>
/// 206 Request successful, partial content returned
/// </summary>
SuccessOkPartialContent = 206,
#endregion
#region 3xx Redirect code: user agent needs to go somewhere else
/// <summary>
/// 300 Redirect: different presentation forms available, take a pick
/// </summary>
RedirectMultipleChoices = 300,
/// <summary>
/// 301 Redirect: requested resource has moved and now lives somewhere else
/// </summary>
RedirectMovedPermanently = 301,
/// <summary>
/// 302 Redirect: Resource temporarily somewhere else, location might change
/// </summary>
RedirectFound = 302,
/// <summary>
/// 303 Redirect: See other as result of a POST
/// </summary>
RedirectSeeOther = 303,
/// <summary>
/// 304 Redirect: Resource still the same as before
/// </summary>
RedirectNotModified = 304,
/// <summary>
/// 305 Redirect: Resource must be accessed via proxy provided in location field
/// </summary>
RedirectUseProxy = 305,
/// <summary>
/// 307 Redirect: Resource temporarily somewhere else, location might change
/// </summary>
RedirectMovedTemporarily = 307,
#endregion
#region 4xx Client error: the client borked the request
/// <summary>
/// 400 Client error: bad request, server does not grok what the client wants
/// </summary>
ClientErrorBadRequest = 400,
/// <summary>
/// 401 Client error: the client is not authorized, response provides WWW-Authenticate header field with a challenge
/// </summary>
ClientErrorUnauthorized = 401,
/// <summary>
/// 402 Client error: Payment required (reserved for future use)
/// </summary>
ClientErrorPaymentRequired = 402,
/// <summary>
/// 403 Client error: Server understood request, will not deliver, do not try again.
ClientErrorForbidden = 403,
/// <summary>
/// 404 Client error: Server cannot find anything matching the client request.
/// </summary>
ClientErrorNotFound = 404,
/// <summary>
/// 405 Client error: The method specified by the client in the request is not allowed for the resource requested
/// </summary>
ClientErrorMethodNotAllowed = 405,
/// <summary>
/// 406 Client error: Server cannot generate suitable response for the resource and content characteristics requested by the client
/// </summary>
ClientErrorNotAcceptable = 406,
/// <summary>
/// 407 Client error: Similar to 401, Server requests that client authenticate itself with the proxy first
/// </summary>
ClientErrorProxyAuthRequired = 407,
/// <summary>
/// 408 Client error: Server got impatient with client and decided to give up waiting for the client's request to arrive
/// </summary>
ClientErrorRequestTimeout = 408,
/// <summary>
/// 409 Client error: Server could not fulfill the request for a resource as there is a conflict with the current state of the resource but thinks client can do something about this
/// </summary>
ClientErrorConflict = 409,
/// <summary>
/// 410 Client error: The resource has moved somewhere else, but server has no clue where.
/// </summary>
ClientErrorGone = 410,
/// <summary>
/// 411 Client error: The server is picky again and insists on having a content-length header field in the request
/// </summary>
ClientErrorLengthRequired = 411,
/// <summary>
/// 412 Client error: one or more preconditions supplied in the client's request is false
/// </summary>
ClientErrorPreconditionFailed = 412,
/// <summary>
/// 413 Client error: For fear of reflux, the server refuses to swallow that much data.
/// </summary>
ClientErrorRequestEntityToLarge = 413,
/// <summary>
/// 414 Client error: The server considers the Request-URI to be indecently long and refuses to even look at it.
/// </summary>
ClientErrorRequestURITooLong = 414,
/// <summary>
/// 415 Client error: The server has no clue about the media type requested by the client (contrary to popular belief it is not a warez server)
/// </summary>
ClientErrorUnsupportedMediaType = 415,
/// <summary>
/// 416 Client error: The requested range cannot be delivered by the server.
/// </summary>
ClientErrorRequestRangeNotSatisfiable = 416,
// 417 Client error: The expectations of the client as
// expressed in one or more Expect header fields cannot be met
// by the server, the server is awfully sorry about this.
ClientErrorExpectationFailed = 417,
// 499 Client error: Wildcard error.
ClientErrorJoker = 499,
// 5xx Server errors (rare)
// 500 Server error: something really strange and unexpected
// happened
ServerErrorInternalError = 500,
// 501 Server error: The server does not do the functionality
// required to carry out the client request. not at
// all. certainly not before breakfast. but also not after
// breakfast.
ServerErrorNotImplemented = 501,
// 502 Server error: While acting as a proxy or a gateway, the
// server got ditched by the upstream server and as a
// consequence regretfully cannot fulfill the client's request
ServerErrorBadGateway = 502,
// 503 Server error: Due to unforseen circumstances the server
// cannot currently deliver the service requested. Retry-After
// header might indicate when to try again.
ServerErrorServiceUnavailable = 503,
// 504 Server error: The server blames the upstream server
// for not being able to deliver the service requested and
// claims that the upstream server is too slow delivering the
// goods.
ServerErrorGatewayTimeout = 504,
// 505 Server error: The server does not support the HTTP
// version conveyed in the client's request.
ServerErrorHttpVersionNotSupported = 505,
/// <summary>
/// 417 Client error: The expectations of the client as expressed in one or more Expect header fields cannot be met by the server, the server is awfully sorry about this.
/// </summary>
ClientErrorExpectationFailed = 417,
/// <summary>
/// 428 Client error :The 428 status code indicates that the origin server requires the request to be conditional.
/// </summary>
ClientErrorPreconditionRequired = 428,
/// <summary>
/// 429 Client error: The 429 status code indicates that the user has sent too many requests in a given amount of time ("rate limiting").
/// </summary>
ClientErrorTooManyRequests = 429,
/// <summary>
/// 431 Client error: The 431 status code indicates that the server is unwilling to process the request because its header fields are too large. The request MAY be resubmitted after reducing the size of the request header fields.
/// </summary>
ClientErrorRequestHeaderFieldsTooLarge = 431,
/// <summary>
/// 499 Client error: Wildcard error.
/// </summary>
ClientErrorJoker = 499,
#endregion
#region 5xx Server errors (rare)
/// <summary>
/// 500 Server error: something really strange and unexpected happened
/// </summary>
ServerErrorInternalError = 500,
/// <summary>
/// 501 Server error: The server does not do the functionality required to carry out the client request. not at all. certainly not before breakfast. but also not after breakfast.
/// </summary>
ServerErrorNotImplemented = 501,
/// <summary>
/// 502 Server error: While acting as a proxy or a gateway, the server got ditched by the upstream server and as a consequence regretfully cannot fulfill the client's request
/// </summary>
ServerErrorBadGateway = 502,
/// <summary>
/// 503 Server error: Due to unforseen circumstances the server cannot currently deliver the service requested. Retry-After header might indicate when to try again.
/// </summary>
ServerErrorServiceUnavailable = 503,
/// <summary>
/// 504 Server error: The server blames the upstream server for not being able to deliver the service requested and claims that the upstream server is too slow delivering the goods.
/// </summary>
ServerErrorGatewayTimeout = 504,
/// <summary>
/// 505 Server error: The server does not support the HTTP version conveyed in the client's request.
/// </summary>
ServerErrorHttpVersionNotSupported = 505,
/// <summary>
/// 511 Server error: The 511 status code indicates that the client needs to authenticate to gain network access.
/// </summary>
ServerErrorNetworkAuthenticationRequired = 511,
#endregion
}
}

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

@@ -66,6 +66,7 @@ namespace OpenSim.Framework.Servers.HttpServer
ThreadPriority.Normal,
false,
true,
null,
int.MaxValue);
}
@@ -75,6 +76,7 @@ namespace OpenSim.Framework.Servers.HttpServer
ThreadPriority.Normal,
false,
true,
null,
1000 * 60 * 10);
}
@@ -138,9 +140,8 @@ namespace OpenSim.Framework.Servers.HttpServer
foreach (object o in m_requests)
{
PollServiceHttpRequest req = (PollServiceHttpRequest) o;
m_server.DoHTTPGruntWork(
req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id),
new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext));
PollServiceWorkerThread.DoHTTPGruntWork(
m_server, req, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
}
m_requests.Clear();
@@ -149,6 +150,7 @@ namespace OpenSim.Framework.Servers.HttpServer
{
t.Abort();
}
m_running = false;
}
}

View File

@@ -90,15 +90,16 @@ namespace OpenSim.Framework.Servers.HttpServer
}
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd());
m_server.DoHTTPGruntWork(responsedata,
new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request),req.HttpContext));
DoHTTPGruntWork(m_server, req, responsedata);
}
else
{
if ((Environment.TickCount - req.RequestTime) > m_timeout)
{
m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id),
new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request),req.HttpContext));
DoHTTPGruntWork(
m_server,
req,
req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
}
else
{
@@ -119,5 +120,45 @@ namespace OpenSim.Framework.Servers.HttpServer
{
m_request.Enqueue(pPollServiceHttpRequest);
}
/// <summary>
/// FIXME: This should be part of BaseHttpServer
/// </summary>
internal static void DoHTTPGruntWork(BaseHttpServer server, PollServiceHttpRequest req, Hashtable responsedata)
{
OSHttpResponse response
= new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext);
byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
response.SendChunked = false;
response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8;
try
{
response.OutputStream.Write(buffer, 0, buffer.Length);
}
catch (Exception ex)
{
m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex));
}
finally
{
//response.OutputStream.Close();
try
{
response.OutputStream.Flush();
response.Send();
//if (!response.KeepAlive && response.ReuseContext)
// response.FreeContext();
}
catch (Exception e)
{
m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e));
}
}
}
}
}
}

View File

@@ -39,7 +39,11 @@ namespace OpenSim.Framework.Servers.HttpServer
private RestDeserialiseMethod<TRequest, TResponse> m_method;
public RestDeserialiseHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method)
: base(httpMethod, path)
: this(httpMethod, path, method, null, null) {}
public RestDeserialiseHandler(
string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method, string name, string description)
: base(httpMethod, path, name, description)
{
m_method = method;
}

View File

@@ -38,19 +38,25 @@ namespace OpenSim.Framework.Servers.HttpServer
get { return m_dhttpMethod; }
}
public override Hashtable Handle(string path, Hashtable request)
{
string param = GetParam(path);
request.Add("param", param);
request.Add("path", path);
return m_dhttpMethod(request);
}
public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod)
: base(httpMethod, path)
{
m_dhttpMethod = dhttpMethod;
}
public RestHTTPHandler(
string httpMethod, string path, GenericHTTPMethod dhttpMethod, string name, string description)
: base(httpMethod, path, name, description)
{
m_dhttpMethod = dhttpMethod;
}
public override Hashtable Handle(string path, Hashtable request)
{
string param = GetParam(path);
request.Add("param", param);
request.Add("path", path);
return m_dhttpMethod(request);
}
}
}

View File

@@ -39,6 +39,15 @@ namespace OpenSim.Framework.Servers.HttpServer
get { return m_restMethod; }
}
public RestStreamHandler(string httpMethod, string path, RestMethod restMethod)
: this(httpMethod, path, restMethod, null, null) {}
public RestStreamHandler(string httpMethod, string path, RestMethod restMethod, string name, string description)
: base(httpMethod, path, name, description)
{
m_restMethod = restMethod;
}
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
Encoding encoding = Encoding.UTF8;
@@ -52,10 +61,5 @@ namespace OpenSim.Framework.Servers.HttpServer
return Encoding.UTF8.GetBytes(responseString);
}
public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) : base(httpMethod, path)
{
m_restMethod = restMethod;
}
}
}

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

@@ -34,14 +34,12 @@ namespace OpenSim.Framework.Statistics
{
private static AssetStatsCollector assetStats;
private static UserStatsCollector userStats;
private static SimExtraStatsCollector simExtraStats;
private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
public static AssetStatsCollector AssetStats { get { return assetStats; } }
public static UserStatsCollector UserStats { get { return userStats; } }
public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
private StatsManager() {}
/// <summary>
/// Start collecting statistics related to assets.
/// Should only be called once.
@@ -63,16 +61,5 @@ namespace OpenSim.Framework.Statistics
return userStats;
}
/// <summary>
/// Start collecting extra sim statistics apart from those collected for the client.
/// Should only be called once.
/// </summary>
public static SimExtraStatsCollector StartCollectingSimExtraStats()
{
simExtraStats = new SimExtraStatsCollector();
return simExtraStats;
}
}
}
}

View File

@@ -26,6 +26,8 @@
*/
using System;
using System.Reflection;
using log4net;
using OpenMetaverse;
namespace OpenSim.Framework
@@ -35,6 +37,8 @@ namespace OpenSim.Framework
/// </summary>
public class TaskInventoryItem : ICloneable
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// XXX This should really be factored out into some constants class.
/// </summary>
@@ -69,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;
@@ -331,12 +338,27 @@ namespace OpenSim.Framework
}
}
public bool OwnerChanged {
get {
public bool OwnerChanged
{
get
{
return _ownerChanged;
}
set {
set
{
_ownerChanged = value;
// m_log.DebugFormat(
// "[TASK INVENTORY ITEM]: Owner changed set {0} for {1} {2} owned by {3}",
// _ownerChanged, Name, ItemID, OwnerID);
}
}
public bool ScriptRunning {
get {
return _scriptRunning;
}
set {
_scriptRunning = value;
}
}

View File

@@ -214,16 +214,13 @@ namespace OpenSim.Framework.Tests
for (int i = 0; i < contenttypes.Length; i++)
{
if (SLUtil.ContentTypeToSLAssetType(contenttypes[i]) == 18)
{
Assert.That(contenttypes[i] == "image/tga");
}
int expected;
if (contenttypes[i] == "image/tga")
expected = 12; // if we know only the content-type "image/tga", then we assume the asset type is TextureTGA; not ImageTGA
else
{
Assert.That(SLUtil.ContentTypeToSLAssetType(contenttypes[i]) == assettypes[i],
"Expecting {0} but got {1}", assettypes[i],
SLUtil.ContentTypeToSLAssetType(contenttypes[i]));
}
expected = assettypes[i];
Assert.AreEqual(expected, SLUtil.ContentTypeToSLAssetType(contenttypes[i]),
String.Format("Incorrect AssetType mapped from Content-Type {0}", contenttypes[i]));
}
int[] inventorytypes = new int[] {-1,0,1,2,3,6,7,8,9,10,15,17,18,20};
@@ -237,7 +234,7 @@ namespace OpenSim.Framework.Tests
"application/vnd.ll.primitive",
"application/vnd.ll.notecard",
"application/vnd.ll.folder",
"application/octet-stream",
"application/vnd.ll.rootfolder",
"application/vnd.ll.lsltext",
"image/x-j2c",
"application/vnd.ll.primitive",
@@ -247,7 +244,8 @@ namespace OpenSim.Framework.Tests
for (int i=0;i<inventorytypes.Length;i++)
{
Assert.That(SLUtil.SLInvTypeToContentType(inventorytypes[i]) == invcontenttypes[i], "Expected {0}, Got {1}", invcontenttypes[i], SLUtil.SLInvTypeToContentType(inventorytypes[i]));
Assert.AreEqual(invcontenttypes[i], SLUtil.SLInvTypeToContentType(inventorytypes[i]),
String.Format("Incorrect Content-Type mapped from InventoryType {0}", inventorytypes[i]));
}
invcontenttypes = new string[]
@@ -280,7 +278,8 @@ namespace OpenSim.Framework.Tests
for (int i = 0; i < invtypes.Length; i++)
{
Assert.That(SLUtil.ContentTypeToSLInvType(invcontenttypes[i]) == invtypes[i], "Expected {0}, Got {1}", invtypes[i], SLUtil.ContentTypeToSLInvType(invcontenttypes[i]));
Assert.AreEqual(invtypes[i], SLUtil.ContentTypeToSLInvType(invcontenttypes[i]),
String.Format("Incorrect InventoryType mapped from Content-Type {0}", invcontenttypes[i]));
}
}
}

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)
@@ -1236,8 +1237,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

@@ -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>
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
@@ -58,7 +58,7 @@ namespace OpenSim.Framework
public int FirstTick { get; private set; }
/// <summary>
/// First time this heartbeat update was invoked
/// Last time this heartbeat update was invoked
/// </summary>
public int LastTick { get; set; }
@@ -77,6 +77,11 @@ namespace OpenSim.Framework
/// </summary>
public bool AlarmIfTimeout { get; set; }
/// <summary>
/// Method execute if alarm goes off. If null then no alarm method is fired.
/// </summary>
public Func<string> AlarmMethod { get; set; }
public ThreadWatchdogInfo(Thread thread, int timeout)
{
Thread = thread;
@@ -87,27 +92,33 @@ namespace OpenSim.Framework
}
/// <summary>
/// This event is called whenever a tracked thread is stopped or
/// has not called UpdateThread() in time
/// </summary>
/// <param name="thread">The thread that has been identified as dead</param>
/// <param name="lastTick">The last time this thread called UpdateThread()</param>
public delegate void WatchdogTimeout(Thread thread, int lastTick);
/// <summary>This event is called whenever a tracked thread is
/// stopped or has not called UpdateThread() in time</summary>
public static event WatchdogTimeout OnWatchdogTimeout;
/// This event is called whenever a tracked thread is
/// stopped or has not called UpdateThread() in time<
/// /summary>
public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout;
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;
// Set now so we don't get alerted on the first run
LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
m_watchdogTimer.Start();
}
@@ -123,7 +134,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, WATCHDOG_TIMEOUT_MS);
return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS);
}
/// <summary>
@@ -135,17 +146,24 @@ namespace OpenSim.Framework
/// <param name="isBackground">True to run this thread as a background
/// thread, otherwise false</param>
/// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
/// <param name="alarmMethod">
/// Alarm method to call if alarmIfTimeout is true and there is a timeout.
/// Normally, this will just return some useful debugging information.
/// </param>
/// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
/// <returns>The newly created Thread object</returns>
public static Thread StartThread(
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, int timeout)
ThreadStart start, string name, ThreadPriority priority, bool isBackground,
bool alarmIfTimeout, Func<string> alarmMethod, int timeout)
{
Thread thread = new Thread(start);
thread.Name = name;
thread.Priority = priority;
thread.IsBackground = isBackground;
ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout) { AlarmIfTimeout = alarmIfTimeout };
ThreadWatchdogInfo twi
= new ThreadWatchdogInfo(thread, timeout)
{ AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
m_log.DebugFormat(
"[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
@@ -258,7 +276,17 @@ namespace OpenSim.Framework
/// <param name="e"></param>
private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
WatchdogTimeout callback = OnWatchdogTimeout;
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)
{
@@ -266,8 +294,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)
@@ -296,7 +322,7 @@ namespace OpenSim.Framework
if (callbackInfos != null)
foreach (ThreadWatchdogInfo callbackInfo in callbackInfos)
callback(callbackInfo.Thread, callbackInfo.LastTick);
callback(callbackInfo);
}
m_watchdogTimer.Start();

View File

@@ -53,19 +53,36 @@ namespace OpenSim.Framework
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private static int m_requestNumber = 0;
/// <summary>
/// Request number for diagnostic purposes.
/// </summary>
public static int RequestNumber = 0;
// this is the header field used to communicate the local request id
// used for performance and debugging
/// <summary>
/// this is the header field used to communicate the local request id
/// used for performance and debugging
/// </summary>
public const string OSHeaderRequestID = "opensim-request-id";
// number of milliseconds a call can take before it is considered
// a "long" call for warning & debugging purposes
public const int LongCallTime = 500;
/// <summary>
/// Number of milliseconds a call can take before it is considered
/// a "long" call for warning & debugging purposes
/// </summary>
public const int LongCallTime = 3000;
// dictionary of end points
/// <summary>
/// The maximum length of any data logged because of a long request time.
/// </summary>
/// <remarks>
/// This is to truncate any really large post data, such as an asset. In theory, the first section should
/// give us useful information about the call (which agent it relates to if applicable, etc.).
/// </remarks>
public const int MaxRequestDiagLength = 100;
/// <summary>
/// Dictionary of end points
/// </summary>
private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>();
private static object EndPointLock(string url)
{
@@ -86,8 +103,7 @@ namespace OpenSim.Framework
return eplock;
}
}
#region JSONRequest
/// <summary>
@@ -129,12 +145,13 @@ namespace OpenSim.Framework
private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed)
{
int reqnum = m_requestNumber++;
int reqnum = RequestNumber++;
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
string errorMessage = "unknown error";
int tickstart = Util.EnvironmentTickCount();
int tickdata = 0;
string strBuffer = null;
try
{
@@ -149,7 +166,7 @@ namespace OpenSim.Framework
// If there is some input, write it into the request
if (data != null)
{
string strBuffer = OSDParser.SerializeJsonString(data);
strBuffer = OSDParser.SerializeJsonString(data);
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer);
if (compressed)
@@ -209,14 +226,23 @@ namespace OpenSim.Framework
}
finally
{
// This just dumps a warning for any operation that takes more than 100 ms
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > LongCallTime)
m_log.DebugFormat("[WEB UTIL]: osd request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing",
reqnum,url,method,tickdiff,tickdata);
m_log.InfoFormat(
"[OSD REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
reqnum,
method,
url,
tickdiff,
tickdata,
strBuffer != null
? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer)
: "");
}
m_log.DebugFormat("[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage);
m_log.DebugFormat(
"[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage);
return ErrorResponseMap(errorMessage);
}
@@ -289,17 +315,17 @@ namespace OpenSim.Framework
private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout)
{
int reqnum = m_requestNumber++;
int reqnum = RequestNumber++;
string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown";
// m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method);
string errorMessage = "unknown error";
int tickstart = Util.EnvironmentTickCount();
int tickdata = 0;
string queryString = null;
try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.Timeout = timeout;
@@ -310,7 +336,7 @@ namespace OpenSim.Framework
if (data != null)
{
string queryString = BuildQueryString(data);
queryString = BuildQueryString(data);
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString);
request.ContentLength = buffer.Length;
@@ -353,11 +379,20 @@ namespace OpenSim.Framework
{
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > LongCallTime)
m_log.InfoFormat("[WEB UTIL]: form request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing",
reqnum,url,method,tickdiff,tickdata);
m_log.InfoFormat(
"[SERVICE FORM]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
reqnum,
method,
url,
tickdiff,
tickdata,
queryString != null
? (queryString.Length > MaxRequestDiagLength) ? queryString.Remove(MaxRequestDiagLength) : queryString
: "");
}
m_log.WarnFormat("[WEB UTIL]: <{0}> form request failed: {1}",reqnum,errorMessage);
m_log.WarnFormat("[SERVICE FORM]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage);
return ErrorResponseMap(errorMessage);
}
@@ -637,8 +672,6 @@ namespace OpenSim.Framework
return new string[0];
}
}
public static class AsynchronousRestObjectRequester
@@ -661,6 +694,12 @@ namespace OpenSim.Framework
public static void MakeRequest<TRequest, TResponse>(string verb,
string requestUrl, TRequest obj, Action<TResponse> action)
{
int reqnum = WebUtil.RequestNumber++;
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
int tickstart = Util.EnvironmentTickCount();
int tickdata = 0;
// m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl);
Type type = typeof(TRequest);
@@ -671,12 +710,13 @@ namespace OpenSim.Framework
XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
request.Method = verb;
MemoryStream buffer = null;
if (verb == "POST")
{
request.ContentType = "text/xml";
MemoryStream buffer = new MemoryStream();
buffer = new MemoryStream();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
@@ -698,6 +738,9 @@ namespace OpenSim.Framework
requestStream.Write(buffer.ToArray(), 0, length);
requestStream.Close();
// capture how much time was spent writing
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
request.BeginGetResponse(delegate(IAsyncResult ar)
{
response = request.EndGetResponse(ar);
@@ -723,83 +766,108 @@ namespace OpenSim.Framework
}, null);
}, null);
return;
}
request.BeginGetResponse(delegate(IAsyncResult res2)
else
{
try
request.BeginGetResponse(delegate(IAsyncResult res2)
{
// If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't
// documented in MSDN
response = request.EndGetResponse(res2);
Stream respStream = null;
try
{
respStream = response.GetResponseStream();
deserial = (TResponse)deserializer.Deserialize(respStream);
}
catch (System.InvalidOperationException)
{
}
finally
{
respStream.Close();
response.Close();
}
}
catch (WebException e)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
if (e.Response is HttpWebResponse)
// If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't
// documented in MSDN
response = request.EndGetResponse(res2);
Stream respStream = null;
try
{
HttpWebResponse httpResponse = (HttpWebResponse)e.Response;
if (httpResponse.StatusCode != HttpStatusCode.NotFound)
{
// We don't appear to be handling any other status codes, so log these feailures to that
// people don't spend unnecessary hours hunting phantom bugs.
m_log.DebugFormat(
"[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}",
verb, requestUrl, httpResponse.StatusCode);
}
respStream = response.GetResponseStream();
deserial = (TResponse)deserializer.Deserialize(respStream);
}
catch (System.InvalidOperationException)
{
}
finally
{
respStream.Close();
response.Close();
}
}
else
catch (WebException e)
{
m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", verb, requestUrl, e.Status, e.Message);
if (e.Status == WebExceptionStatus.ProtocolError)
{
if (e.Response is HttpWebResponse)
{
HttpWebResponse httpResponse = (HttpWebResponse)e.Response;
if (httpResponse.StatusCode != HttpStatusCode.NotFound)
{
// We don't appear to be handling any other status codes, so log these feailures to that
// people don't spend unnecessary hours hunting phantom bugs.
m_log.DebugFormat(
"[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}",
verb, requestUrl, httpResponse.StatusCode);
}
}
}
else
{
m_log.ErrorFormat(
"[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}",
verb, requestUrl, e.Status, e.Message);
}
}
}
catch (Exception e)
catch (Exception e)
{
m_log.ErrorFormat(
"[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}",
verb, requestUrl, e.Message, e.StackTrace);
}
// m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString());
try
{
action(deserial);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}",
verb, requestUrl, e.Message, e.StackTrace);
}
}, null);
}
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > WebUtil.LongCallTime)
{
string originalRequest = null;
if (buffer != null)
{
m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with exception {2}", verb, requestUrl, e);
originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
}
// m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString());
try
{
action(deserial);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}", verb, requestUrl, e);
}
}, null);
m_log.InfoFormat(
"[ASYNC REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
reqnum,
verb,
requestUrl,
tickdiff,
tickdata,
originalRequest);
}
}
}
public static class SynchronousRestFormsRequester
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Perform a synchronous REST request.
@@ -813,6 +881,12 @@ namespace OpenSim.Framework
/// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
public static string MakeRequest(string verb, string requestUrl, string obj)
{
int reqnum = WebUtil.RequestNumber++;
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
int tickstart = Util.EnvironmentTickCount();
int tickdata = 0;
WebRequest request = WebRequest.Create(requestUrl);
request.Method = verb;
string respstring = String.Empty;
@@ -841,12 +915,16 @@ namespace OpenSim.Framework
}
catch (Exception e)
{
m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: " + e.ToString(), requestUrl);
m_log.DebugFormat(
"[FORMS]: exception occured {0} {1}: {2}{3}", verb, requestUrl, e.Message, e.StackTrace);
}
finally
{
if (requestStream != null)
requestStream.Close();
// capture how much time was spent writing
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
}
}
@@ -867,7 +945,9 @@ namespace OpenSim.Framework
}
catch (Exception e)
{
m_log.DebugFormat("[FORMS]: exception occured on receiving reply " + e.ToString());
m_log.DebugFormat(
"[FORMS]: Exception occured on receiving {0} {1}: {2}{3}",
verb, requestUrl, e.Message, e.StackTrace);
}
finally
{
@@ -880,9 +960,21 @@ namespace OpenSim.Framework
catch (System.InvalidOperationException)
{
// This is what happens when there is invalid XML
m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving request");
m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving {0} {1}", verb, requestUrl);
}
}
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > WebUtil.LongCallTime)
m_log.InfoFormat(
"[FORMS]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
reqnum,
verb,
requestUrl,
tickdiff,
tickdata,
obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj);
return respstring;
}
}
@@ -905,17 +997,24 @@ namespace OpenSim.Framework
/// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj)
{
int reqnum = WebUtil.RequestNumber++;
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
int tickstart = Util.EnvironmentTickCount();
int tickdata = 0;
Type type = typeof(TRequest);
TResponse deserial = default(TResponse);
WebRequest request = WebRequest.Create(requestUrl);
request.Method = verb;
MemoryStream buffer = null;
if ((verb == "POST") || (verb == "PUT"))
{
request.ContentType = "text/xml";
MemoryStream buffer = new MemoryStream();
buffer = new MemoryStream();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
@@ -938,13 +1037,19 @@ namespace OpenSim.Framework
}
catch (Exception e)
{
m_log.DebugFormat("[SynchronousRestObjectRequester]: exception in sending data to {0}: {1}", requestUrl, e);
m_log.DebugFormat(
"[SynchronousRestObjectRequester]: Exception in making request {0} {1}: {2}{3}",
verb, requestUrl, e.Message, e.StackTrace);
return deserial;
}
finally
{
if (requestStream != null)
requestStream.Close();
// capture how much time was spent writing
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
}
}
@@ -960,7 +1065,11 @@ namespace OpenSim.Framework
respStream.Close();
}
else
m_log.DebugFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb);
{
m_log.DebugFormat(
"[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}",
verb, requestUrl);
}
}
}
catch (WebException e)
@@ -971,20 +1080,47 @@ namespace OpenSim.Framework
return deserial;
else
m_log.ErrorFormat(
"[SynchronousRestObjectRequester]: WebException {0} {1} {2} {3}",
requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace);
"[SynchronousRestObjectRequester]: WebException for {0} {1} {2}: {3} {4}",
verb, requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace);
}
catch (System.InvalidOperationException)
{
// This is what happens when there is invalid XML
m_log.DebugFormat("[SynchronousRestObjectRequester]: Invalid XML {0} {1}", requestUrl, typeof(TResponse).ToString());
m_log.DebugFormat(
"[SynchronousRestObjectRequester]: Invalid XML from {0} {1} {2}",
verb, requestUrl, typeof(TResponse).ToString());
}
catch (Exception e)
{
m_log.DebugFormat("[SynchronousRestObjectRequester]: Exception on response from {0} {1}", requestUrl, e);
m_log.DebugFormat(
"[SynchronousRestObjectRequester]: Exception on response from {0} {1}: {2}{3}",
verb, requestUrl, e.Message, e.StackTrace);
}
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > WebUtil.LongCallTime)
{
string originalRequest = null;
if (buffer != null)
{
originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
}
m_log.InfoFormat(
"[SynchronousRestObjectRequester]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
reqnum,
verb,
requestUrl,
tickdiff,
tickdata,
originalRequest);
}
return deserial;
}
}
}
}

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

@@ -28,6 +28,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
@@ -69,6 +70,7 @@ namespace OpenSim
private Regex m_consolePromptRegex = new Regex(@"([^\\])\\(\w)", RegexOptions.Compiled);
private string m_timedScript = "disabled";
private int m_timeInterval = 1200;
private Timer m_scriptTimer;
public OpenSim(IConfigSource configSource) : base(configSource)
@@ -98,6 +100,10 @@ namespace OpenSim
m_consolePort = (uint)networkConfig.GetInt("console_port", 0);
m_timedScript = startupConfig.GetString("timer_Script", "disabled");
if (m_timedScript != "disabled")
{
m_timeInterval = startupConfig.GetInt("timer_Interval", 1200);
}
if (m_logFileAppender != null)
{
@@ -138,7 +144,7 @@ namespace OpenSim
m_log.Info("====================================================================");
m_log.Info("========================= STARTING OPENSIM =========================");
m_log.Info("====================================================================");
//m_log.InfoFormat("[OPENSIM MAIN]: GC Is Server GC: {0}", GCSettings.IsServerGC.ToString());
// http://msdn.microsoft.com/en-us/library/bb384202.aspx
//GCSettings.LatencyMode = GCLatencyMode.Batch;
@@ -215,7 +221,7 @@ namespace OpenSim
{
m_scriptTimer = new Timer();
m_scriptTimer.Enabled = true;
m_scriptTimer.Interval = 1200*1000;
m_scriptTimer.Interval = m_timeInterval*1000;
m_scriptTimer.Elapsed += RunAutoTimerScript;
}
}
@@ -225,12 +231,14 @@ namespace OpenSim
/// </summary>
private void RegisterConsoleCommands()
{
m_console.Commands.AddCommand("Regions", false, "force update",
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"
@@ -242,17 +250,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);
@@ -306,7 +306,7 @@ namespace OpenSim
+ " If this is not given then the oar is saved to region.oar in the current directory.",
SaveOar);
m_console.Commands.AddCommand("Regions", false, "edit scale",
m_console.Commands.AddCommand("Objects", false, "edit scale",
"edit scale <name> <x> <y> <z>",
"Change the scale of a named prim", HandleEditScale);
@@ -349,7 +349,7 @@ namespace OpenSim
"show ratings",
"Show rating data", HandleShow);
m_console.Commands.AddCommand("Regions", false, "backup",
m_console.Commands.AddCommand("Objects", false, "backup",
"backup",
"Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand);
@@ -409,10 +409,6 @@ namespace OpenSim
m_console.Commands.AddCommand("General", false, "modules unload",
"modules unload <name>",
"Unload a module", HandleModules);
m_console.Commands.AddCommand("Regions", false, "kill uuid",
"kill uuid <UUID>",
"Kill an object by UUID", KillUUID);
}
public override void ShutdownSpecific()
@@ -437,12 +433,16 @@ namespace OpenSim
}
}
private void WatchdogTimeoutHandler(System.Threading.Thread thread, int lastTick)
private void WatchdogTimeoutHandler(Watchdog.ThreadWatchdogInfo twi)
{
int now = Environment.TickCount & Int32.MaxValue;
m_log.ErrorFormat("[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago",
thread.Name, thread.ThreadState, now - lastTick);
m_log.ErrorFormat(
"[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago. {3}",
twi.Thread.Name,
twi.Thread.ThreadState,
now - twi.LastTick,
twi.AlarmMethod != null ? string.Format("Data: {0}", twi.AlarmMethod()) : "");
}
#region Console Commands
@@ -481,10 +481,10 @@ namespace OpenSim
else
presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n");
// ...and close on our side
presence.Scene.IncomingCloseAgent(presence.UUID);
}
}
MainConsole.Instance.Output("");
}
@@ -618,10 +618,11 @@ namespace OpenSim
return;
}
PopulateRegionEstateInfo(regInfo);
bool changed = PopulateRegionEstateInfo(regInfo);
IScene scene;
CreateRegion(regInfo, true, out scene);
regInfo.EstateSettings.Save();
if (changed)
regInfo.EstateSettings.Save();
}
/// <summary>
@@ -903,21 +904,6 @@ 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)
{
@@ -969,8 +955,7 @@ namespace OpenSim
if (showParams.Length > 1 && showParams[1] == "full")
{
agents = m_sceneManager.GetCurrentScenePresences();
}
else
} else
{
agents = m_sceneManager.GetCurrentSceneAvatars();
}
@@ -979,7 +964,8 @@ namespace OpenSim
MainConsole.Instance.Output(
String.Format("{0,-16} {1,-16} {2,-37} {3,-11} {4,-16} {5,-30}", "Firstname", "Lastname",
"Agent ID", "Root/Child", "Region", "Position"));
"Agent ID", "Root/Child", "Region", "Position")
);
foreach (ScenePresence presence in agents)
{
@@ -989,8 +975,7 @@ namespace OpenSim
if (regionInfo == null)
{
regionName = "Unresolvable";
}
else
} else
{
regionName = regionInfo.RegionName;
}
@@ -1003,43 +988,19 @@ namespace OpenSim
presence.UUID,
presence.IsChildAgent ? "Child" : "Root",
regionName,
presence.AbsolutePosition.ToString()));
presence.AbsolutePosition.ToString())
);
}
MainConsole.Instance.Output(String.Empty);
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":
@@ -1077,17 +1038,29 @@ namespace OpenSim
}
m_sceneManager.ForEachScene(
delegate(Scene scene)
delegate(Scene scene) {
m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:");
foreach (IRegionModule module in scene.Modules.Values)
{
m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:");
foreach (IRegionModule module in scene.Modules.Values)
if (!module.IsSharedModule)
{
if (!module.IsSharedModule)
{
m_log.Error("Region Module: " + module.Name);
}
m_log.Error("Region Module: " + module.Name);
}
});
}
}
);
m_sceneManager.ForEachScene(
delegate(Scene scene) {
MainConsole.Instance.Output("Loaded new region modules in" + scene.RegionInfo.RegionName + " are:");
foreach (IRegionModuleBase module in scene.RegionModules.Values)
{
Type type = module.GetType().GetInterface("ISharedRegionModule");
string module_type = type != null ? "Shared" : "Non-Shared";
MainConsole.Instance.OutputFormat("New Region Module ({0}): {1}", module_type, module.Name);
}
}
);
MainConsole.Instance.Output("");
break;
@@ -1132,6 +1105,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);
m_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);
m_sceneManager.ForEachScene(
s => s.ForEachClient(
c => cdt.AddRow(
s.Name,
c.Name,
c.RemoteEndPoint.ToString(),
c.CircuitCode.ToString(),
c.IsActive.ToString())));
MainConsole.Instance.Output(cdt.ToString());
}
/// <summary>
/// Use XML2 format to serialize data to a file
/// </summary>
@@ -1299,58 +1319,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

@@ -223,7 +223,7 @@ namespace OpenSim
base.StartupSpecific();
m_stats = StatsManager.StartCollectingSimExtraStats();
m_stats = StatsManager.SimExtraStats;
// Create a ModuleLoader instance
m_moduleLoader = new ModuleLoader(m_config.Source);
@@ -388,7 +388,7 @@ namespace OpenSim
scene.LoadPrimsFromStorage(regionInfo.originRegionID);
// TODO : Try setting resource for region xstats here on scene
MainServer.Instance.AddStreamHandler(new Region.Framework.Scenes.RegionStatsHandler(regionInfo));
MainServer.Instance.AddStreamHandler(new RegionStatsHandler(regionInfo));
scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
scene.EventManager.TriggerParcelPrimCountUpdate();
@@ -773,6 +773,9 @@ namespace OpenSim
return Util.UTF8.GetBytes("OK");
}
public string Name { get { return "SimStatus"; } }
public string Description { get { return "Simulator Status"; } }
public string ContentType
{
get { return "text/plain"; }
@@ -797,6 +800,9 @@ namespace OpenSim
{
OpenSimBase m_opensim;
string osXStatsURI = String.Empty;
public string Name { get { return "XSimStatus"; } }
public string Description { get { return "Simulator XStatus"; } }
public XSimStatusHandler(OpenSimBase sim)
{
@@ -837,6 +843,9 @@ namespace OpenSim
{
OpenSimBase m_opensim;
string osUXStatsURI = String.Empty;
public string Name { get { return "UXSimStatus"; } }
public string Description { get { return "Simulator UXStatus"; } }
public UXSimStatusHandler(OpenSimBase sim)
{
@@ -968,13 +977,13 @@ namespace OpenSim
/// Load the estate information for the provided RegionInfo object.
/// </summary>
/// <param name="regInfo"></param>
public void PopulateRegionEstateInfo(RegionInfo regInfo)
public bool PopulateRegionEstateInfo(RegionInfo regInfo)
{
if (EstateDataService != null)
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false);
if (regInfo.EstateSettings.EstateID != 0)
return;
return false; // estate info in the database did not change
m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
@@ -1009,7 +1018,7 @@ namespace OpenSim
}
if (defaultEstateJoined)
return;
return true; // need to update the database
else
m_log.ErrorFormat(
"[OPENSIM BASE]: Joining default estate {0} failed", defaultEstateName);
@@ -1071,8 +1080,10 @@ namespace OpenSim
MainConsole.Instance.Output("Joining the estate failed. Please try again.");
}
}
}
}
}
return true; // need to update the database
}
}
public class OpenSimConfigSource

View File

@@ -155,7 +155,9 @@ namespace OpenSim.Region.ClientStack.Linden
try
{
// the root of all evil
m_HostCapsObj.RegisterHandler("SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest));
m_HostCapsObj.RegisterHandler(
"SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null));
m_log.DebugFormat(
"[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
@@ -163,7 +165,10 @@ namespace OpenSim.Region.ClientStack.Linden
// new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
// capsBase + m_mapLayerPath,
// GetMapLayer);
IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory);
IRequestHandler req
= new RestStreamHandler(
"POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory, "UpdateScript", null);
m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
}
@@ -178,14 +183,27 @@ namespace OpenSim.Region.ClientStack.Linden
try
{
// I don't think this one works...
m_HostCapsObj.RegisterHandler("NewFileAgentInventory", new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST",
capsBase + m_newInventory,
NewAgentInventoryRequest));
IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory);
m_HostCapsObj.RegisterHandler(
"NewFileAgentInventory",
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>(
"POST",
capsBase + m_newInventory,
NewAgentInventoryRequest,
"NewFileAgentInventory",
null));
IRequestHandler req
= new RestStreamHandler(
"POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory, "Update*", null);
m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
m_HostCapsObj.RegisterHandler("CopyInventoryFromNotecard", new RestStreamHandler("POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard));
m_HostCapsObj.RegisterHandler(
"CopyInventoryFromNotecard",
new RestStreamHandler(
"POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard, "CopyInventoryFromNotecard", null));
// As of RC 1.22.9 of the Linden client this is
// supported
@@ -235,7 +253,10 @@ namespace OpenSim.Region.ClientStack.Linden
if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
{
m_log.DebugFormat("[CAPS]: Unauthorized CAPS client");
m_log.DebugFormat(
"[CAPS]: Unauthorized CAPS client {0} from {1}",
m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint);
return string.Empty;
}
@@ -286,7 +307,9 @@ namespace OpenSim.Region.ClientStack.Linden
m_dumpAssetsToFile);
uploader.OnUpLoad += TaskScriptUpdated;
m_HostCapsObj.HttpListener.AddStreamHandler(new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
m_HostCapsObj.HttpListener.AddStreamHandler(
new BinaryStreamHandler(
"POST", capsBase + uploaderPath, uploader.uploaderCaps, "TaskInventoryScriptUpdater", null));
string protocol = "http://";
@@ -413,8 +436,14 @@ namespace OpenSim.Region.ClientStack.Linden
AssetUploader uploader =
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
m_HostCapsObj.HttpListener.AddStreamHandler(
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
new BinaryStreamHandler(
"POST",
capsBase + uploaderPath,
uploader.uploaderCaps,
"NewAgentInventoryRequest",
m_HostCapsObj.AgentID.ToString()));
string protocol = "http://";
@@ -730,7 +759,8 @@ namespace OpenSim.Region.ClientStack.Linden
uploader.OnUpLoad += ItemUpdated;
m_HostCapsObj.HttpListener.AddStreamHandler(
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
new BinaryStreamHandler(
"POST", capsBase + uploaderPath, uploader.uploaderCaps, "NoteCardAgentInventory", null));
string protocol = "http://";

View File

@@ -106,13 +106,14 @@ namespace OpenSim.Region.ClientStack.Linden
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
MainConsole.Instance.Commands.AddCommand(
"Comms",
"Debug",
false,
"debug eq",
"debug eq [0|1]",
"Turn on event queue debugging",
"debug eq 1 will turn on event queue debugging. This will log all outgoing event queue messages to clients.\n"
+ "debug eq 0 will turn off event queue debugging.",
"debug eq [0|1|2]",
"Turn on event queue debugging"
+ "<= 0 - turns off all event queue logging"
+ ">= 1 - turns on outgoing event logging"
+ ">= 2 - turns on poll notification",
HandleDebugEq);
}
else
@@ -235,19 +236,19 @@ namespace OpenSim.Region.ClientStack.Linden
// ClientClosed(client.AgentId);
// }
private void ClientClosed(UUID AgentID, Scene scene)
private void ClientClosed(UUID agentID, Scene scene)
{
// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName);
// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
int count = 0;
while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5)
while (queues.ContainsKey(agentID) && queues[agentID].Count > 0 && count++ < 5)
{
Thread.Sleep(1000);
}
lock (queues)
{
queues.Remove(AgentID);
queues.Remove(agentID);
}
List<UUID> removeitems = new List<UUID>();
@@ -256,7 +257,7 @@ namespace OpenSim.Region.ClientStack.Linden
foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
{
// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
if (ky == AgentID)
if (ky == agentID)
{
removeitems.Add(ky);
}
@@ -267,7 +268,12 @@ namespace OpenSim.Region.ClientStack.Linden
UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
m_AvatarQueueUUIDMapping.Remove(ky);
MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + eventQueueGetUuid.ToString() + "/");
string eqgPath = GenerateEqgCapPath(eventQueueGetUuid);
MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath);
// m_log.DebugFormat(
// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}",
// eqgPath, agentID, m_scene.RegionInfo.RegionName);
}
}
@@ -281,7 +287,7 @@ namespace OpenSim.Region.ClientStack.Linden
{
searchval = m_QueueUUIDAvatarMapping[ky];
if (searchval == AgentID)
if (searchval == agentID)
{
removeitems.Add(ky);
}
@@ -305,6 +311,15 @@ namespace OpenSim.Region.ClientStack.Linden
//}
}
/// <summary>
/// Generate an Event Queue Get handler path for the given eqg uuid.
/// </summary>
/// <param name='eqgUuid'></param>
private string GenerateEqgCapPath(UUID eqgUuid)
{
return string.Format("/CAPS/EQG/{0}/", eqgUuid);
}
public void OnRegisterCaps(UUID agentID, Caps caps)
{
// Register an event queue for the client
@@ -316,8 +331,7 @@ namespace OpenSim.Region.ClientStack.Linden
// Let's instantiate a Queue for this agent right now
TryGetQueue(agentID);
string capsBase = "/CAPS/EQG/";
UUID EventQueueGetUUID = UUID.Zero;
UUID eventQueueGetUUID;
lock (m_AvatarQueueUUIDMapping)
{
@@ -325,44 +339,50 @@ namespace OpenSim.Region.ClientStack.Linden
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
{
//m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
}
else
{
EventQueueGetUUID = UUID.Random();
eventQueueGetUUID = UUID.Random();
//m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
}
}
lock (m_QueueUUIDAvatarMapping)
{
if (!m_QueueUUIDAvatarMapping.ContainsKey(EventQueueGetUUID))
m_QueueUUIDAvatarMapping.Add(EventQueueGetUUID, agentID);
if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID))
m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID);
}
lock (m_AvatarQueueUUIDMapping)
{
if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
m_AvatarQueueUUIDMapping.Add(agentID, EventQueueGetUUID);
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
}
string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID);
// Register this as a caps handler
// FIXME: Confusingly, we need to register separate as a capability so that the client is told about
// EventQueueGet when it receive capability information, but then we replace the rest handler immediately
// afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but
// really it should be possible to directly register the poll handler as a capability.
caps.RegisterHandler("EventQueueGet",
new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString() + "/", null));
caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null));
// delegate(Hashtable m_dhttpMethod)
// {
// return ProcessQueue(m_dhttpMethod, agentID, caps);
// }));
// This will persist this beyond the expiry of the caps handlers
// TODO: Add EventQueueGet name/description for diagnostics
MainServer.Instance.AddPollServiceHTTPHandler(
capsBase + EventQueueGetUUID.ToString() + "/",
eventQueueGetPath,
new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
// m_log.DebugFormat(
// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}",
// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName);
Random rnd = new Random(Environment.TickCount);
lock (m_ids)
{
@@ -384,9 +404,25 @@ namespace OpenSim.Region.ClientStack.Linden
return false;
}
/// <summary>
/// Logs a debug line for an outbound event queue message if appropriate.
/// </summary>
/// <param name='element'>Element containing message</param>
private void LogOutboundDebugMessage(OSD element, UUID agentId)
{
if (element is OSDMap)
{
OSDMap ev = (OSDMap)element;
m_log.DebugFormat(
"Eq OUT {0,-30} to {1,-20} {2,-20}",
ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.RegionInfo.RegionName);
}
}
public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request)
{
// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Invoked GetEvents() for {0}", pAgentId);
if (DebugLevel >= 2)
m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName);
Queue<OSD> queue = TryGetQueue(pAgentId);
OSD element;
@@ -410,13 +446,8 @@ namespace OpenSim.Region.ClientStack.Linden
}
else
{
if (DebugLevel > 0 && element is OSDMap)
{
OSDMap ev = (OSDMap)element;
m_log.DebugFormat(
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
ev["message"], m_scene.GetScenePresence(pAgentId).Name);
}
if (DebugLevel > 0)
LogOutboundDebugMessage(element, pAgentId);
array.Add(element);
@@ -426,13 +457,8 @@ namespace OpenSim.Region.ClientStack.Linden
{
element = queue.Dequeue();
if (DebugLevel > 0 && element is OSDMap)
{
OSDMap ev = (OSDMap)element;
m_log.DebugFormat(
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
ev["message"], m_scene.GetScenePresence(pAgentId).Name);
}
if (DebugLevel > 0)
LogOutboundDebugMessage(element, pAgentId);
array.Add(element);
thisID++;

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");
@@ -60,7 +69,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
CapabilitiesModule capsModule = new CapabilitiesModule();
EventQueueGetModule eqgModule = new EventQueueGetModule();
m_scene = SceneHelpers.SetupScene();
m_scene = new SceneHelpers().SetupScene();
SceneHelpers.SetupSceneModules(m_scene, config, capsModule, eqgModule);
}

View File

@@ -132,7 +132,8 @@ namespace OpenSim.Region.ClientStack.Linden
capUrl = "/CAPS/" + UUID.Random();
IRequestHandler reqHandler
= new RestStreamHandler("POST", capUrl, m_fetchHandler.FetchInventoryRequest);
= new RestStreamHandler(
"POST", capUrl, m_fetchHandler.FetchInventoryRequest, capName, agentID.ToString());
caps.RegisterHandler(capName, reqHandler);
}

View File

@@ -120,11 +120,13 @@ namespace OpenSim.Region.ClientStack.Linden
{
// m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(),
delegate(Hashtable m_dhttpMethod)
{
return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null);
});
IRequestHandler reqHandler
= new RestHTTPHandler(
"GET",
"/CAPS/" + UUID.Random(),
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
"GetMesh",
agentID.ToString());
caps.RegisterHandler("GetMesh", reqHandler);
}

View File

@@ -130,7 +130,9 @@ namespace OpenSim.Region.ClientStack.Linden
if (m_URL == "localhost")
{
// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService));
caps.RegisterHandler(
"GetTexture",
new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString()));
}
else
{

View File

@@ -117,7 +117,9 @@ namespace OpenSim.Region.ClientStack.Linden
public void RegisterCaps(UUID agentID, Caps caps)
{
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag);
IRequestHandler reqHandler
= new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag, "MeshUploadFlag", agentID.ToString());
caps.RegisterHandler("MeshUploadFlag", reqHandler);
m_agentID = agentID;
}

View File

@@ -115,67 +115,66 @@ namespace OpenSim.Region.ClientStack.Linden
UUID capID = UUID.Random();
// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>("POST",
"/CAPS/" + capID.ToString(),
delegate(LLSDAssetUploadRequest req)
{
return NewAgentInventoryRequest(req,agentID);
}));
caps.RegisterHandler(
"NewFileAgentInventoryVariablePrice",
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>(
"POST",
"/CAPS/" + capID.ToString(),
req => NewAgentInventoryRequest(req, agentID),
"NewFileAgentInventoryVariablePrice",
agentID.ToString()));
}
#endregion
public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
{
//TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit
// You need to be aware of this and
// you need to be aware of this
//if (llsdRequest.asset_type == "texture" ||
// llsdRequest.asset_type == "animation" ||
// llsdRequest.asset_type == "sound")
// {
// check user level
ScenePresence avatar = null;
IClientAPI client = null;
m_scene.TryGetScenePresence(agentID, out avatar);
if (avatar != null)
ScenePresence avatar = null;
IClientAPI client = null;
m_scene.TryGetScenePresence(agentID, out avatar);
if (avatar != null)
{
client = avatar.ControllingClient;
if (avatar.UserLevel < m_levelUpload)
{
client = avatar.ControllingClient;
if (client != null)
client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
if (avatar.UserLevel < m_levelUpload)
{
if (client != null)
client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
errorResponse.rsvp = "";
errorResponse.state = "error";
return errorResponse;
}
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
errorResponse.rsvp = "";
errorResponse.state = "error";
return errorResponse;
}
}
// check funds
IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
// check funds
IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
if (mm != null)
if (mm != null)
{
if (!mm.UploadCovered(agentID, mm.UploadCharge))
{
if (!mm.UploadCovered(agentID, mm.UploadCharge))
{
if (client != null)
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
if (client != null)
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
errorResponse.rsvp = "";
errorResponse.state = "error";
return errorResponse;
}
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
errorResponse.rsvp = "";
errorResponse.state = "error";
return errorResponse;
}
}
// }
string assetName = llsdRequest.name;
@@ -189,8 +188,14 @@ namespace OpenSim.Region.ClientStack.Linden
AssetUploader uploader =
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
MainServer.Instance.AddStreamHandler(
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
new BinaryStreamHandler(
"POST",
capsBase + uploaderPath,
uploader.uploaderCaps,
"NewFileAgentInventoryVariablePrice",
agentID.ToString()));
string protocol = "http://";
@@ -199,10 +204,9 @@ namespace OpenSim.Region.ClientStack.Linden
string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase +
uploaderPath;
LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
uploadResponse.rsvp = uploaderURL;
uploadResponse.state = "upload";
@@ -220,6 +224,7 @@ namespace OpenSim.Region.ClientStack.Linden
pinventoryItem, pparentFolder, pdata, pinventoryType,
passetType,agentID);
};
return uploadResponse;
}

View File

@@ -66,12 +66,14 @@ namespace OpenSim.Region.ClientStack.Linden
// m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/");
caps.RegisterHandler("ObjectAdd",
new RestHTTPHandler("POST", "/CAPS/OA/" + capuuid + "/",
delegate(Hashtable m_dhttpMethod)
{
return ProcessAdd(m_dhttpMethod, agentID, caps);
}));
caps.RegisterHandler(
"ObjectAdd",
new RestHTTPHandler(
"POST",
"/CAPS/OA/" + capuuid + "/",
httpMethod => ProcessAdd(httpMethod, agentID, caps),
"ObjectAdd",
agentID.ToString()));;
}
public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)

View File

@@ -106,12 +106,15 @@ namespace OpenSim.Region.ClientStack.Linden
UUID capID = UUID.Random();
// m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID);
caps.RegisterHandler("UploadObjectAsset",
new RestHTTPHandler("POST", "/CAPS/OA/" + capID + "/",
delegate(Hashtable m_dhttpMethod)
{
return ProcessAdd(m_dhttpMethod, agentID, caps);
}));
caps.RegisterHandler(
"UploadObjectAsset",
new RestHTTPHandler(
"POST",
"/CAPS/OA/" + capID + "/",
httpMethod => ProcessAdd(httpMethod, agentID, caps),
"UploadObjectAsset",
agentID.ToString()));
/*
caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
@@ -330,7 +333,6 @@ namespace OpenSim.Region.ClientStack.Linden
grp.AbsolutePosition = obj.Position;
prim.RotationOffset = obj.Rotation;
grp.IsAttachment = false;
// Required for linking
grp.RootPart.ClearUpdateSchedule();

View File

@@ -154,7 +154,9 @@ namespace OpenSim.Region.ClientStack.Linden
public void RegisterCaps(UUID agentID, Caps caps)
{
IRequestHandler reqHandler
= new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), HandleSimulatorFeaturesRequest);
= new RestHTTPHandler(
"GET", "/CAPS/" + UUID.Random(),
HandleSimulatorFeaturesRequest, "SimulatorFeatures", agentID.ToString());
caps.RegisterHandler("SimulatorFeatures", reqHandler);
}

View File

@@ -106,7 +106,9 @@ namespace OpenSim.Region.ClientStack.Linden
"POST",
"/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
new UploadBakedTextureHandler(
caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture));
caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture,
"UploadBakedTexture",
agentID.ToString()));
}
}
}

View File

@@ -144,7 +144,12 @@ namespace OpenSim.Region.ClientStack.Linden
capUrl = "/CAPS/" + UUID.Random();
IRequestHandler reqHandler
= new RestStreamHandler("POST", capUrl, m_webFetchHandler.FetchInventoryDescendentsRequest);
= new RestStreamHandler(
"POST",
capUrl,
m_webFetchHandler.FetchInventoryDescendentsRequest,
"FetchInventoryDescendents2",
agentID.ToString());
caps.RegisterHandler(capName, reqHandler);
}
@@ -160,4 +165,4 @@ namespace OpenSim.Region.ClientStack.Linden
// capName, capUrl, m_scene.RegionInfo.RegionName, agentID);
}
}
}
}

View File

@@ -39,7 +39,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public sealed class IncomingPacket
{
/// <summary>Client this packet came from</summary>
public LLUDPClient Client;
public LLClientView Client;
/// <summary>Packet data that has been received</summary>
public Packet Packet;
@@ -48,7 +49,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary>
/// <param name="client">Reference to the client this packet came from</param>
/// <param name="packet">Packet data</param>
public IncomingPacket(LLUDPClient client, Packet packet)
public IncomingPacket(LLClientView client, Packet packet)
{
Client = client;
Packet = packet;

View File

@@ -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.
@@ -357,7 +357,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;
@@ -442,7 +441,7 @@ 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;
@@ -450,7 +449,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
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 +465,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;
@@ -490,16 +487,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary>
public void Close()
{
IsActive = false;
m_log.DebugFormat(
"[CLIENT]: Close has been called for {0} attached to scene {1}",
Name, m_scene.RegionInfo.RegionName);
// Send the STOP packet
DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
OutPacket(disable, ThrottleOutPacketType.Unknown);
IsActive = false;
// Shutdown the image manager
ImageManager.Close();
@@ -2723,6 +2716,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
public void SendAssetNotFound(AssetRequestToClient req)
{
TransferInfoPacket Transfer = new TransferInfoPacket();
Transfer.TransferInfo.ChannelType = 2;
Transfer.TransferInfo.Status = -2;
Transfer.TransferInfo.TargetType = 0;
Transfer.TransferInfo.Params = req.Params;
Transfer.TransferInfo.Size = 0;
Transfer.TransferInfo.TransferID = req.TransferRequestID;
Transfer.Header.Zerocoded = true;
OutPacket(Transfer, ThrottleOutPacketType.Asset);
}
public void SendTexture(AssetBase TextureAsset)
{
@@ -3726,8 +3732,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
++updatesThisCall;
#region UpdateFlags to packet type conversion
PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
@@ -3784,20 +3788,53 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (!canUseImproved && !canUseCompressed)
{
ObjectUpdatePacket.ObjectDataBlock updateBlock;
if (update.Entity is ScenePresence)
{
objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
objectUpdates.Value.Add(update);
updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
}
else
{
objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
objectUpdates.Value.Add(update);
SceneObjectPart part = (SceneObjectPart)update.Entity;
updateBlock = CreatePrimUpdateBlock(part, AgentId);
// If the part has become a private hud since the update was scheduled then we do not
// want to send it to other avatars.
if (part.ParentGroup.IsAttachment
&& 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);
objectUpdates.Value.Add(update);
}
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
@@ -3810,15 +3847,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
else
{
ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
= CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
// Everything else goes here
terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
if (update.Entity is SceneObjectPart)
{
SceneObjectPart part = (SceneObjectPart)update.Entity;
// If the part has become a private hud since the update was scheduled then we do not
// want to send it to other avatars.
if (part.ParentGroup.IsAttachment
&& 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
}
#region Packet Sending
ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
@@ -11654,7 +11716,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (DebugPacketLevel <= 100 && (packet.Type == PacketType.AvatarAnimation || packet.Type == PacketType.ViewerEffect))
logPacket = false;
if (DebugPacketLevel <= 50 && packet.Type == PacketType.ImprovedTerseObjectUpdate)
if (DebugPacketLevel <= 50
& (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
logPacket = false;
if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily)
@@ -11767,7 +11830,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
ClientInfo info = m_udpClient.GetClientInfo();
info.userEP = m_userEndPoint;
info.proxyEP = null;
info.agentcircuit = RequestClientInfo();
@@ -11779,11 +11841,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)
@@ -11864,10 +11921,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return string.Empty;
}
public void KillEndDone()
{
}
#region IClientCore
private readonly Dictionary<Type, object> m_clientInterfaces = new Dictionary<Type, object>();
@@ -11955,21 +12008,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected void MakeAssetRequest(TransferRequestPacket transferRequest, UUID taskID)
{
UUID requestID = UUID.Zero;
if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset)
int sourceType = transferRequest.TransferInfo.SourceType;
if (sourceType == (int)SourceType.Asset)
{
requestID = new UUID(transferRequest.TransferInfo.Params, 0);
}
else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimInventoryItem)
else if (sourceType == (int)SourceType.SimInventoryItem)
{
requestID = new UUID(transferRequest.TransferInfo.Params, 80);
}
else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimEstate)
else if (sourceType == (int)SourceType.SimEstate)
{
requestID = taskID;
}
// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
// m_log.DebugFormat(
// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
// requestID, taskID, (SourceType)sourceType, Name);
m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
}
@@ -11982,14 +12038,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name="asset"></param>
protected void AssetReceived(string id, Object sender, AssetBase asset)
{
if (asset == null)
return;
TransferRequestPacket transferRequest = (TransferRequestPacket)sender;
UUID requestID = UUID.Zero;
byte source = (byte)SourceType.Asset;
AssetRequestToClient req = new AssetRequestToClient();
if (asset == null)
{
req.AssetInf = null;
req.AssetRequestSource = source;
req.IsTextureRequest = false;
req.NumPackets = 0;
req.Params = transferRequest.TransferInfo.Params;
req.RequestAssetID = requestID;
req.TransferRequestID = transferRequest.TransferInfo.TransferID;
SendAssetNotFound(req);
return;
}
if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset)
{
requestID = new UUID(transferRequest.TransferInfo.Params, 0);
@@ -12006,7 +12075,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return;
// The asset is known to exist and is in our cache, so add it to the AssetRequests list
AssetRequestToClient req = new AssetRequestToClient();
req.AssetInf = asset;
req.AssetRequestSource = source;
req.IsTextureRequest = false;
@@ -12042,24 +12110,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

@@ -147,21 +147,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private int m_elapsed500MSOutgoingPacketHandler;
/// <summary>Flag to signal when clients should check for resends</summary>
private bool m_resendUnacked;
protected bool m_resendUnacked;
/// <summary>Flag to signal when clients should send ACKs</summary>
private bool m_sendAcks;
protected bool m_sendAcks;
/// <summary>Flag to signal when clients should send pings</summary>
private bool m_sendPing;
protected bool m_sendPing;
private int m_defaultRTO = 0;
private int m_maxRTO = 0;
private int m_ackTimeout = 0;
private int m_pausedAckTimeout = 0;
private bool m_disableFacelights = false;
public Socket Server { get { return null; } }
private int m_malformedCount = 0; // Guard against a spamming attack
/// <summary>
/// Record current outgoing client for monitoring purposes.
/// </summary>
private IClientAPI m_currentOutgoingClient;
/// <summary>
/// Recording current incoming client for monitoring purposes.
/// </summary>
private IClientAPI m_currentIncomingClient;
public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
: base(listenIP, (int)port)
{
@@ -198,11 +211,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_defaultRTO = config.GetInt("DefaultRTO", 0);
m_maxRTO = config.GetInt("MaxRTO", 0);
m_disableFacelights = config.GetBoolean("DisableFacelights", false);
m_ackTimeout = 1000 * config.GetInt("AckTimeout", 60);
m_pausedAckTimeout = 1000 * config.GetInt("PausedAckTimeout", 300);
}
else
{
PrimUpdatesPerCallback = 100;
TextureSendLimit = 20;
m_ackTimeout = 1000 * 60; // 1 minute
m_pausedAckTimeout = 1000 * 300; // 5 minutes
}
#region BinaryStats
@@ -239,19 +256,56 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (m_scene == null)
throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference");
m_log.Info("[LLUDPSERVER]: Starting the LLUDP server in " + (m_asyncPacketHandling ? "asynchronous" : "synchronous") + " mode");
m_log.InfoFormat(
"[LLUDPSERVER]: Starting the LLUDP server in {0} mode",
m_asyncPacketHandling ? "asynchronous" : "synchronous");
base.Start(m_recvBufferSize, m_asyncPacketHandling);
// Start the packet processing threads
Watchdog.StartThread(
IncomingPacketHandler, "Incoming Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true);
IncomingPacketHandler,
string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName),
ThreadPriority.Normal,
false,
true,
GetWatchdogIncomingAlarmData,
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
Watchdog.StartThread(
OutgoingPacketHandler, "Outgoing Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true);
OutgoingPacketHandler,
string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName),
ThreadPriority.Normal,
false,
true,
GetWatchdogOutgoingAlarmData,
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
m_elapsedMSSinceLastStatReport = Environment.TickCount;
}
/// <summary>
/// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
/// </summary>
/// <returns></returns>
private string GetWatchdogIncomingAlarmData()
{
return string.Format(
"Client is {0}",
m_currentIncomingClient != null ? m_currentIncomingClient.Name : "none");
}
/// <summary>
/// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
/// </summary>
/// <returns></returns>
private string GetWatchdogOutgoingAlarmData()
{
return string.Format(
"Client is {0}",
m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none");
}
public new void Stop()
{
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
@@ -485,19 +539,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null);
}
public void HandleUnacked(LLUDPClient udpClient)
public void HandleUnacked(LLClientView client)
{
LLUDPClient udpClient = client.UDPClient;
if (!udpClient.IsConnected)
return;
// Disconnect an agent if no packets are received for some time
//FIXME: Make 60 an .ini setting
if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60)
{
m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
int timeoutTicks = m_ackTimeout;
// Allow more slack if the client is "paused" eg file upload dialogue is open
// Some sort of limit is needed in case the client crashes, loses its network connection
// or some other disaster prevents it from sendung the AgentResume
if (udpClient.IsPaused)
timeoutTicks = m_pausedAckTimeout;
if (client.IsActive &&
(Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks)
{
// 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;
// Fire this out on a different thread so that we don't hold up outgoing packet processing for
// everybody else if this is being called due to an ack timeout.
// This is the same as processing as the async process of a logout request.
Util.FireAndForget(o => DeactivateClientDueToTimeout(client));
RemoveClient(udpClient);
return;
}
@@ -820,7 +889,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion Ping Check Handling
// Inbox insertion
packetInbox.Enqueue(new IncomingPacket(udpClient, packet));
packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet));
}
#region BinaryStats
@@ -916,7 +985,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint);
m_log.DebugFormat(
"[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;
@@ -945,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(
@@ -1032,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;
@@ -1044,15 +1115,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return client;
}
private void RemoveClient(LLUDPClient udpClient)
/// <summary>
/// Deactivates the client if we don't receive any packets within a certain amount of time (default 60 seconds).
/// </summary>
/// <remarks>
/// If a connection is active then we will always receive packets even if nothing else is happening, due to
/// regular client pings.
/// </remarks>
/// <param name='client'></param>
private void DeactivateClientDueToTimeout(IClientAPI client)
{
// Remove this client from the scene
IClientAPI client;
if (m_scene.TryGetClient(udpClient.AgentID, out client))
{
client.IsLoggingOut = true;
client.Close();
}
// 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();
}
private void IncomingPacketHandler()
@@ -1159,6 +1245,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// client. m_packetSent will be set to true if a packet is sent
m_scene.ForEachClient(clientPacketHandler);
m_currentOutgoingClient = null;
// If nothing was sent, sleep for the minimum amount of time before a
// token bucket could get more tokens
if (!m_packetSent)
@@ -1175,18 +1263,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Watchdog.RemoveThread();
}
private void ClientOutgoingPacketHandler(IClientAPI client)
protected void ClientOutgoingPacketHandler(IClientAPI client)
{
m_currentOutgoingClient = client;
try
{
if (client is LLClientView)
{
LLUDPClient udpClient = ((LLClientView)client).UDPClient;
LLClientView llClient = (LLClientView)client;
LLUDPClient udpClient = llClient.UDPClient;
if (udpClient.IsConnected)
{
if (m_resendUnacked)
HandleUnacked(udpClient);
HandleUnacked(llClient);
if (m_sendAcks)
SendAcks(udpClient);
@@ -1202,8 +1293,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
catch (Exception ex)
{
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name +
" threw an exception: " + ex.Message, ex);
m_log.Error(
string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex);
}
}
@@ -1229,11 +1320,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
nticks++;
watch1.Start();
m_currentOutgoingClient = client;
try
{
if (client is LLClientView)
{
LLUDPClient udpClient = ((LLClientView)client).UDPClient;
LLClientView llClient = (LLClientView)client;
LLUDPClient udpClient = llClient.UDPClient;
if (udpClient.IsConnected)
{
@@ -1242,7 +1336,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
nticksUnack++;
watch2.Start();
HandleUnacked(udpClient);
HandleUnacked(llClient);
watch2.Stop();
avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
@@ -1313,23 +1407,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion
private void ProcessInPacket(object state)
private void ProcessInPacket(IncomingPacket incomingPacket)
{
IncomingPacket incomingPacket = (IncomingPacket)state;
Packet packet = incomingPacket.Packet;
LLUDPClient udpClient = incomingPacket.Client;
IClientAPI client;
LLClientView client = incomingPacket.Client;
// Sanity check
if (packet == null || udpClient == null)
if (client.IsActive)
{
m_log.WarnFormat("[LLUDPSERVER]: Processing a packet with incomplete state. Packet=\"{0}\", UDPClient=\"{1}\"",
packet, udpClient);
}
m_currentIncomingClient = client;
// Make sure this client is still alive
if (m_scene.TryGetClient(udpClient.AgentID, out client))
{
try
{
// Process this packet
@@ -1344,21 +1430,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
catch (Exception e)
{
// Don't let a failure in an individual client thread crash the whole sim.
m_log.ErrorFormat("[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw an exception", udpClient.AgentID, packet.Type);
m_log.Error(e.Message, e);
m_log.Error(
string.Format(
"[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw ",
client.Name, packet.Type),
e);
}
finally
{
m_currentIncomingClient = null;
}
}
else
{
m_log.DebugFormat("[LLUDPSERVER]: Dropping incoming {0} packet for dead client {1}", packet.Type, udpClient.AgentID);
m_log.DebugFormat(
"[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
packet.Type, client.Name, m_scene.RegionInfo.RegionName);
}
}
protected void LogoutHandler(IClientAPI client)
{
client.SendLogoutPacket();
if (client.IsActive)
RemoveClient(((LLClientView)client).UDPClient);
if (!client.IsLoggingOut)
{
client.IsLoggingOut = true;
client.Close();
}
}
}
}
}

View File

@@ -45,6 +45,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
[TestFixture]
public class BasicCircuitTests
{
private Scene m_scene;
private TestLLUDPServer m_udpServer;
[TestFixtureSetUp]
public void FixtureInit()
{
@@ -61,83 +64,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
}
// /// <summary>
// /// Add a client for testing
// /// </summary>
// /// <param name="scene"></param>
// /// <param name="testLLUDPServer"></param>
// /// <param name="testPacketServer"></param>
// /// <param name="acm">Agent circuit manager used in setting up the stack</param>
// protected void SetupStack(
// IScene scene, out TestLLUDPServer testLLUDPServer, out TestLLPacketServer testPacketServer,
// out AgentCircuitManager acm)
// {
// IConfigSource configSource = new IniConfigSource();
// ClientStackUserSettings userSettings = new ClientStackUserSettings();
// testLLUDPServer = new TestLLUDPServer();
// acm = new AgentCircuitManager();
//
// uint port = 666;
// testLLUDPServer.Initialise(null, ref port, 0, false, configSource, acm);
// testPacketServer = new TestLLPacketServer(testLLUDPServer, userSettings);
// testLLUDPServer.LocalScene = scene;
// }
// /// <summary>
// /// Set up a client for tests which aren't concerned with this process itself and where only one client is being
// /// tested
// /// </summary>
// /// <param name="circuitCode"></param>
// /// <param name="epSender"></param>
// /// <param name="testLLUDPServer"></param>
// /// <param name="acm"></param>
// protected void AddClient(
// uint circuitCode, EndPoint epSender, TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
// {
// UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
// UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
//
// AddClient(circuitCode, epSender, myAgentUuid, mySessionUuid, testLLUDPServer, acm);
// }
// /// <summary>
// /// Set up a client for tests which aren't concerned with this process itself
// /// </summary>
// /// <param name="circuitCode"></param>
// /// <param name="epSender"></param>
// /// <param name="agentId"></param>
// /// <param name="sessionId"></param>
// /// <param name="testLLUDPServer"></param>
// /// <param name="acm"></param>
// protected void AddClient(
// uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId,
// TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
// {
// AgentCircuitData acd = new AgentCircuitData();
// acd.AgentID = agentId;
// acd.SessionID = sessionId;
//
// UseCircuitCodePacket uccp = new UseCircuitCodePacket();
//
// UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
// = new UseCircuitCodePacket.CircuitCodeBlock();
// uccpCcBlock.Code = circuitCode;
// uccpCcBlock.ID = agentId;
// uccpCcBlock.SessionID = sessionId;
// uccp.CircuitCode = uccpCcBlock;
//
// acm.AddNewCircuit(circuitCode, acd);
//
// testLLUDPServer.LoadReceive(uccp, epSender);
// testLLUDPServer.ReceiveData(null);
// }
[SetUp]
public void SetUp()
{
m_scene = new SceneHelpers().SetupScene();
}
/// <summary>
/// Build an object name packet for test purposes
/// </summary>
/// <param name="objectLocalId"></param>
/// <param name="objectName"></param>
protected ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName)
private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName)
{
ObjectNamePacket onp = new ObjectNamePacket();
ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock();
@@ -148,29 +86,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
return onp;
}
/// <summary>
/// Test adding a client to the stack
/// </summary>
[Test]
public void TestAddClient()
{
TestHelpers.InMethod();
// XmlConfigurator.Configure();
TestScene scene = SceneHelpers.SetupScene();
uint myCircuitCode = 123456;
private void AddUdpServer()
{
AddUdpServer(new IniConfigSource());
}
private void AddUdpServer(IniConfigSource configSource)
{
uint port = 0;
AgentCircuitManager acm = m_scene.AuthenticateHandler;
m_udpServer = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, configSource, acm);
m_udpServer.AddScene(m_scene);
}
/// <summary>
/// Used by tests that aren't testing this stage.
/// </summary>
private ScenePresence AddClient()
{
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
uint myCircuitCode = 123456;
IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
uint port = 0;
AgentCircuitManager acm = scene.AuthenticateHandler;
TestLLUDPServer llUdpServer
= new TestLLUDPServer(IPAddress.Any, ref port, 0, false, new IniConfigSource(), acm);
llUdpServer.AddScene(scene);
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
@@ -185,26 +125,67 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
llUdpServer.PacketReceived(upb);
AgentCircuitData acd = new AgentCircuitData();
acd.AgentID = myAgentUuid;
acd.SessionID = mySessionUuid;
m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);
m_udpServer.PacketReceived(upb);
return m_scene.GetScenePresence(myAgentUuid);
}
/// <summary>
/// Test adding a client to the stack
/// </summary>
[Test]
public void TestAddClient()
{
TestHelpers.InMethod();
// XmlConfigurator.Configure();
AddUdpServer();
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
uint myCircuitCode = 123456;
IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
= new UseCircuitCodePacket.CircuitCodeBlock();
uccpCcBlock.Code = myCircuitCode;
uccpCcBlock.ID = myAgentUuid;
uccpCcBlock.SessionID = mySessionUuid;
uccp.CircuitCode = uccpCcBlock;
byte[] uccpBytes = uccp.ToBytes();
UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length);
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
m_udpServer.PacketReceived(upb);
// Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet
Assert.That(scene.GetScenePresence(myAgentUuid), Is.Null);
Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null);
AgentCircuitData acd = new AgentCircuitData();
acd.AgentID = myAgentUuid;
acd.SessionID = mySessionUuid;
acm.AddNewCircuit(myCircuitCode, acd);
m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);
llUdpServer.PacketReceived(upb);
m_udpServer.PacketReceived(upb);
// Should succeed now
ScenePresence sp = scene.GetScenePresence(myAgentUuid);
ScenePresence sp = m_scene.GetScenePresence(myAgentUuid);
Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));
Assert.That(llUdpServer.PacketsSent.Count, Is.EqualTo(1));
Assert.That(m_udpServer.PacketsSent.Count, Is.EqualTo(1));
Packet packet = llUdpServer.PacketsSent[0];
Packet packet = m_udpServer.PacketsSent[0];
Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));
PacketAckPacket ackPacket = packet as PacketAckPacket;
@@ -212,6 +193,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0));
}
[Test]
public void TestLogoutClientDueToAck()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
IniConfigSource ics = new IniConfigSource();
IConfig config = ics.AddConfig("ClientStack.LindenUDP");
config.Set("AckTimeout", -1);
AddUdpServer(ics);
ScenePresence sp = AddClient();
m_udpServer.ClientOutgoingPacketHandler(sp.ControllingClient, true, false, false);
ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID);
Assert.That(spAfterAckTimeout, Is.Null);
// TestHelpers.DisableLogging();
}
// /// <summary>
// /// Test removing a client from the stack
// /// </summary>

View File

@@ -79,7 +79,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
J2KDecoderModule j2kdm = new J2KDecoderModule();
scene = SceneHelpers.SetupScene();
SceneHelpers sceneHelpers = new SceneHelpers();
scene = sceneHelpers.SetupScene();
SceneHelpers.SetupSceneModules(scene, j2kdm);
tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene);

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

@@ -59,6 +59,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
PacketsSent.Add(packet);
}
public void ClientOutgoingPacketHandler(IClientAPI client, bool resendUnacked, bool sendAcks, bool sendPing)
{
m_resendUnacked = resendUnacked;
m_sendAcks = sendAcks;
m_sendPing = sendPing;
ClientOutgoingPacketHandler(client);
}
//// /// <summary>
//// /// The chunks of data to pass to the LLUDPServer when it calls EndReceive
//// /// </summary>

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