Compare commits

..

359 Commits

Author SHA1 Message Date
Justin Clark-Casey (justincc)
a315aee803 Move SenseRepeaters.Count check inside the SenseRepeatListLock.
No methods in the List class are thread safe in the MS specification/documentation
2012-03-02 00:36:29 +00:00
Justin Clark-Casey (justincc)
0c931e3657 lock SenseRepeatListLock when added a new sensor during script reconstitution.
This is already being done in the other place where a sensor is added.
Adding a sensor whilst another thread is iterating over the sensor list can cause a concurrency exception.
2012-03-02 00:36:20 +00:00
Justin Clark-Casey (justincc)
9f4d772d6a Add line numbers to Util.PrintCallStack() 2012-02-14 20:47:53 +00:00
Justin Clark-Casey (justincc)
d6cf029860 Fix bug where somebody taking a copy of an object they didn't own that was rezzed before the region was restarted would wrongly place the copy in the object owner's inventory.
Addresses http://opensimulator.org/mantis/view.php?id=5825
2012-02-14 20:47:40 +00:00
Justin Clark-Casey (justincc)
083587eb32 Stop a scene object from attempting to link with itself (which results in an exception and constant complaints in v3 viewers).
Aims to address http://opensimulator.org/mantis/view.php?id=5878
2012-02-14 20:47:10 +00:00
Justin Clark-Casey (justincc)
8c8e3ad3ff Make WebStats logging report consistently as WEB STATS MODULE instead of VC, VS and WEBSTATS 2012-02-14 20:46:59 +00:00
Justin Clark-Casey (justincc)
91d5495e26 Temporarily remove ScenePresenceAgentTests since getting them operational in this branch may require considerable changes 2012-02-14 20:45:16 +00:00
Justin Clark-Casey (justincc)
2030377d2c Only look for an uploaded transactional asset in Scene.UpdateTaskInventory if we have been passed a non-zero transaction ID.
This resolves the recent regression from deeb728 where notecards could not be saved in prim inventories.
This looks like a better solution than deeb728 since only non-caps updates pass in a transaction ID.
Hopefully resolves http://opensimulator.org/mantis/view.php?id=5873
2012-02-14 20:37:58 +00:00
Justin Clark-Casey (justincc)
31a0f75aff D'oh - we want to call llGetLinkNumberOfSides() in the LSL_Stub, not llGetLinkNumber(). 2012-02-14 20:36:09 +00:00
Justin Clark-Casey (justincc)
c1d84ffc6c Add llGetLinkNumberOfSides to LSL_Stub and ILSL_Api
It already existed in LSL_Api but it also needs to exist in these two other places for a script to be able to see it.
Hopefully resolves http://opensimulator.org/mantis/view.php?id=5489
2012-02-14 20:36:00 +00:00
Justin Clark-Casey (justincc)
6c72381732 Lay out script status in property per row format, since getting too long for console lines. 2012-02-02 23:59:01 +00:00
Justin Clark-Casey (justincc)
8c271802ac Add count of events queued for a particular script in "scripts show" console command 2012-02-02 23:58:51 +00:00
Justin Clark-Casey (justincc)
20a76fd224 Make script console commands only show for selected region. 2012-02-02 23:58:42 +00:00
Justin Clark-Casey (justincc)
4473f00e63 Implement "xengine status" console command to show various xengine stats 2012-02-02 23:58:36 +00:00
Justin Clark-Casey (justincc)
0b5210dd6a Add "show part uuid" and "show part name" console commands.
These commands will display part/prim details for a given uuid or name
The "show object uuid" and "show object name" commands will now only display details for objects (i.e. not child parts in a linkset).
This is for consistency with the "delete object" commands which only delete objects, not parts.
2012-02-02 23:58:27 +00:00
Justin Clark-Casey (justincc)
34d4bde585 Implement "show object name <name>" console command to show details of an object with the given name 2012-02-02 23:58:17 +00:00
Justin Clark-Casey (justincc)
4c20c2045c Get rid of the "no objects found" feedback for now - this doesn't work well if a command is executed over multiple scenes. 2012-02-02 23:58:09 +00:00
Justin Clark-Casey (justincc)
d9a8f5f16d Implement "show object uuid <uuid>" console command.
This will show details about a part with the given uuid if it's found.
2012-02-02 23:57:18 +00:00
Justin Clark-Casey (justincc)
79c2081741 Add more user feedback if an object isn't found for which delete was requested. 2012-02-02 23:57:07 +00:00
Justin Clark-Casey (justincc)
eb49c356e2 Add the name of a deleted object to the console output 2012-02-02 23:56:59 +00:00
Justin Clark-Casey (justincc)
717942e81b If a particular region is selected in the console, only try to delete objects in that region, rather than in every region on the simulator
The old wrong behaviour was in place before the command was extracted to a module.
2012-02-02 23:56:52 +00:00
Justin Clark-Casey (justincc)
6d47c394b2 Move object delete commands into a commands region module, in preparation for adding similar show commands. 2012-02-02 23:56:45 +00:00
Justin Clark-Casey (justincc)
8305c5d369 Use Environment.TickCount & Int32.MaxValue; instead of Util.EnvironmentTickCount(); when producing the threads report to reduce wraparound.
This matches the tickcount masking in the thread watchdog.
For some reason, Util.EnvironmentTickCount() masks ticks by 0x3fffffff instead of 0xffffffff
2012-02-02 23:56:29 +00:00
Justin Clark-Casey (justincc)
9e5f5f3d80 lock SceneObjectGroupsByFullID in SceneGraph.ForEachSOG() to stop failure if SceneObjectGroupsByFullID is updated elsewhere at the same time. 2012-02-02 23:55:13 +00:00
Justin Clark-Casey (justincc)
0a277a64a7 Comment out xfer section in Scene.UpdateTaskInventory() which was causing spurious errors and "script saved" messages when script properties were changed.
Viewers since at least Linden Lab 1.23 use the script upload capability to save script changes.
It's unknown whether the commented out code was working for very old viewers or not.
Code is commented out to reduce complexity and so that useful error messages don't need to be removed.
If there is a substantial population using extremely old viewers that can't upgrade to a newer version 1 viewer (e.g. 1.23) or similar TPV then this can be revisited.
2012-02-02 23:54:42 +00:00
Justin Clark-Casey (justincc)
7dd0b7ea2f minor: stop the WebStatsModule logging UPDATE or INSERT every time it updates bin/LocalUserStatistics.db 2012-02-02 23:54:00 +00:00
Justin Clark-Casey (justincc)
cd666a3d2c Serialize calls to ODE Collide() function across OdeScene instances to prevent ODE crashes on simulators running more than one region.
It turns out that calls to Collide() are not thread-safe even for objects in different ODE physics worlds due to ODE static caches.
For simulators running multiple regions, not serializing calls from different scene loops will sooner or later cause OpenSim to crash with a native stack trace referencing OBBCollider.
This affects the default OPCODE collider but not GIMPACT.  However, GIMPACT fails for other reasons under some current simulator loads.
ODE provides a thread local storage option, but as of ODE r1755 (and r1840) DLLs compiled with this crash OpenSim immediately.
2012-02-02 23:53:46 +00:00
Justin Clark-Casey (justincc)
681502473e Fix "Abnormal client thread terminations" stat in period CONNECTION STATISTICS to count the number of times clients are disconnected due to ack timeouts.
This has been broken for a long period and would only ever show 0.
2012-02-02 23:53:23 +00:00
Justin Clark-Casey (justincc)
0ffe293692 minor: correct text and usage for "image queues show" reigon console command. 2012-02-02 23:52:59 +00:00
Justin Clark-Casey (justincc)
356e8516f0 Restrict accessible of ODECharacter Shell and Body. Add method doc and some error log lines. 2012-02-02 23:52:32 +00:00
Justin Clark-Casey (justincc)
71b11f557d Allow a viewer UDP image request retry to trigger another asset fetch if an existing fetch hasn't responded before a timeout.
This is to stop a high priority image/texture request from blocking the entire download queue if its asset fetch got dropped for some reason.
2012-01-23 21:35:25 +00:00
Justin Clark-Casey (justincc)
26be9ed08e Add image not in database test for LLImageManager 2012-01-23 21:35:16 +00:00
Justin Clark-Casey (justincc)
f43d63240d refactor: separate out common parts of LLImageManagerTests 2012-01-23 21:34:46 +00:00
Justin Clark-Casey (justincc)
5c982c98aa Add LLImageManager regression test for discard case 2012-01-23 21:34:35 +00:00
Justin Clark-Casey (justincc)
63f0ec9aeb Add "image queues clear <first-name> <last-name>" console command
This allows a way to manually clear pending image queue requests for debug purposes
2012-01-23 21:33:56 +00:00
Justin Clark-Casey (justincc)
e90cfc17ca Add basic request and send image regression tests for LLImageManager 2012-01-23 21:33:44 +00:00
Justin Clark-Casey (justincc)
16d5ce16b6 Extend scripts show command to accept a single item UUID parameter to display one script's status
Usage is now scripts show [<script-item-uuid>]
2012-01-16 21:24:15 +00:00
Justin Clark-Casey (justincc)
ab4c4a362f Register the UrlModule for script engine events OnScriptRemoved and OnObjectRemoved just once in the UrlModule itself, rather than repeatedly for every script.
Doing this in every script is unnecessary since the event trigger is parameterized by the item id.
All that would happen is 2000 scripts would trigger 1999 unnecessary calls, and a large number of initialized scripts may eventually trigger a StackOverflowException.
Registration moved to UrlModule so that the handler is registered for all script engine implementations.
This required moving the OnScriptRemoved and OnObjectRemoved events (only used by UrlModule in core) from IScriptEngine to IScriptModule to avoid circular references.
2012-01-16 21:24:05 +00:00
Justin Clark-Casey (justincc)
b5971db76c minor: Fix wrong column length in image queues report 2012-01-16 21:23:03 +00:00
Justin Clark-Casey (justincc)
0c39c9e84d rename "show image queue" to "show image queues" in line with other udp info commands.
Eliminate redundant one line methods
2012-01-16 21:22:54 +00:00
Justin Clark-Casey (justincc)
0b49773ab3 Add "show image queue <first-name> <last-name>" region console command
This is so that we can inspect the image download queue (texture download via udp) for debugging purposes.
2012-01-16 21:22:44 +00:00
Justin Clark-Casey (justincc)
820a39621e correct very minor typo in "debug scene" help 2012-01-16 21:20:36 +00:00
Justin Clark-Casey (justincc)
7a0f4cf8e1 Add "app find <uuid-or-start-of-uuid>" command to find the appearance using a particular baked texture, if any.
This is for debugging to relate texture console entries back to particular users on the simulator end.
2012-01-16 21:20:18 +00:00
Justin Clark-Casey (justincc)
2853b78f16 Improve "j2k decode" command to tell us how many layers and components were decoded, instead of just success/failure 2012-01-09 13:14:50 +00:00
Justin Clark-Casey (justincc)
a3ada745bd Add a "j2k decode" region console command that allows a manual request for a JPEG2000 decode of an asset
For debugging purposes.
2012-01-09 13:14:39 +00:00
Justin Clark-Casey (justincc)
ff0f90bc35 Make "show asset" command available simulator side. Actually make the service command be "show asset" instead of "show digest" this time.
Last time I accidnetally just changed the usage message.
2012-01-09 13:14:26 +00:00
Justin Clark-Casey (justincc)
7b564b8b35 Rename 'show digest' console command to 'show asset' 2012-01-09 13:14:19 +00:00
Justin Clark-Casey (justincc)
19a818017d Add size and temporary information to "show asset" command 2012-01-09 13:14:00 +00:00
Justin Clark-Casey (justincc)
7bc03a54e5 Move simulator asset info commands to an optional module from the connector. Make them conform with service side commands.
This stops them appearing twice when Hypergrid is enabled.
2012-01-09 13:13:40 +00:00
Justin Clark-Casey (justincc)
aef6a9571c Move asset commands from AssetService to AssetServerConnector so that we can harmonise the same commands on the simulator side.
No functional change.
2012-01-09 13:13:33 +00:00
Justin Clark-Casey (justincc)
0a3b2f904e recomment log messages I accidentally left uncommented 2012-01-09 13:13:11 +00:00
Justin Clark-Casey (justincc)
023023a5fc Improve "app rebake" command to return a better message if no uploaded texture ids were available for the rebake request 2012-01-09 13:12:52 +00:00
Justin Clark-Casey (justincc)
eebcea22ba Commenting out DataSnapShot message "Registering service discovery capability" for now.
Please uncomment if/when needed.
2012-01-09 13:08:02 +00:00
Justin Clark-Casey (justincc)
9474bdb6df Add "appearance rebake" command to ask a specific viewer to rebake textures from the server end.
This is not as useful as it sounds, since you can only request rebakes for texture IDs already received.
In other words, if the viewer has never sent the server this information (which happens quite often) then it will have no effect.
Nonetheless, this is useful for diagnostic/debugging purposes.
2012-01-09 13:07:39 +00:00
Justin Clark-Casey (justincc)
4d28bac9bb Separate out rebake request code from cache validation code AvatarFactoryModule.
This allows some logic simplification and allows an external caller to manually request rebakes even if textures are uploaded (future command).
2012-01-09 13:00:56 +00:00
Justin Clark-Casey (justincc)
de746cd987 Minor formatting changes and commented out log lines for future debugging of image manager (udp texture fetch). No significant functional changes. 2012-01-09 12:37:51 +00:00
Justin Clark-Casey (justincc)
0ef16f9f5b Remove the pointless LLClientView.m_imageManager null check.
Despite the code comments we never actually null it.
2012-01-09 12:37:38 +00:00
Justin Clark-Casey (justincc)
de0a45d9a3 Update C5.dll to version 1.1.1 from 1.1.0
C5 is a collections library and can be found at http://www.itu.dk/research/c5/
This is used in the UDP texture (image) sending code.
2012-01-09 12:37:26 +00:00
Justin Clark-Casey (justincc)
a2071e5b13 Reduce accessibility of some J2KImage/LLImageManager properties and methods to reduce potential code complexity and make code reading easier. 2012-01-09 12:37:04 +00:00
Justin Clark-Casey (justincc)
1b3ae566e8 Adding commented out log messages and some minor formatting for future bug hunting. No functional changes. 2012-01-09 12:37:00 +00:00
Mic Bowman
674baa39ed fix the UsesPhysics flag to reference the physics flag rather than the temponrez flag 2012-01-09 12:33:51 +00:00
Justin Clark-Casey (justincc)
1cf57c83e1 Align default ODE_STEPSIZE with that already used through OpenSimDefaults.ini 2012-01-09 12:33:39 +00:00
Justin Clark-Casey (justincc)
e98e580900 rename Scene.m_physicalPrim to PhysicalPrims since its public and access external as a property 2012-01-09 12:31:53 +00:00
Justin Clark-Casey (justincc)
292ab783e4 Remove unused m_physicalPrim parameter from SOG.ApplyPhysics() 2012-01-09 12:30:04 +00:00
Justin Clark-Casey (justincc)
0563530bf8 remove now redundant m_physical_prim flag from SOP.ApplyPhysics() 2012-01-09 12:26:49 +00:00
Justin Clark-Casey (justincc)
2135b89c07 Make it possible to force all prims to be phantom via the collidable_prim boolean setting in the OpenSim.ini config [Startup] section.
Naturally, default is true.
When set to false, "phantom" flags on prims can be set as usual but all prims remain phantom.
This setting is for test purposes.
This switch does not affect the collision of avatars with the terrain.
2012-01-09 12:04:45 +00:00
Dan Lake
2b19a112d9 Remove unused SetAcceleration and add set on Acceleration parameter 2012-01-09 12:02:46 +00:00
Justin Clark-Casey (justincc)
cd78f50632 Though the viewer warns about receiving this, not sending appears to break baked texture caching when crossing region boundaries.
Needs further investigation.

Revert "Stop sending the viewer its own AvatarAppearance packet."

This reverts commit 92039f295d.
2011-12-20 20:58:37 +00:00
Justin Clark-Casey (justincc)
b300db9e0a Stop sending the viewer its own AvatarAppearance packet.
The viewer warns in the log if it receives this.
Stopping this doesn't appear to have adverse effects on viewer 1 or viewer 3 - the viewer gets its own appearance from body parts/clothes and self-baked textures.
2011-12-19 21:16:34 +00:00
Justin Clark-Casey (justincc)
4370f0e181 Stop unnecessarily sending the TextureEntry in client avatar updates.
As far as I know, viewers don't use this mechanism to recieve new TextureEntry data for avatars.  This is done via the AvatarAppearance packet instead.
Tested this back to viewer 1.23.
Replacing with Utils.EmptyBytes since converting the texture entry to bytes on each AvatarUpdate (or which there are many) is not cost-free.
2011-12-19 21:16:24 +00:00
Justin Clark-Casey (justincc)
48ea503c33 Fix race condition where the appearance update timer could be stopped just after another thread had started it on QueueAppearanceSave() or *Send()
However, the window for this race is very small, and the next queued appearance save or send would restart the timer anyway.
2011-12-19 21:16:14 +00:00
nebadon
546eb88112 addresses mantis #5827
RAdmin - admin_save_oar fails if noassets parameter missing
thanks Michelle Argus
2011-12-19 21:09:36 +00:00
Justin Clark-Casey (justincc)
52710b48ac Provide user feedback on execution of "backup" region console command 2011-12-19 21:09:28 +00:00
Justin Clark-Casey (justincc)
cc5e28c1c1 Fix bug where objects couldn't be set back to the "none" group.
This is handled by treating UUID.Zero as a special case.
Currently, asking for the "none" group returns nothing because XMLRPC groups, at least, is not properly handling this case.
It may be better in the future to have GroupsModule return an appropriate GroupsData structure instead or require the underlying services to behave appropriately.
This is a further component of http://opensimulator.org/mantis/view.php?id=5588
2011-12-19 21:09:19 +00:00
Justin Clark-Casey (justincc)
67a2d6d855 Fix bug where objects could not be set to a new group if the group had been created in that client session, or if no other action has been performed on the object.
There were two problems here:
1) On object group update, we looked for the group is the IClientAPI group cache rather than in the groups service.  This fails to groups created newly in that session
2) On object group update, we weren't setting the HasGroupChanged flag.  This meant that the change was not persisted unless some other action set this flag.
This commit fixes these issues and hopefully addresses http://opensimulator.org/mantis/view.php?id=5588
This commit also moves HandleObjectGroupUpdate() to the GroupsModule from the Scene.PacketHandlers.cs file
2011-12-19 21:09:09 +00:00
Justin Clark-Casey (justincc)
7d426debd3 refactor: simplify methods in Scene.PacketHandlers.cs by using GetGroupByPrim() rather than retrieving GetEntities() and inspecting the entire list 2011-12-19 21:05:27 +00:00
Justin Clark-Casey (justincc)
4de98ca4c8 Add SceneViewer changes for removing unused client flags 2011-12-19 21:01:46 +00:00
Justin Clark-Casey (justincc)
deb50cd410 Stop generating client flags when we send out full object updates.
These were entirely unused.
2011-12-19 20:59:18 +00:00
Justin Clark-Casey (justincc)
b3cfc5b76e Stop pointlessly setting the m_colliderarr[] to false in the ODECharacter constructor 2011-12-19 20:49:31 +00:00
Justin Clark-Casey (justincc)
27644bcce6 Stop having to call SetHeight again in ScenePresence.AddToPhysicalScene() when we've already passed size information to the avatar at PhysicsScene.AddAvatar()
Eliminate some copypasta for height setting in OdeCharacter
2011-12-19 20:49:09 +00:00
Justin Clark-Casey (justincc)
903da8acbd Simplify some manipulation of _taintedActors in OdeScene 2011-12-19 20:31:57 +00:00
Justin Clark-Casey (justincc)
cfdccdd71c Eliminate _taintedPrimsH and _taintedPrimsL (and _taintedPrimLock) in favour of just a _taintedPrims HashSet.
There's no point maintaining a list because any pending taint operations are all carried out in the same call anyway.
2011-12-19 20:30:52 +00:00
Justin Clark-Casey (justincc)
93e65fb9d5 In AvatarFactoryModule.SetApperance(), perform ValidateBakedTextureCache() in the same thread rather than on another one.
The caller is already an async thread from LLClientView so this doesn't hold up the client.
However, launching on a separate thread does remove the effect of m_setAppearanceLock
This was potentially allowing two different SetAppearance threads to interfere with each other, though this probably rarely happens, if at all.
2011-12-19 20:30:26 +00:00
Justin Clark-Casey (justincc)
af117fe4d4 Get rid of the 'lolcat' library asset.
This was both unused and an invalid jpeg2000 texture from way back in 2008
2011-12-19 20:26:19 +00:00
Justin Clark-Casey (justincc)
986f6b39ca Fix build 2011-12-12 20:32:47 +00:00
Justin Clark-Casey (justincc)
7a8dd539fd minor: remove pointless comment from OdeScene.cs 2011-12-12 20:24:03 +00:00
Justin Clark-Casey (justincc)
382cda662f minor: comment out "unpacked appearance" log mesasge for now 2011-12-12 20:23:17 +00:00
Justin Clark-Casey (justincc)
ede9aea45f Comment out ChildAgentDataUpdate.Pack() "Pack data" message for now. 2011-12-12 20:23:07 +00:00
Justin Clark-Casey (justincc)
52b8518fc2 Do some clean up Scene.cs log messages.
This prints out both exception message and stacktrace (Exception.ToString()) isn't enough on Windows.
This also uses m_log.*Format() which is more efficient than string concat.
2011-12-12 20:22:57 +00:00
Justin Clark-Casey (justincc)
c3d16955a7 Get rid of IScene.PresenceChildStatus() which always had to execute a lookup in favour of IClientAPI.ISceneAgent.IsChildAgent instead. 2011-12-12 20:22:54 +00:00
Justin Clark-Casey (justincc)
61df0da7f9 remove some unused fields in ScenePresence 2011-12-12 20:18:13 +00:00
Justin Clark-Casey (justincc)
f8b0427086 Move client id check in Scene.Inventory.cs:UpdateInventoryItemAsset so that it doesn't trigger an exception if the item hasn't been found.
In this situation we will now put out a slightly more meaningful log error message instead.
2011-12-12 20:17:43 +00:00
Justin Clark-Casey (justincc)
5b0d0ef1e9 Don't reply with an ack packet if the client is not authorized. 2011-12-12 20:17:22 +00:00
Justin Clark-Casey (justincc)
7ca688f5c5 Extend TestAddClient() to check that the first packet received is an ack packet 2011-12-12 20:17:14 +00:00
Justin Clark-Casey (justincc)
9dc1000c27 Add OpenSim.Region.ClientStack.LindenUDP.Tests.dll back into the test suite 2011-12-12 20:15:28 +00:00
Justin Clark-Casey (justincc)
638afca5aa Reactivate BasicCircuitTests.TestAddClient()
This checks that the initial UseCircuitCode packet is handled correctly for a normal client login.
2011-12-12 20:15:16 +00:00
Justin Clark-Casey (justincc)
7e415e3f85 Remove unnecessary AgentCircuitData null check from Scene.AddNewClient().
The only caller is the LLUDP stack and this has to validate the UDP circuit itself, so we know that it exists.
This allows us to eliminate another null check elsewhere and simplifies the method contract
2011-12-12 20:11:26 +00:00
Justin Clark-Casey (justincc)
8c4e58995d When a client connects to a scene, send other avatar appearance data asynchronously to reduce hold up in the IN UDP packet processing loop.
This is already being done for the initial object data send.
2011-12-12 20:09:04 +00:00
Justin Clark-Casey (justincc)
d26ded4788 fix build 2011-12-12 20:08:49 +00:00
Justin Clark-Casey (justincc)
5268334c61 On a new client circuit, send the initial reply ack to let the client know it's live before sending other data.
This means that avatar/appearance data of other avatars and scene objects for a client will be sent after the ack rather than possibly before.
This may stop some avatars appearing grey on login.
This introduces a new OpenSim.Framework.ISceneAgent to accompany the existing OpenSim.Framework.ISceneObject and ISceneEntity
This allows IClientAPI to handle this as it can't reference OpenSim.Region.Framework.Interfaces
2011-12-12 20:08:02 +00:00
Justin Clark-Casey (justincc)
6ba4cbc259 Simplify Scene.AddNewClient()
If sp becomes null right after we've checked or created it, then behaviour down the line is going to be wrong anyway.
So instead retain the check/create ScenePresence reference and use this.
2011-12-12 20:00:15 +00:00
Melanie
ac445463e9 Remove a left over log output 2011-12-08 23:54:33 +00:00
Justin Clark-Casey (justincc)
1e83800d32 Remove warning in admin_save_oar xmlrpc method where noassets == true was comparing against an object rather than a string 2011-12-08 23:54:25 +00:00
Justin Clark-Casey (justincc)
3d94984eee Have admin_load_heighmap and admin_save_heightmap xmlrpcadmin methods return success = true on success rather than false 2011-12-08 23:54:18 +00:00
Justin Clark-Casey (justincc)
fd8734b22c Refactor RemoteAdminPlugin so that every xmlrpc method calls a common block of code to do password checks, etc., instead of copy/pasting this code into every method 2011-12-08 23:54:11 +00:00
Justin Clark-Casey (justincc)
9b229efdc5 Remove unused SceneManager.TryGetAvatarsScene()
It makes far more sense anyway to use TryGetRootScenePresence().Scene, in common with the rest of the code
This method could also return any scene for child or root agents, depending in which order the scenes happened to lie in the list
2011-12-08 23:54:04 +00:00
Justin Clark-Casey (justincc)
81daedcfe3 Implement XMLRPCAdmin command admin_teleport_agent.
This allows someone with access to this command on the XMLRPCAdmin interface to teleport an avatar to an arbitrary region and/or position.
2011-12-08 23:53:43 +00:00
Michelle Argus
b819771919 RemoteAdmin - Added optional terrain loading on region create using parameter heightmap_file to specify the terrain file to be loaded 2011-12-08 23:53:18 +00:00
Justin Clark-Casey (justincc)
2f536f92c0 Remove the inconsistently applied now pointless FailIfRemoteAdminDisabled() check on XMLRPC RemoteAdmin handlers.
If admin is disabled then the XMLRPC handlers are never registered, which means that they cannot be called anyway.
2011-12-08 23:52:04 +00:00
Justin Clark-Casey (justincc)
0b4774c50c replace List used by m_accessIP in RemoteAdminPlugin with the more efficient HashSet 2011-12-08 23:51:58 +00:00
Justin Clark-Casey (justincc)
139b0d03b6 Improve explanation of access_ip_addresses in [RemoteAdmin] to say that there are no restrictions if not set 2011-12-08 23:51:51 +00:00
Justin Clark-Casey (justincc)
c13916d392 Add option to allow only explicitly listed IPs to access RemoteAdmin facilities.
Also adds password check to some functions where this was missing and fixes some parameter checking.
This is a patch from http://opensimulator.org/mantis/view.php?id=5715 with a few small unrelated spacing tweaks from me.
Thanks Michelle Argus.
2011-12-08 23:51:16 +00:00
Justin Clark-Casey (justincc)
3ebb56734d properly lock CapsHandlers.m_capsHandlers 2011-12-08 23:47:45 +00:00
Justin Clark-Casey (justincc)
235147c857 Make "show appearance" a synonym for "appearance show" 2011-12-06 22:24:11 +00:00
Justin Clark-Casey (justincc)
ddb74bc68d In "appearance show", if a particular avatar is specified, print out texture UUID for each bake type and whether the simulator can find it. 2011-12-06 22:23:52 +00:00
Justin Clark-Casey (justincc)
cd132966df Actually send the avatar data if an individual avatar is specified, rather than accidentally doing nothing 2011-12-06 22:21:02 +00:00
Justin Clark-Casey (justincc)
5d4fee6eb9 conflict resolution due to drift in ValidateBakedTextureCache args 2011-12-06 22:20:44 +00:00
Justin Clark-Casey (justincc)
cc80377325 Allow "appearance show" command to take an optional avatar name 2011-12-06 22:20:01 +00:00
Justin Clark-Casey (justincc)
7dce33ce69 Make it possible to manually send appearance information via the "appearance send" command for a chosen avatar as well as all 2011-12-06 22:16:49 +00:00
Justin Clark-Casey (justincc)
0dd45f6ca4 Provide feedback as to which avatars are resending appearance informion on "appearance send" console command 2011-12-06 22:16:40 +00:00
Justin Clark-Casey (justincc)
ac3d88804f Stop accidentally setting up the UploadTexture caps handler with the same url for all users
This meant that if a user exited the region, the UploadTexture handler would be effectively removed for everyone, causing subsequent failures.
This hopefully resolves the recent UploadTexture LLSD problems
This was a regression in 5640f2e (Thu Dec 1 23:24:15 2011 +0000)
2011-12-06 22:13:58 +00:00
Justin Clark-Casey (justincc)
f1698552f9 For the GetTexture capability, if a data range is requested that covers the whole asset length, return HTTP PartialContent instead of NotFound
NotFound is obviously wrong, and this change stops viewer 3.2.2 (and v probably earlier) complaining in the log about missing textures that are actually present.
We still return PartialContent even if the range requested is a superset of the data range as per httpd's behaviour
https://issues.apache.org/bugzilla/show_bug.cgi?id=51878
Viewer 3.2.2 and very probably earlier appear happy with this.
Whether fixing this NotFound bug has any practical effect apart from resolve viewer log messages is unknown.
2011-12-05 21:06:16 +00:00
Justin Clark-Casey (justincc)
dfeb424afd Add "appearance send" command to allow manual sending of appearance. 2011-12-05 16:02:26 +00:00
Justin Clark-Casey (justincc)
2380980975 Stop performing the asset save part of baked texture uploading on the UploadBakedTexture cap asynchronously.
This prevents a possible race condition where the client would be told all baked textures had updated before they were in the asset service.
The client would then trigger a set appearance which, after a delay, would send the avatar appearance out to other clients.
The race condition seems unlikely because of this delay but it's still possible.
Might help with grey avatar appearances.
2011-12-05 16:00:36 +00:00
Justin Clark-Casey (justincc)
52ec854c42 refactor: Separate the upload baked texture handler out from BunchOfCaps 2011-12-05 16:00:27 +00:00
Justin Clark-Casey (justincc)
4dbfcc26a2 Provide more user feedback when "debug http" is set 2011-12-05 16:00:15 +00:00
Justin Clark-Casey (justincc)
a262d2492f On "show caps", stop excluding the seed cap but do exclude it elsewhere 2011-12-05 16:00:06 +00:00
Justin Clark-Casey (justincc)
e5b7e2fd40 With "debug http 1", show the path with the query string instead of just the path.
Also simplifies debug levels to just 0 and 1
2011-12-05 15:59:53 +00:00
Justin Clark-Casey (justincc)
7505f23f80 Improve some of the debug help messages 2011-12-05 15:59:45 +00:00
Justin Clark-Casey (justincc)
7562e63ae6 minor: remove mono compile warning, a Vector3 can never be null since it's a struct 2011-12-05 15:59:38 +00:00
Justin Clark-Casey (justincc)
7987a6da95 tabulate "show caps" output for easier readability 2011-12-05 15:59:27 +00:00
Justin Clark-Casey (justincc)
fcd60c6b74 Correct mistake in "debug eq" help 2011-12-05 15:59:19 +00:00
Justin Clark-Casey (justincc)
1e88bf78f1 When setting packet level logging via "debug packet", apply to all clients, not just root ones.
Also adds scene name and client type (root|child) to logged information.
2011-12-05 15:58:24 +00:00
Justin Clark-Casey (justincc)
a819890137 Add a "debug eq" console command for debugging.
This will log outgoing event queue message names if turned on.
2011-12-05 15:55:32 +00:00
Justin Clark-Casey (justincc)
5c85a98f6a Add "debug http" command for currently simple extra debug logging of non-event queue inbound http requests to a simulator 2011-12-05 15:54:10 +00:00
Justin Clark-Casey (justincc)
e58daf052d minor: remove mono compiler warning 2011-12-05 15:50:20 +00:00
Justin Clark-Casey (justincc)
0a0e285919 remove some mono compiler warnings 2011-11-28 15:59:43 +00:00
Justin Clark-Casey (justincc)
c693bd51a0 Remove bizarre call to PhysicsScene.Simulate(0) in Scene.GetNearestAllowedPosition()
At least on ODE, this wasn't doing any harm but there wasn't any point to it either
2011-11-28 15:59:30 +00:00
Justin Clark-Casey (justincc)
808ace0696 minor: remove mono compiler warning 2011-11-28 15:59:20 +00:00
Justin Clark-Casey (justincc)
9730a862db Log error if we attempt to add/remove an OdeCharacter from the _characters list inappropriately 2011-11-28 15:58:06 +00:00
Justin Clark-Casey (justincc)
754d6036ea Stop removing actor from the hash maps in OdeScene.RemoveCharacter() since this is now being down in OdeCharacter.DestroyOdeStructures() 2011-11-28 15:54:57 +00:00
Justin Clark-Casey (justincc)
476d893630 Comment out uncalled OdeScene.UnCombine() 2011-11-28 15:54:49 +00:00
Justin Clark-Casey (justincc)
0a6374d37a Comment out unimplemented and uncalled RegionCombinerModule.UnCombineRegion() 2011-11-28 15:54:40 +00:00
Justin Clark-Casey (justincc)
0337f2e2a0 minor: remove mono compiler warning 2011-11-28 15:54:32 +00:00
Justin Clark-Casey (justincc)
7be35d5a9a Stop an exception being thrown and a teleport/border cross failing if the desintation sim has no active script engines.
This involves getting IScene.RequestModuleInterfaces() to return an empty array (as was stated in the method doc) rather than an array containing one null entry.
Callers adjusted to stop checking for the list reference being null (which never happened anyway)
2011-11-28 15:54:25 +00:00
Justin Clark-Casey (justincc)
8ab2d42143 slightly simplify OdeScene.Simulate() by removing bool processtaints, since we can inspect count of taint lists instead.
also groups OdeCharacter.CreateOdeStructures() and DestroyOdeStructures() together
2011-11-28 15:54:13 +00:00
Justin Clark-Casey (justincc)
dc8ce9ec5d Improve the error messages returned if the HelloNeighbour call fails.
This is the message a region sends to its neighbours when it comes up
2011-11-28 15:54:04 +00:00
Justin Clark-Casey (justincc)
7171913400 Slightly improve "Unable to space collide" logging message, though I don't think I've ever seen this. 2011-11-28 15:53:53 +00:00
Justin Clark-Casey (justincc)
0cf5c0837b Get rid of OdeCharacter != null checks since OdeScene._characters can never contain a null character.
Ignoring the ancient code glyphs not to do this....
2011-11-28 15:53:45 +00:00
Justin Clark-Casey (justincc)
1edfe05c16 remove unnecessary OdeScene._activeprims locking. Code is single-threaded 2011-11-28 15:53:36 +00:00
Justin Clark-Casey (justincc)
bba4577d88 Restore defects list. In hindsight, the reason for this is becuase we can't remove the character whilst iterating over the list.
This commit also removes locking on OdeScene._characters since code is single threaded
2011-11-28 15:53:28 +00:00
Justin Clark-Casey (justincc)
5c305494ae simplify operation of OdeScene._perloopContact 2011-11-28 15:53:19 +00:00
Justin Clark-Casey (justincc)
4b2b0d4a05 don't bother locking OdeScene._perloopContact in single threaded code 2011-11-28 15:53:11 +00:00
Justin Clark-Casey (justincc)
61848ebe0d don't lock OdeScene.contacts since only ever accessed by a single thread 2011-11-28 15:53:04 +00:00
Justin Clark-Casey (justincc)
f48431345b rename ODECharacter.AvatarGeomAndBodyCreation() -> CreateOdeStructures() to match existing DestroyOdeStructures() 2011-11-28 15:52:53 +00:00
Justin Clark-Casey (justincc)
9c4597a00f refactor: Eliminate one line ODECharacter.doForce() method for code clarity 2011-11-28 15:49:37 +00:00
Justin Clark-Casey (justincc)
b528150d16 Comment out calls to OdeScene.waitForSpaceUnlock() since that method does nothing right now 2011-11-28 15:42:36 +00:00
Justin Clark-Casey (justincc)
4a99619bc0 Reduce complexity of OdeScene.Simulate() by fully removing bad characters at point of detection rather than later on. 2011-11-28 15:42:21 +00:00
Justin Clark-Casey (justincc)
5bd27b7b22 move geom/actor map maintenance into DestroyODEStructures()/AvatarGeomAndBodyCreation().
This saves us having to do it separately when a character capsule size is changed
2011-11-28 15:38:50 +00:00
Justin Clark-Casey (justincc)
8ea97cc608 When changing avatar size in ODE, remove the old actor from the name and actor maps 2011-11-28 15:38:42 +00:00
Justin Clark-Casey (justincc)
1850b778e2 When an ODECharacter is removed (e.g. when an avatar leaves a scene), remove the actor reference in OdeScene.actor_name_map rather than leaving it dangling.
This also largely centralizes adds/removes in OdeScene.AddCharacter()/RemoveCharacter()
2011-11-28 15:37:57 +00:00
Justin Clark-Casey (justincc)
5cd33f5e21 Have ODECharacter and ODEPrim both use PhysicsActor.Name instead of maintaining their own properties 2011-11-28 15:37:49 +00:00
Justin Clark-Casey (justincc)
cd3d5379d6 Actually remove PhysicsActor.SOPDescription this time 2011-11-28 15:37:04 +00:00
Justin Clark-Casey (justincc)
58021b5300 Chain SOP constructors together rather than having copy/paste code 2011-11-28 15:36:53 +00:00
Justin Clark-Casey (justincc)
3b141e5eee refactor: Make SOP.Description an automatic property 2011-11-28 15:34:29 +00:00
Justin Clark-Casey (justincc)
08bc6622dd Remove unused PhysicsActor.SOPDescription 2011-11-28 15:30:00 +00:00
Justin Clark-Casey (justincc)
c253539c04 Instead of generating a new list for bad characters on every physics pass, keep reusing the same list. 2011-11-28 15:29:51 +00:00
Justin Clark-Casey (justincc)
f3b45be9c0 Move DeleteScriptsOnStartup switch from [Startup] to [XEngine] in OpenSim.ini.example.
If anybody was changing this and wondering why there was no effect, this is why.
2011-11-28 15:29:38 +00:00
Justin Clark-Casey (justincc)
59c19110e4 Remove the "[LOCAL SIMULATION CONNECTOR]: Did not find region {0} for SendCreateChildAgent" message
This is misleading since a simulator will call this method before successfully trying remote regions.
Also comments out spammy "[SIMULATION]: Stream handler called" AgentHandlers messages for now.
2011-11-28 15:28:35 +00:00
Justin Clark-Casey (justincc)
7c03fba3fc minor: Make HelloNeighbour messages more informative 2011-11-28 15:28:28 +00:00
Justin Clark-Casey (justincc)
2593a446ac Get rid of the spurious [WEB UTIL] couldn't decode <OpenSim agent 57956c4b-ff2e-4fc1-9995-613c6256cc98>: Invalid character 'O' in input string messages
These are just the result of an attempt to canonicalize received messages - it's not important that we constantly log them.
Also finally get the deregister grid service message working properly
2011-11-28 15:28:14 +00:00
Justin Clark-Casey (justincc)
011c1279f5 Enable v2/v3 map tile url setting on robust as default in config
This is necessary to see map tiles on v2/v3 viewers and appears to work fine
2011-11-28 15:28:05 +00:00
Justin Clark-Casey (justincc)
25133cbdf6 Remove mono compiler warnings. Fix problem with co-ordinate given in deregister region message 2011-11-28 15:27:53 +00:00
Justin Clark-Casey (justincc)
06ed824711 Improve some grid region log messages to express regions at co-ordinate (e.g. 1000, 1000) rather than meter positions (256000, 256000) 2011-11-28 15:27:43 +00:00
Justin Clark-Casey (justincc)
63aa448608 improve region deregistration log message 2011-11-28 15:27:36 +00:00
justincc
4afb773399 Replace HttpServer_OpenSim.dll with Oren Hurvitz's patch applied.
This will hopefully address mantis 5471, 5694 and 5718.
This code is now in opensim-libs, along with Diva's slightly older patches (which were already applied to the DLLs in the opensim tree).
Thanks Oren!
2011-11-28 15:23:11 +00:00
Justin Clark-Casey (justincc)
dafe65ad81 Turn the [RegionReady] module on by default and login_disable = true while scripts are loading.
From field experience, we know that simulators can be unstable if a user logs in before the scripts have finished loading.
This commit turns login_disable = true in [RegionReady] on by default which prevents this from happening.
If you want the old behaviour, please copy these section from OpenSimDefaults.ini into OpenSim.ini and set login_disable = false
2011-11-28 15:23:01 +00:00
Justin Clark-Casey (justincc)
b107a8ec2a Turn SellEnabled in the [EconomyModule] on by default.
This only provides enough functionality to allow operations for no money (e.g. sell for $0).
2011-11-28 15:22:51 +00:00
Justin Clark-Casey (justincc)
e31d7fe424 minor: remove some mono compiler warnings 2011-11-17 23:55:45 +00:00
justincc
cc9888f28b Fix Windows build break 2011-11-17 23:40:45 +00:00
Justin Clark-Casey (justincc)
fef3baf107 For TerrainModule.SaveToFile(), don't bother throwing the exception onwards after printing out the error, since this method is invoked by users.
Still throwing the exception on the stream method since this invoked programatically
2011-11-17 23:24:58 +00:00
Justin Clark-Casey (justincc)
123322569d Make "terrain save" more friendly by telling the user if we have saved and putting out a useful complaint message if we haven't for some reason 2011-11-17 23:24:50 +00:00
Justin Clark-Casey (justincc)
8c0d8e72aa If the entire simulator is shutting down then don't bother to unload the scripts from the appdomain in XEngine.
All the other actions (script state save, etc.) still occur.
This makes shutdown where there are many scripts vastly quicker.
2011-11-17 23:24:43 +00:00
Justin Clark-Casey (justincc)
1e69845869 Make tracked per scene thread names conform to the majorirty format.
This is <thread-name> (<region-name>)
2011-11-17 23:24:23 +00:00
Justin Clark-Casey (justincc)
1bc0d0fac6 improve formatting of "show threads" 2011-11-17 23:24:05 +00:00
Justin Clark-Casey (justincc)
f7b5d17aa2 send a watchdog heartbeat for a poll worker thread when it's actually run 2011-11-17 23:23:57 +00:00
Justin Clark-Casey (justincc)
85170f5d5d distinguish between FriendsSimConnector and FriendsServiceConnector in log 2011-11-17 23:23:48 +00:00
Justin Clark-Casey (justincc)
66863fdd34 Add number of milliseconds since last update to "show threads" 2011-11-17 23:23:42 +00:00
Justin Clark-Casey (justincc)
6b0553ed7c Dont' bother with a userAgentService != null check right after we've constructed it 2011-11-17 23:23:35 +00:00
Justin Clark-Casey (justincc)
57cffcd1ec Remove prebuild reference to now gone PumaCode.SvnDotNet.dll 2011-11-17 23:23:06 +00:00
Justin Clark-Casey (justincc)
78739067d1 Remove unused RegionCommsListener/IRegionCommsListener.
All this is now being handled through IEntityTransferModule and SimulationService instead, and has been for some time.
2011-11-17 23:22:57 +00:00
Justin Clark-Casey (justincc)
310c2403b0 remove SceneCommunicationService.OnAvatarCrossingIntoRegion. This stuff is not being used any more - it's now IEntityTransferModule and SimulationService instead 2011-11-17 23:22:48 +00:00
Justin Clark-Casey (justincc)
a88381ba82 Rename FetchFriendslist() -> CacheFriends() and RefetchFriends() -> RecacheFriends() to reflect their intended function 2011-11-17 23:22:27 +00:00
Justin Clark-Casey (justincc)
1fa0c2f9b0 refactor: rename m_NeedsListOfFriends => m_NeedsListOfOnlineFriends to better reflect its actual function 2011-11-17 23:22:16 +00:00
Justin Clark-Casey (justincc)
1069390b3e For clients that are entering a simulator from initial login, stop executing FriendsModule.FetchFriendslist() asychronously.
Executing this asynchronously allows a race condition where subsequent friends fetches hit a cache that FetchFriendsList() had not yet populated.
Changing this to synchronous may improve issues where a user does not see friends as online even though they are.
I don't believe synchronous is a problem here, but if it is, then a more complicated signalling mechanism is required.  Locking the cache isn't sufficient.
2011-11-17 23:22:07 +00:00
Justin Clark-Casey (justincc)
3068cc3618 refactor: Don't create a new UUID for passing uuids to client - UUIDs are structs are so not passed by reference (and they're immutable!) 2011-11-17 23:21:59 +00:00
Justin Clark-Casey (justincc)
b5a69833f8 Add test for removing a friendship. 2011-11-17 23:21:40 +00:00
Justin Clark-Casey (justincc)
8b5bacc78b Improved method doc for AddFriend() - it actually does set up a two-way relationship.
Rename IFriendsModule.AddFriend() to AddFriendship()
2011-11-17 23:21:27 +00:00
Justin Clark-Casey (justincc)
8f7f03e7fd Add test for adding a friend whilst online 2011-11-17 23:20:47 +00:00
Justin Clark-Casey (justincc)
80bea38c07 Add very simple FriendsModuleTests.TestNoFriends() 2011-11-17 23:20:36 +00:00
Justin Clark-Casey (justincc)
9742491a63 doh - correct build break 2011-11-17 23:18:45 +00:00
Justin Clark-Casey (justincc)
acad65a832 Add threads to the watchdog thread list before we start them.
Hopefully this wil make "WATCHDOG: Asked to update thread ## which is not being monitored" messages." go away.
2011-11-17 23:18:35 +00:00
Justin Clark-Casey (justincc)
b527901556 As with prim sitting avatars, make an avatar phantom when it sits on the ground and solid again when it stands.
This is to avoid http://opensimulator.org/mantis/view.php?id=5783 when a collision with a ground sitting avatar causes that avatar to automatically stand and sometimes not be able to move
A better solution may be to keep gound sitting avatars solid but remove their collision status.  However, this requires some physics code work.
2011-11-17 23:18:24 +00:00
Justin Clark-Casey (justincc)
3c9654d5d6 Bump warp sit distance up to 10 meters, as discussed on opensim-dev mailing list last week.
This means that if the avatar is within 10 meters of the selected target, it sits on it immediately without walking.
Existing autopilot outside this range will be disabled in a later commit
2011-11-17 22:48:10 +00:00
Justin Clark-Casey (justincc)
4be42b3f75 Get some hopefully more useful exception information when OpenJPEG.EncodeFromImage() fails in VectorRender and DynamicTexture modules 2011-11-02 19:08:01 +00:00
Justin Clark-Casey (justincc)
6a994f8c9c Fix race condition that would sometimes send or save appearance for the wrong avatar.
In AvatarFactoryModule.HandleAppearanceUpdateTimer(), we loop through appearance save and send requests and dispatch via a FireAndForget thread.
If there was more than one request in the save or send queue, then this led to a subtle race condition where the foreach loop would load in the next KeyValuePair before the thread was dispatched.
This gave the thread the wrong avatar ID, leaving some avatar appearance cloudy since appearance data was never sent.
This change loads the fields into local references so that this doesn't happen.
2011-11-02 19:07:56 +00:00
Justin Clark-Casey (justincc)
f9e6e32ce2 Catch any exceptions exiting the top of the robust console, as we already do for the main simulator.
This prevents issues such as transient mono console problems from crashing the server.
2011-11-02 19:00:56 +00:00
Melanie
6bbf4fdc0f Plug a security hole in the inventory service 2011-11-02 18:59:54 +00:00
Dan Lake
10aee2f0ec Fix line endings 2011-11-02 18:59:47 +00:00
Dan Lake
0ed6149463 Experimental reorder of Heartbeat loop now simulates physics and sends updates to clients prior to sleep. Existing behavior was to sleep BEFORE sending updates. We found this patch reduced latency to clients by 1-2 heartbeat periods. 2011-11-02 18:59:38 +00:00
Justin Clark-Casey (justincc)
a64be59c3b Add missing max_listens_per_region to [LL_Functions] config section in OpenSimDefaults.ini + explanation.
This setting controls the maximum number of listeners in a region
2011-11-02 18:59:30 +00:00
Justin Clark-Casey (justincc)
b720454950 Remove the SyncRoot locking from Scene which was only being done around the main physics loop and ScenePresence position and velocity setting
This is no longer necessary with ODECharacter taints (ODEPrim was already not taking part in this).  BSCharacter was already tainting.
2011-11-02 18:57:04 +00:00
Justin Clark-Casey (justincc)
dd3dc5cd91 Add taint target velocity for ODECharacters as is already done for ODECharacter position and position and velocity for ODEPrims.
This is to help stop surprises if the velocity is set in the middle of physics calculations, though this probably isn't a huge problem.
It's more for consistency and for the next step of removing some scene locks
2011-11-02 18:51:55 +00:00
Justin Clark-Casey (justincc)
9cd94ac6ec tidy up OdeCharacter so that we just use OpenMetaverse.Vector3 assignment directly where possible, instead of transferring X, Y and Z components separately
some of this is probably a hold over from using ODE.Vector3, which is still necessary in some places.
2011-11-02 18:51:46 +00:00
Justin Clark-Casey (justincc)
2cc49d7d9a Move position set from taint to logically better position at top of ODECharacter.ProcessTaints() though this makes no practical difference 2011-11-02 18:51:31 +00:00
Justin Clark-Casey (justincc)
69e11af475 Stop setting _position as well as m_taint_position in ODECharacter.Position
setting position at the same time as taint appears to undermine the whole purpose of taint
testing doesn't reveal any obvious regressions in doing this
2011-11-02 18:51:20 +00:00
Dan Lake
aa6915f1ba Continuation of previous checkin. Found more places where ForEachScenePresence can be changed to ForEachRootScenePresence. 2011-11-02 18:50:17 +00:00
Dan Lake
b36ff0fd24 Added new ForEachRootScenePresence to Scene since almost every delegate passed to ForEachScenePresence checks for !IsChildAgent first. It consolidates child and root handling for coming refactors. 2011-11-02 18:48:21 +00:00
Justin Clark-Casey (justincc)
a16c9206b4 For now, comment out error message on new script engine console commands.
This causes false positives if a simulator has more than 1 region and the current region is 'root' since this sends the command separately to each region and each region has its own XEngine
2011-10-28 22:19:46 +01:00
Justin Clark-Casey (justincc)
b5b2541d1a Comment out inventory folder bulk update code on InventoryAccepted message introduced in commit db91044 on Aug 22 2011
This should be unecessary since the folder update is already made at the time of the offer (and moved to trash if not accepted).
This code was also not taking into account the situation where an item was accepted.
Needs more fixing if this results in an aggression elsewhere.
2011-10-28 22:19:36 +01:00
Justin Clark-Casey (justincc)
1baadac59a Don't blow our brains out if LLClientView.BulkInventoryUpdate() is wrongly passed a null node reference.
Addresses worst aspect of http://opensimulator.org/mantis/view.php?id=5752
2011-10-28 22:19:26 +01:00
Justin Clark-Casey (justincc)
88ef35cb23 Fix a bug I introduced yesterday in ODE physics where prim scripts would only receive the very first collision. 2011-10-28 22:19:17 +01:00
Justin Clark-Casey (justincc)
05dff4987b Restart the event queue worker threads that I accidentally disabled earlier today in 8a0a78c.
Also adds these to the watchdogs with very large timeouts (should really be infinite)
2011-10-28 22:19:04 +01:00
Justin Clark-Casey (justincc)
e1e0f20c7f In Watchdog, add ability to specific timeout for a thread.
This also changes the point of registration to the StartThread() call rather than the first Update()
2011-10-28 22:18:56 +01:00
Justin Clark-Casey (justincc)
70d559d1af Add m_threads dictionary locking to Watchdog.GetThreads() 2011-10-28 22:18:48 +01:00
Justin Clark-Casey (justincc)
6c92b48143 Clear OdeCharacter CollisionEventUpdate when we subscribe or unsubscribe from collision events 2011-10-28 22:18:42 +01:00
Justin Clark-Casey (justincc)
127626edd8 Remove unused fields from CollisionEventUpdate 2011-10-28 22:18:35 +01:00
Justin Clark-Casey (justincc)
aba26c098d Get rid of the pointless null checks on collision listeners. Add warning about synchronicity for PhysicsActor.OnCollisionUpdate event doc 2011-10-28 22:18:23 +01:00
Justin Clark-Casey (justincc)
9f19405490 When sending object collision updates, don't null out and recreate the CollisionEventUpdate() if the number of collisions falls to zero. Reuse the existing one instead. 2011-10-28 22:18:17 +01:00
Justin Clark-Casey (justincc)
871f1d0ae7 For ScenePresence collision events, instead of creating a new CollisionEventsThisFrame every time we need to send some new ones, reuse the existing one instead.
This assumes that the listener is using the data synchronously, which is currently the case.
2011-10-28 22:18:11 +01:00
Justin Clark-Casey (justincc)
057b78bfbe Fix bug where collision event listeners were not removed once the listener had gone away.
This was causing continuous use of temporary memory even when all avatars had left the scene.
Memory does leak but it does cause more calls to the garbage collector, which would pause the scene thread for a very short while during collection.
2011-10-28 22:18:03 +01:00
Justin Clark-Casey (justincc)
d4fc07aae1 minor: rename a parameter in OdeScene.Simulate() from actor -> prim since it's an OdePrim 2011-10-28 22:17:55 +01:00
Justin Clark-Casey (justincc)
750e8ec3da Add new LindenCaps test dll to panda run as well as "nant test" 2011-10-28 22:17:44 +01:00
Justin Clark-Casey (justincc)
15142093ad minor: add "threads show" as synonym for "show threads" for consistency 2011-10-28 22:17:32 +01:00
Justin Clark-Casey (justincc)
f050f0fc0b Add "threads abort <thread-id>" simulator console command that allows us to abort a watchdog managed thread.
This is for diagnostic purposes.
2011-10-28 22:17:20 +01:00
Justin Clark-Casey (justincc)
a3c79b399e Make OpenSim.Framework.Servers.HttpServer rely on OpenSim.Framework instead of the other way around.
This is necessary so that code in HttpServer can use framework facilities such as the thread watchdog for monitoring purposes.
Doing this shuffle meant that MainServer was moved into OpenSim/Framework/Servers
Also had to make OpenSim.Framework.Console rely on OpenSim.Framework rather than the other way around since it in turn relies on HttpServer
MainConsole and some new interfaces had to be moved into OpenSim/Framework to allow this.  This can be reverted if parts of OpenSim.Framework stop relying on console presence (cheifly RegionInfo)
2011-10-28 22:17:10 +01:00
Justin Clark-Casey (justincc)
424735efee separate out future common setup code from EventQueueTests.AddForClient() 2011-10-28 22:16:49 +01:00
Justin Clark-Casey (justincc)
d5dfbc3844 Add new EventQueueTests with basic test to check that adding a client registers an http poll 2011-10-28 22:16:31 +01:00
Justin Clark-Casey (justincc)
c3127d1323 Remove earlier mistaken addition of EventQueueTests.cs 2011-10-28 22:15:03 +01:00
Justin Clark-Casey (justincc)
03c98c3b8f Fix bugs in EventQueueGetModule.ClientClosed() and BaseHttpServer.RemovePollServerHTTPHandler() that stopped existing code in ClientClosed() from actually tearing down the poll handler
Actually doing the tear down appear to have no ill effects with region crossing and teleport.
2011-10-28 22:09:53 +01:00
Justin Clark-Casey (justincc)
24e02afeac Comment out the uuid gatherer lines that I accidentally left in. 2011-10-28 22:02:54 +01:00
Justin Clark-Casey (justincc)
8d5606e09b Rename some of the example commented out server names to mygridserver.com like all the others.
This is to make it easier to change all these names at once, where all grids services are running from the same location.
Also rearranges some lines in [Modules] so that StandaloneCommon.ini.example and GridCommon.ini.exmaple are consistent.
2011-10-28 22:02:43 +01:00
Justin Clark-Casey (justincc)
bd3d119a03 Make config comments about choosing assetcache modules clearer.
OpenSim needs an asset cache.  Running without one will cause problems.
Thanks to Ai Austin for the suggestions in http://opensimulator.org/mantis/view.php?id=4850
2011-10-28 22:02:37 +01:00
Justin Clark-Casey (justincc)
cf2405385d Get UUIDGatherer to scan notecards in the graph for asset uuids.
This is to support npc baked texture saving in oars and iars.
May address http://opensimulator.org/mantis/view.php?id=5743
2011-10-28 22:02:25 +01:00
Justin Clark-Casey (justincc)
a6eba09dac redirect UserInventoryHelpers to use a different CreateNotecardAsset() so we can comment out some inconsistency 2011-10-28 22:02:18 +01:00
Justin Clark-Casey (justincc)
b2ca7c0927 correct misleading method doc on CreateNotecardAsset() 2011-10-28 22:02:09 +01:00
Justin Clark-Casey (justincc)
dd6c236253 in AssetHelpers, store the actual text passed in to the method, not the string "data" 2011-10-28 22:02:02 +01:00
Justin Clark-Casey (justincc)
b2ff680cca encode notecard assets in proper format for tests, rather than just using whatever string is given 2011-10-28 22:01:54 +01:00
Justin Clark-Casey (justincc)
23a9a7daa7 refactor: rename some AssetHelpers.CreateAsset() methods to CreateNotecardAsset() 2011-10-28 22:01:47 +01:00
Justin Clark-Casey (justincc)
19fde57fca Change wording on asset requests.
Not all 'notified missing' assets are a problem.  Some are invalid references which happen to be buried in other text.
2011-10-28 21:59:53 +01:00
Justin Clark-Casey (justincc)
a556930456 Store scene identifier passed in to OdeScene for later debug messages 2011-10-28 21:58:30 +01:00
Justin Clark-Casey (justincc)
1a008b237b Don't bother taking OdeLock during OdeScene construction, since there can be no contention until the object is constructed. 2011-10-28 21:58:21 +01:00
Justin Clark-Casey (justincc)
d6456b9ea8 Remove unnecessary lock of OdeLock in OdePrim.changeadd()
This taint can only ever be processed from the OdeScene.Simulate() loop, which already locks OdeLock.
2011-10-28 21:58:12 +01:00
Justin Clark-Casey (justincc)
5980d57b7a minor: method doc to explain a lock of OdeLock 2011-10-28 21:58:01 +01:00
Justin Clark-Casey (justincc)
7c409eff53 Remove the unused CollisionLocker from ODE
Despite its name, this wasn't actually being used in any collision checking
2011-10-28 21:56:04 +01:00
Justin Clark-Casey (justincc)
614ea5a48a refactor: Use SOP.SitTargetAvatar instead of calling a special GetAvatarOnSitTarget() which returned exactly the same thing 2011-10-28 21:47:08 +01:00
Justin Clark-Casey (justincc)
8905f34e18 rename OS_NPC_SIT_IMMEDIATE to OS_NPC_SIT_NOW since it's shorter and more understandable
This makes something like osNpcSit(npc, llGetKey(), OS_NPC_IMMEDIATE) now become
osNpcSit(npc, llGetKey(), OS_NPC_SIT_NOW);
This is why it's in development :)
2011-10-28 21:47:00 +01:00
Justin Clark-Casey (justincc)
380f2a1719 Implement osNpcStand(<npc-id>)
Allows you to stand an NPC that has sat.
2011-10-28 21:46:53 +01:00
Justin Clark-Casey (justincc)
1c66e08964 Implement osNpcSit(). This is still in development so don't trust it
Format is osNpcSit(<npc-uuid>, <target-uuid>, OS_NPC_SIT_IMMEDIATE)
e.g. osNpcSit(npc, llGetKey(), OS_NPC_SIT_IMMEDIATE);
At the moment, sit only succeeds if the part has a sit target set.
NPC immediately sits on the target even if miles away - they do not walk up to it.
This method is in development - it may change so please don't trust it yet.
Standing will follow shortly since that's kind of important once you're sitting :)
2011-10-28 21:46:36 +01:00
Justin Clark-Casey (justincc)
af564291f2 improve method doc on Scene.OtherRegionUp()
this is really just to trigger panda.
2011-10-28 21:45:58 +01:00
Justin Clark-Casey (justincc)
250eed5141 move see_into_this_sim_from_neighbor [Startup] flag parsing into Scene with the others 2011-10-28 21:45:50 +01:00
Justin Clark-Casey (justincc)
a2c9b3d83d fetch physical_prim switch from [Startup] config from inside scene, as is done for most other scene config params 2011-10-28 21:45:41 +01:00
Justin Clark-Casey (justincc)
3a047b2bdb Restore [Startup] physical_prim flag which can stop any prims being subject to physics
This had stopped working.  However, at the moment it still allows the physics flag to be set even though this has no effect.  This needs to be fixed.
Default for this flag is true as previously.
2011-10-28 21:45:00 +01:00
Justin Clark-Casey (justincc)
f8deca7f2d remove redundant PhysActor.IsPhysical call from SOP.UpdatePrimFlags() as its done immediately afterwards in DoPhysicsPropertyUpdate() 2011-10-28 21:44:52 +01:00
Justin Clark-Casey (justincc)
63a6bc93e4 refactor: Remove redundant code in SOP.UpdatePrimFlags() 2011-10-28 21:44:44 +01:00
Justin Clark-Casey (justincc)
50c340ef35 factor common code out into SOP.RemoveFromPhysics() 2011-10-28 21:44:36 +01:00
Justin Clark-Casey (justincc)
41e7e613a2 reduce access to ODECharacter methods to make code analysis easier. Eliminate redundant argument on ProcessTaints() 2011-10-28 21:44:28 +01:00
Justin Clark-Casey (justincc)
4d1ab38068 restrict unnecessary access levels on ODEPrim fields/properties 2011-10-28 21:44:20 +01:00
Justin Clark-Casey (justincc)
47c412ca1e refactor: make methods that do not need to be public in ODE private or internal to aid code reading/analysis. Remove some unused method arguments 2011-10-28 21:44:12 +01:00
Justin Clark-Casey (justincc)
acb0a5b6c1 refactor: rename IClientAPI.SendPrimUpdate() to SendEntityUpdate() since it sends entity updates (including presence ones), not just prims. 2011-10-28 21:43:39 +01:00
Justin Clark-Casey (justincc)
1b8716a99a Get rid of some traces of the old pre-ROBUST grid architecture config 2011-10-28 21:41:48 +01:00
Justin Clark-Casey (justincc)
9edbb4f77a Bring LindenUDP.Tests back from the dead. No tests are running.
Code drift means that most of this stuff doesn't compile but the structure is still useful.

Conflicts:

	OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLPacketServer.cs
2011-10-28 21:40:53 +01:00
Justin Clark-Casey (justincc)
753f11273f re-enable running linden udp tests in local.include, though no tests are currently active there 2011-10-28 21:31:44 +01:00
Justin Clark-Casey (justincc)
435aefe1bf Drop some unnecessary ContainsKey() checking before Remove() in BaseHttpServer()
Remove() presumably does this check anyway since it just returns false if the key is not in the collection.
2011-10-28 21:30:36 +01:00
Justin Clark-Casey (justincc)
e5286b7b7c Fix bugs in EventQueueGetModule.ClientClosed() and BaseHttpServer.RemovePollServerHTTPHandler() that stopped existing code in ClientClosed() from actually tearing down the poll handler
Actually doing the tear down appear to have no ill effects with region crossing and teleport.
2011-10-28 21:29:44 +01:00
Justin Clark-Casey (justincc)
aa4637db47 Add optional getauthinfo and setauthinfo authentication service calls.
These are disabled by default, as before.  Please only turn these on in secure grids, since they allow the same facilities as the existing SetPassword call (also disabled by default)
These facilities can be helpful when integrating external systems, in addition to the existing option of adapting an IAuthenticationService or using WebLoginKey
2011-10-24 23:28:02 +01:00
Justin Clark-Casey (justincc)
73c201449f very minor removal of old commented out line of code in OdeScene 2011-10-21 00:08:59 +01:00
Justin Clark-Casey (justincc)
36be226dc8 remove unnecessary null check on _collisionEventPrim 2011-10-21 00:08:45 +01:00
Justin Clark-Casey (justincc)
ea5d1d0ff0 Get OdeScene to use passed in time step rather than hard-coded 0.089
However, I still don't recommend changing MinFrameTime from 0.089, high values do not work well and lower values don't seem to make much difference
2011-10-21 00:08:32 +01:00
Justin Clark-Casey (justincc)
299cc2d12d Pass PhysicsScene.Simulate() only the MinFrameTime rather than the useless Math.Max(SinceLastFrame.TotalSeconds, MinFrameTime)
SinceLastFrame was calculating the interval between any sleep that had occurred to pad out the frame time and the start of the next frame.
This would usually be below MinFrameTime but occasionally if the sleep was long it would be above, often due to the time required to update the watchdog.
This doesn't appear to play much practical role right now.
ODE was actually ignoring it entirely.  Bullet might be helped slightly by receiving a non-varying value.
2011-10-21 00:06:20 +01:00
Justin Clark-Casey (justincc)
4ecd3fbff1 For now, stop passing timeStep into methods where it's not actually used. 2011-10-21 00:06:13 +01:00
Justin Clark-Casey (justincc)
1b32d5c6a4 Extend scripts stop/start/suspend/resume console commands to allow action on a single script by giving the script item id (which can be found via scripts show).
Not an ideal way to do this on a region with many scripts.  Needs refinement later.
2011-10-19 23:03:59 +01:00
Justin Clark-Casey (justincc)
c404760731 Add "scripts stop" and "scripts start" console commands.
These will stop all running scripts and start all stopped scripts respectively.
A stopped script does not save any events for later processing.
2011-10-19 23:03:28 +01:00
Justin Clark-Casey (justincc)
7d4e224620 minor: improve command help on scripts suspend/resume 2011-10-19 23:03:22 +01:00
Justin Clark-Casey (justincc)
986ded5a72 Fix resume scripts.
On resume, we need to place requeue the script for event processing if there are any events on the queue.
Also need to do this under m_Script lock in order to avoid a race
2011-10-19 23:03:14 +01:00
Justin Clark-Casey (justincc)
8340bd7e20 Add "scripts suspend" and "scripts resume" commands.
These aim currently to suspend and resume all scripts.
However, resume isn't currently working due to what looks like a bug in resume functionality itself.
2011-10-19 23:03:05 +01:00
Justin Clark-Casey (justincc)
9d59fc0587 on log and "show scripts" messages, show script item UUID rather than asset UUID
The item ID is the one required for any script manipulation on the command line, so I think it's somewhat more useful to show this bearing in mind the limited space available
2011-10-19 23:02:56 +01:00
Justin Clark-Casey (justincc)
22e1298e97 add current script status to "scripts show" command (running, suspended, etc.) 2011-10-19 23:02:50 +01:00
Justin Clark-Casey (justincc)
1a29ddf328 Add "show scripts" command to show all scripts currently known to the script engine in the current region.
Also added synonym of "scripts show"
2011-10-19 23:02:43 +01:00
Justin Clark-Casey (justincc)
8a2c3a0267 Add option to allow remote http calls to setpassword in the AuthenticationService.
This is switched on by setting AllowSetPassword = true in the [AuthenticationService] section of Robust.ini or Robust.HG.ini
Default is false as before.
2011-10-19 23:02:36 +01:00
Justin Clark-Casey (justincc)
ea65d4f5ce Make ScopeID optional for http GetAccount and GetAccounts
If not specified then it assumes UUID.Zero. as occurs elsewhere in the codebase
2011-10-19 00:36:49 +01:00
Justin Clark-Casey (justincc)
eb65f5072d Make PrincipalID a synonym for UserID in GetUserAccount 2011-10-19 00:36:38 +01:00
Justin Clark-Casey (justincc)
aad13a4c76 Get new NewUser and SetUserAccount calls to accept PrincipalID instead of UserID for consistency with output 2011-10-19 00:36:31 +01:00
Justin Clark-Casey (justincc)
233127c696 Allow an http call to set account details if AllowSetAccount = true in [UserAccountService].
As before, default is false to not allow these calls.
2011-10-19 00:36:24 +01:00
Justin Clark-Casey (justincc)
b7fcd6871e Provide an option to allow remote calls to the CreateUser method on the UserAccountService
Default is false, as before.
Enabling AllowCreateUser in [UserAccountService] for ROBUST allows avatars to be created via an http call, with viewer 2 appropriate bits and pieces.
Only Ruths can be created at present.
Please don't rely on the config since at some point CreateUser will be moved to a separate co-ordinating service.
2011-10-18 22:56:43 +01:00
Justin Clark-Casey (justincc)
c06cd3b2b9 Allow an avatar to be explicitly named to the "debug packet" command 2011-10-17 21:12:00 +01:00
Justin Clark-Casey (justincc)
31ac7571f4 refactor: Make IClientAPI.DebugPacketFormat a property rather than a setter without a getter 2011-10-17 21:11:50 +01:00
Justin Clark-Casey (justincc)
2a7a5c4c90 Add avatar names to debug packet output 2011-10-17 21:11:43 +01:00
Justin Clark-Casey (justincc)
d8ad649957 Add back the missing bin/addon-modules directory that I somehow managed to accidentally delete in 2fbc98f (Jul 7 2011) 2011-10-17 21:11:04 +01:00
Justin Clark-Casey (justincc)
a1f232af2b change default ODE world_stepsize to 0.0178 from 0.02
This exactly fits five ODE steps in the default frame time (0.089).
This means that ODE execution time now matches the default minimum frame time.
This eliminates errors between distance travelled as calculated by ODE in clear air and simple extrapolation.
On the old values, ODE would actually do calculations over 0.1 seconds rather than 0.089.
This means that once the avatar is at top speed, no additional packets need to be sent for smooth movement, since no error develops between server and viewer.
This approach replaces the tweaks previously discussed on the opensim-dev mailing list
2011-10-17 21:10:52 +01:00
Justin Clark-Casey (justincc)
14bddb6af9 Change hardcoded ODE total frame time to match the default total frame time (0.09375 -> 0.089).
No apparant ill effects - because the default stepsize is 0.2, there are still 5 physics steps per physics frame.
This is a precursor to using the elapsed value passed in (and now changeable in config).
2011-10-17 21:10:43 +01:00
Justin Clark-Casey (justincc)
f93635fe85 Extract NullPhysicsScene from PhysicsScene to improve code readability 2011-10-17 21:10:25 +01:00
Justin Clark-Casey (justincc)
3a635507cc Don't execute rest of code in XEngine.RemoveRegion() and Close() if the module is disabled. 2011-10-17 21:10:17 +01:00
Justin Clark-Casey (justincc)
0506ccb51a Expose minimum frame time and update periods for experimentation.
Settings are at bottom of [Startup] in OpenSimDefaults.ini, override in OpenSim.ini to change
Defaults are the same as previously.
More information to come on opensim-dev shortly.
Feel free to tweak but if you do please don't expect any support unless feedback on certain tweaks is explicitly requested.
2011-10-17 21:09:56 +01:00
Justin Clark-Casey (justincc)
4bce90d0ab refactor: Put the frame update period when temporary objects are cleaned up in a field, like all the other update periods 2011-10-17 21:06:03 +01:00
Justin Clark-Casey (justincc)
4d93ab06c9 refactor: chain the two scene constructors together to eliminate more copypasta 2011-10-17 21:05:47 +01:00
Justin Clark-Casey (justincc)
e2c807a0d0 Tie reported FPS correction factor into the minimum frame time rather than setting separately.
This makes reported FPS scale as required if min frame time changes
2011-10-17 21:05:37 +01:00
Justin Clark-Casey (justincc)
23a9a98d5d Move fps stat adjustment factor into field rather than hard-coded. 2011-10-17 21:05:29 +01:00
Justin Clark-Casey (justincc)
32ba06a55c More method doc and formatting changes. Makes DestroyOdeStructures() private 2011-10-17 21:05:21 +01:00
Justin Clark-Casey (justincc)
64c42a729a refactor: move 3x copy/pasted ode structure removal code in ODECharacter into a DestroyOdeStructures() method
also adds some method doc
2011-10-17 21:05:12 +01:00
Justin Clark-Casey (justincc)
b342fb9c0a When shutting down XEngine, log how many scripts are being shutdown so the user knows why they are waiting. 2011-10-17 21:03:51 +01:00
Justin Clark-Casey (justincc)
3f70f54fa6 minor: insert some commented out log lines which are a blunt but useful instrument to see packet expiry and received acks 2011-10-17 21:03:41 +01:00
Justin Clark-Casey (justincc)
c4ce7b8162 Improve some method doc for LLUDPClient, LLUDPServer and UnackedPacketCollection 2011-10-17 21:03:30 +01:00
Justin Clark-Casey (justincc)
4c9226be7b Start recording object updates per second statistic (analogue of agent updates per secod) and expose via monitoring module as ObjectUpdatePerSecondMonitor
A useful diagnostic to find out how object updates are burdening a scene
2011-10-17 21:03:04 +01:00
Diva Canto
58f2c9e224 Bug fix on the bug fix on UserAccountService.cs 2011-10-16 16:14:43 -07:00
Diva Canto
8ba0cc470a Guard HGAssetService against uninitialized variables and null arguments. 2011-10-15 20:25:06 -07:00
Justin Clark-Casey (justincc)
2a654974c9 flip release flavour to post-fixes 2011-10-14 02:11:58 +01:00
Diva Canto
b72753dc81 Bug fix -- Test User on first run standalone might not be created properly: let all instances of UserAccountService have all its service references properly initialized, and register console commands on only one. 2011-10-13 18:09:20 -07:00
Justin Clark-Casey (justincc)
2ecfa29eb6 Allow monitoring of stats by region name 2011-10-11 00:07:08 +01:00
Justin Clark-Casey (justincc)
3678b8f1f7 Add other region stats (total frame time, physics fps, etc.) currently missing from MonitorModule
Unlike the other 3 stats mechanisms, monitor data can be queried per individual region, which makes this useful.
This doesn't affect an of the existing monitored stats.
2011-10-11 00:07:00 +01:00
Justin Clark-Casey (justincc)
29a62abc6d Convert getLastReportedSimFPS() and getLastReportedSimStats() into more idiomatic LastReportedSimFPS and LastReportedSimStats on SimStatsReporter 2011-10-11 00:06:51 +01:00
Justin Clark-Casey (justincc)
31ef2f9a2e Provide a way to turn the MonitorModule on and off
Default is currently on since this is the historical setting
2011-10-11 00:06:44 +01:00
Justin Clark-Casey (justincc)
21e3f8e53a refactor: have lsl and ossl interrogate scene.StatsReporter directly rather than going through scene
I know this goes against the law of demeter but I don't think it's that useful here and I'd rather get rid of nasty little wrapper methods
2011-10-11 00:06:36 +01:00
Justin Clark-Casey (justincc)
579aa9c6a0 Go back to lying that sim fps is 55 when it's actually locked at a maximum of 11.
We're been lying since 2008 so I'm sure another few years can't hurt.
To know the real fps, either divide sim fps by 5 and/or look at the frame time.
2011-10-11 00:06:09 +01:00
BlueWall
8b374daae9 Add note to docs
This method is used by externasl/3rd party management tools to
  create users and they depend on us to generate the UUID.
2011-10-11 00:05:54 +01:00
Justin Clark-Casey (justincc)
31d1b3310d remove the pointless slashes on the end of the (5!) different server stat retrieval mechanisms.
Original request URLs that end with / will still work, but this will allow one to type /simstatus as well as /simstatus/
Can't do this with webstats yet since it does insane things to the path.
2011-10-11 00:05:41 +01:00
Pixel Tomsen
d1711519a0 WebStats - Home Link Fix
http://opensimulator.org/mantis/view.php?id=4536
2011-10-11 00:05:31 +01:00
BlueWall
71fa970990 Added back UserAccount that creates random UUID for new account.
This should fix recent issues with 3rd party apps that use the
old interface w/o breaking the new one.
2011-10-11 00:05:15 +01:00
Justin Clark-Casey (justincc)
6fa4f88d39 Instead of adding stat agentMS in all kinds of places, calculate it instead in the main Scene.Update() loop, like the other stats
Some of the places where agentMS was added were in separate threads launched by the update loop.  I don't believe this is correct, since such threads are no longer contributing to frame time.
Some of the places were also driven by client input rather than the scene loop.  I don't believe it's appropriate to add this kind of stuff to scene loop stats.
These changes hopefully have the nice affect of making the broken out frame stats actually add up to the total frame time
2011-10-11 00:05:09 +01:00
Justin Clark-Casey (justincc)
9ff3d9221b Remove vestigal RegionStatus.SlaveScene.
This appears to be code clutter since the code that uses this has long gone.
2011-10-11 00:04:50 +01:00
Justin Clark-Casey (justincc)
3920e56dd4 Add user ID to new estate user prompt, to make it clearer and consistent with the main create user prompts 2011-10-11 00:03:52 +01:00
Justin Clark-Casey (justincc)
6700f1edd9 Make reported sim fps more accurate, in line with frame time ms
Also remove some unused fields and improve naming on others.
2011-10-11 00:03:35 +01:00
Justin Clark-Casey (justincc)
e6d1182dec When creating a new user on the comand line, give the option of allowing a UUID to be specified to override the randomly generated one.
This can be useful in some migration cases where recreating user accounts with known IDs will preserve region scene object ownership.
2011-10-11 00:03:22 +01:00
Justin Clark-Casey (justincc)
a3316f1eac For llGetTexture(), if the face texture asset is in the inventory, return the inventory name rather than the asset UUID
This is as per http://wiki.secondlife.com/wiki/LlGetTexture
Applied patch in http://opensimulator.org/mantis/view.php?id=4552 with an additional break statement if an inventory item is found to exit early.
Thanks Michelle Argus!
2011-10-11 00:02:43 +01:00
Pixel Tomsen
5f281716a9 llGetLinkKey, llGetLinkName Fix for sitting Avatar
when an avatar sits on a prim, we get now his key & name ;-)

http://opensimulator.org/mantis/view.php?id=4476
2011-10-11 00:02:21 +01:00
Pixel Tomsen
f90c3d0633 llAvatarOnLinkSitTarget Implementation
http://wiki.secondlife.com/wiki/LlAvatarOnLinkSitTarget
2011-10-11 00:02:12 +01:00
Justin Clark-Casey (justincc)
633d4f3e6e Correct DeleteScriptsOnRestart to DeleteScriptsOnStartup in comments in OpenSim.ini.example 2011-10-07 21:45:43 +01:00
Justin Clark-Casey (justincc)
43bbdbe760 flip rc2 to release 2011-10-07 21:29:51 +01:00
Justin Clark-Casey (justincc)
494e5867a3 Comment out [SCENE PRESENCE] SendAppearanceToAllOtherAgents: log message
As per earlier discussions with dslake
2011-10-07 21:15:37 +01:00
Justin Clark-Casey (justincc)
270f0d5ae3 Clarify explanation of DeleteScriptsOnStartup switch in [XEngine]. 2011-10-07 20:29:12 +01:00
Dan Lake
d079ee9ef1 Add execute permission to runprebuild2010.bat 2011-10-07 20:28:41 +01:00
Justin Clark-Casey (justincc)
cd46bf6fad Remove OpenSim.Region.Examples.SimpleModule
This module is more than 2 years old and at least some of the 'example' code it gives is now misleading.
Even the logs say it say some bits were broken where it was put in!
2011-10-07 20:28:23 +01:00
Justin Clark-Casey (justincc)
bb419044ef Add ability to pass in the permissions option (perm) to save oar via RemoteAdmin
Applies patch in http://opensimulator.org/mantis/view.php?id=5686
Thanks Michelle Argus!
2011-10-07 20:28:13 +01:00
Justin Clark-Casey (justincc)
549fdc8b11 copy config information on allow/disallow individual os functions into OpenSim.ini.example
I this is generally useful rather than a 'default' setting
2011-10-07 20:27:57 +01:00
Justin Clark-Casey (justincc)
550d1fea96 remove unused postgresql dll 2011-10-07 20:27:49 +01:00
Justin Clark-Casey (justincc)
94f49e859b Add en_US culture setting to the async delete to inventory thread, to avoid any issues with float serialization with machines set to non en_US locales.
Doing this to see if addresses inventory object deserialization problems in http://opensimulator.org/mantis/view.php?id=5708, though if it does I'm really surprised not to have seen it before now.
Really need to go through and systematically set the culture for every timer and change all BeginInvoke calls to FireAndForget instead.
But don't want to do something like that this close to a release.
2011-10-07 20:27:31 +01:00
Snoopy Pfeffer
c2586b0ea9 Fix for rezzing and derezzing HUDs (see Mantis #5406). From now on updates are only sent to affected clients. 2011-10-07 20:27:18 +01:00
Justin Clark-Casey (justincc)
2905288545 Remove the unimplented "clear assets" command.
This was a bizarre relic of a bygone age that had no implementations.
If you're using and want to clear the flotsam asset cache then please use the existing "fcache clear" command
2011-10-07 20:26:15 +01:00
Justin Clark-Casey (justincc)
353170589b Improve locking when access queue in EventQueueGetModule 2011-10-07 20:25:13 +01:00
Justin Clark-Casey (justincc)
ee78c4d2a8 Clarify explanation of the "DeleteScriptsOnStartup" config switch and add this to OpenSim.ini.example since it's very useful if you're not updating OpenSim from source.
On reflection, "DeleteScriptsOnStartup" isn't a great name since it suggests real script deletion rather than compiled versions.
2011-10-07 20:22:16 +01:00
Justin Clark-Casey (justincc)
084df4b7ef make distribution creating code to copy FlotsamCache.ini.example to FlotsamCache.ini 2011-10-07 20:22:08 +01:00
Justin Clark-Casey (justincc)
53ffc7ff8c bump version up to 0.7.2-rc2 2011-09-23 22:47:23 +01:00
Justin Clark-Casey (justincc)
d8d048cfa1 oops, reinstate the try catching of async_call_method but leave the logging disabled 2011-09-23 22:45:02 +01:00
Justin Clark-Casey (justincc)
a4e1d29e3c Catch but don't print out exceptions that make it to the top of the async_call_method stack.
This is not helpful for release code.
2011-09-23 22:40:34 +01:00
Justin Clark-Casey (justincc)
8c4dd6b330 Merge branch 'master' into 0.7.2-post-fixes 2011-09-23 22:36:20 +01:00
Justin Clark-Casey (justincc)
f1612997a6 Use a copy of the inventory items list to register users in the thread started by GetFolderContent(), to protect ourselves against callers modifying lists
Hopefully this addresses http://opensimulator.org/mantis/view.php?id=5681
2011-09-09 01:00:41 +01:00
Justin Clark-Casey (justincc)
c574c80011 Fix unit tests from RegionSettings commit 2011-09-09 00:47:52 +01:00
Justin Clark-Casey (justincc)
9f76bc4fff Save the default terrain texture UUIDs for a new region instead of leaving them as UUID.Zero.
Leaving them at UUID.Zero meant that when a viewer 2 logged into a region that had been freshly created, it received UUID.Zero for these textures, and hence display the land as plain white.
On a simulator restart, the problem would go away since when the database adapators loaded the new region settings, RegionSettings itself has code to use default textures instead of UUID.Zero.
This commit resolves the problem by saving the default texture UUIDs instead of Zero.
However, we currently have to do this in a roundabout way by resaving once the RegionSettings have been created by the database for the first time.  This needless complexity should be addressed.
This change will also have the effect of replacing any existing UUID.Zero terrain textures with the default ones.
However, this shouldn't have any effect since the UUID.Zeros were already being replaced in memory with those same UUIDs.
2011-09-09 00:29:59 +01:00
Justin Clark-Casey (justincc)
79f3de6ba8 change version to rc1 2011-09-08 22:16:42 +01:00
315 changed files with 18559 additions and 32733 deletions

21
.gitignore vendored
View File

@@ -1,6 +1,5 @@
.project
.settings
.gitignore
*.csproj
*.csproj.user
*.build
@@ -11,7 +10,6 @@
*.pidb
*.dll.build
*.dll
*.log
*.VisualState.xml
*/*/obj
*/*/*/obj
@@ -25,7 +23,6 @@
*/*/*/*/*/bin
*/*/*/*/*/*/bin
*/*/*/*/*/*/*/bin
addon-modules/
bin/Debug/*.dll
bin/*.dll.mdb
bin/*.db
@@ -73,20 +70,4 @@ TAGS
Makefile.local
bin/.version
compile.bat
addon-modules
OpenSim/Data/Tests/test-results/
OpenSim/Framework/Serialization/Tests/test-results/
OpenSim/Framework/Servers/Tests/test-results/
OpenSim/Framework/Tests/test-results/
OpenSim/Region/ClientStack/Linden/Caps/test-results/
OpenSim/Region/ClientStack/Linden/UDP/Tests/test-results/
OpenSim/Region/CoreModules/test-results/
OpenSim/Region/Framework/test-results/
OpenSim/Region/OptionalModules/test-results/
OpenSim/Region/Physics/BulletDotNETPlugin/
OpenSim/Region/Physics/Manager/test-results/
OpenSim/Region/Physics/OdePlugin/Tests/test-results/
OpenSim/Region/ScriptEngine/test-results/
OpenSim/Tests/Common/test-results/
OpenSim/Tests/test-results/
test-results/

View File

@@ -117,12 +117,10 @@
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindencaps.tests)==0}" />
<!--
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.clientstack.lindenudp.tests">
<arg value="./bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" />
-->
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.scriptengine.tests">
<arg value="./bin/OpenSim.Region.ScriptEngine.Tests.dll" />
@@ -341,7 +339,7 @@
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" />
<!-- <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" /> -->
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.scriptengine.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.coremodules.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" />

View File

@@ -12,7 +12,7 @@ Steps:
=== Building on Linux ===
Prereqs:
* Mono >= 2.4.3
* Mono >= 2.4.2
* Nant >= 0.85
* On some Linux distributions you may need to install additional packages.
See http://opensimulator.org/wiki/Dependencies for more information.

View File

@@ -5,7 +5,7 @@ for your effort!)
These folks represent the current core team for OpenSim, and are the
people that make the day to day of OpenSim happen.
* justincc (OSVW Consulting, justincc.org)
* justincc
* chi11ken (Genkii)
* dahlia
* Melanie Thielker
@@ -14,9 +14,7 @@ people that make the day to day of OpenSim happen.
* Marck
* Mic Bowman (Intel)
* BlueWall (James Hughes)
* Nebadon Izumi (Michael Cerquoni, OSgrid)
* Snoopy Pfeffer
* Richard Adams (Intel)
= Core Developers Following the White Rabbit =
Core developers who have temporarily (we hope) gone chasing the white rabbit.
@@ -83,7 +81,6 @@ what it is today.
* Gerhard
* Godfrey
* Grumly57
* GuduleLapointe
* Ewe Loon
* Fly-Man
* Flyte Xevious
@@ -104,7 +101,6 @@ what it is today.
* lulurun
* M.Igarashi
* maimedleech
* Mana Janus
* Mic Bowman
* Michelle Argus
* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
@@ -123,7 +119,6 @@ what it is today.
* openlifegrid.com
* Oren Hurvitz (Kitely)
* otakup0pe
* Pixel Tomsen
* ralphos
* RemedyTomm
* Revolution
@@ -136,7 +131,6 @@ what it is today.
* Salahzar Stenvaag
* sempuki
* SignpostMarv
* SpotOn3D
* Strawberry Fride
* tglion
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)

View File

@@ -30,7 +30,6 @@ using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.RegionLoader.Filesystem;
using OpenSim.Framework.RegionLoader.Web;
@@ -153,20 +152,9 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
/// <returns>True if we're sane, false if we're insane</returns>
private bool CheckRegionsForSanity(RegionInfo[] regions)
{
if (regions.Length == 0)
if (regions.Length <= 1)
return true;
foreach (RegionInfo region in regions)
{
if (region.RegionID == UUID.Zero)
{
m_log.ErrorFormat(
"[LOAD REGIONS PLUGIN]: Region {0} has invalid UUID {1}",
region.RegionName, region.RegionID);
return false;
}
}
for (int i = 0; i < regions.Length - 1; i++)
{
for (int j = i + 1; j < regions.Length; j++)
@@ -198,5 +186,35 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
return true;
}
public void LoadRegionFromConfig(OpenSimBase openSim, ulong regionhandle)
{
m_log.Info("[LOADREGIONS]: Load Regions addin being initialised");
IRegionLoader regionLoader;
if (openSim.ConfigSource.Source.Configs["Startup"].GetString("region_info_source", "filesystem") == "filesystem")
{
m_log.Info("[LOADREGIONS]: Loading Region Info from filesystem");
regionLoader = new RegionLoaderFileSystem();
}
else
{
m_log.Info("[LOADREGIONS]: Loading Region Info from web");
regionLoader = new RegionLoaderWebServer();
}
regionLoader.SetIniConfigSource(openSim.ConfigSource.Source);
RegionInfo[] regionsToLoad = regionLoader.LoadRegions();
for (int i = 0; i < regionsToLoad.Length; i++)
{
if (regionhandle == regionsToLoad[i].RegionHandle)
{
IScene scene;
m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " +
Thread.CurrentThread.ManagedThreadId.ToString() + ")");
openSim.CreateRegion(regionsToLoad[i], true, out scene);
}
}
}
}
}

View File

@@ -148,7 +148,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
Rest.main.SceneManager.ForEachScene(delegate(Scene s)
{
s.ForEachRootScenePresence(delegate(ScenePresence sp)
s.ForEachScenePresence(delegate(ScenePresence sp)
{
if (sp.Firstname == names[0] && sp.Lastname == names[1])
{

View File

@@ -51,11 +51,10 @@ namespace OpenSim.Framework.Capabilities
/// supplied BaseHttpServer.
/// </summary>
/// <param name="httpListener">base HTTP server</param>
/// <param name="httpListenerHostname">host name of the HTTP
/// server</param>
/// <param name="httpListenerHostname">host name of the HTTP server</param>
/// <param name="httpListenerPort">HTTP port</param>
public CapsHandlers(BaseHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
: this (httpListener,httpListenerHostname,httpListenerPort, false)
: this(httpListener,httpListenerHostname,httpListenerPort, false)
{
}
@@ -88,44 +87,52 @@ namespace OpenSim.Framework.Capabilities
/// handler to be removed</param>
public void Remove(string capsName)
{
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
m_capsHandlers.Remove(capsName);
lock (m_capsHandlers)
{
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
m_capsHandlers.Remove(capsName);
}
}
public bool ContainsCap(string cap)
{
return m_capsHandlers.ContainsKey(cap);
lock (m_capsHandlers)
return m_capsHandlers.ContainsKey(cap);
}
/// <summary>
/// The indexer allows us to treat the CapsHandlers object
/// in an intuitive dictionary like way.
/// </summary>
/// <Remarks>
/// <remarks>
/// The indexer will throw an exception when you try to
/// retrieve a cap handler for a cap that is not contained in
/// CapsHandlers.
/// </Remarks>
/// </remarks>
public IRequestHandler this[string idx]
{
get
{
return m_capsHandlers[idx];
lock (m_capsHandlers)
return m_capsHandlers[idx];
}
set
{
if (m_capsHandlers.ContainsKey(idx))
lock (m_capsHandlers)
{
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[idx].Path);
m_capsHandlers.Remove(idx);
if (m_capsHandlers.ContainsKey(idx))
{
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[idx].Path);
m_capsHandlers.Remove(idx);
}
if (null == value) return;
m_capsHandlers[idx] = value;
m_httpListener.AddStreamHandler(value);
}
if (null == value) return;
m_capsHandlers[idx] = value;
m_httpListener.AddStreamHandler(value);
}
}
@@ -137,9 +144,12 @@ namespace OpenSim.Framework.Capabilities
{
get
{
string[] __keys = new string[m_capsHandlers.Keys.Count];
m_capsHandlers.Keys.CopyTo(__keys, 0);
return __keys;
lock (m_capsHandlers)
{
string[] __keys = new string[m_capsHandlers.Keys.Count];
m_capsHandlers.Keys.CopyTo(__keys, 0);
return __keys;
}
}
}
@@ -147,25 +157,29 @@ namespace OpenSim.Framework.Capabilities
/// Return an LLSD-serializable Hashtable describing the
/// capabilities and their handler details.
/// </summary>
public Hashtable CapsDetails
/// <param name="excludeSeed">If true, then exclude the seed cap.</param>
public Hashtable GetCapsDetails(bool excludeSeed)
{
get
{
Hashtable caps = new Hashtable();
string protocol = "http://";
if (m_useSSL)
protocol = "https://";
Hashtable caps = new Hashtable();
string protocol = "http://";
if (m_useSSL)
protocol = "https://";
string baseUrl = protocol + m_httpListenerHostName + ":" + m_httpListenerPort.ToString();
string baseUrl = protocol + m_httpListenerHostName + ":" + m_httpListenerPort.ToString();
lock (m_capsHandlers)
{
foreach (string capsName in m_capsHandlers.Keys)
{
// skip SEED cap
if ("SEED" == capsName) continue;
if (excludeSeed && "SEED" == capsName)
continue;
caps[capsName] = baseUrl + m_capsHandlers[capsName].Path;
}
return caps;
}
return caps;
}
}
}
}

View File

@@ -111,6 +111,10 @@ namespace OpenSim.Capabilities.Handlers
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url);
}
// m_log.DebugFormat(
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
httpResponse.Send();
return null;
}
@@ -210,7 +214,7 @@ namespace OpenSim.Capabilities.Handlers
private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format)
{
string range = request.Headers.GetOne("Range");
//m_log.DebugFormat("[GETTEXTURE]: Range {0}", range);
if (!String.IsNullOrEmpty(range)) // JP2's only
{
// Range request
@@ -222,23 +226,27 @@ namespace OpenSim.Capabilities.Handlers
if (start >= texture.Data.Length)
{
response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
return;
}
else
{
end = Utils.Clamp(end, 0, texture.Data.Length - 1);
start = Utils.Clamp(start, 0, end);
int len = end - start + 1;
end = Utils.Clamp(end, 0, texture.Data.Length - 1);
start = Utils.Clamp(start, 0, end);
int len = end - start + 1;
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
if (len < texture.Data.Length)
// Always return PartialContent, even if the range covered the entire data length
// We were accidentally sending back 404 before in this situation
// https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
// entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
response.ContentLength = len;
response.ContentType = texture.Metadata.ContentType;
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
response.Body.Write(texture.Data, start, len);
response.ContentLength = len;
response.ContentType = texture.Metadata.ContentType;
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
response.Body.Write(texture.Data, start, len);
}
}
else
{
@@ -257,6 +265,10 @@ namespace OpenSim.Capabilities.Handlers
response.ContentType = "image/" + format;
response.Body.Write(texture.Data, 0, texture.Data.Length);
}
// m_log.DebugFormat(
// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
}
private bool TryParseRange(string header, out int start, out int end)
@@ -275,7 +287,6 @@ namespace OpenSim.Capabilities.Handlers
return false;
}
private byte[] ConvertTextureData(AssetBase texture, string format)
{
m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
@@ -350,7 +361,5 @@ namespace OpenSim.Capabilities.Handlers
}
return null;
}
}
}
}

View File

@@ -0,0 +1,181 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
using System.IO;
using System.Web;
using log4net;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenMetaverse.Imaging;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
namespace OpenSim.Capabilities.Handlers
{
public class UploadBakedTextureHandler
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Caps m_HostCapsObj;
private IAssetService m_assetService;
private bool m_persistBakedTextures;
public UploadBakedTextureHandler(Caps caps, IAssetService assetService, bool persistBakedTextures)
{
m_HostCapsObj = caps;
m_assetService = assetService;
m_persistBakedTextures = persistBakedTextures;
}
/// <summary>
/// Handle a request from the client for a Uri to upload a baked texture.
/// </summary>
/// <param name="request"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <param name="httpRequest"></param>
/// <param name="httpResponse"></param>
/// <returns>The upload response if the request is successful, null otherwise.</returns>
public string UploadBakedTexture(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
try
{
string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
BakedTextureUploader uploader =
new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener);
uploader.OnUpLoad += BakedTextureUploaded;
m_HostCapsObj.HttpListener.AddStreamHandler(
new BinaryStreamHandler("POST", capsBase + uploaderPath,
uploader.uploaderCaps));
string protocol = "http://";
if (m_HostCapsObj.SSLCaps)
protocol = "https://";
string uploaderURL = protocol + m_HostCapsObj.HostName + ":" +
m_HostCapsObj.Port.ToString() + capsBase + uploaderPath;
LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
uploadResponse.uploader = uploaderURL;
uploadResponse.state = "upload";
return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
}
catch (Exception e)
{
m_log.Error("[UPLOAD BAKED TEXTURE HANDLER]: " + e.ToString());
}
return null;
}
/// <summary>
/// Called when a baked texture has been successfully uploaded by a client.
/// </summary>
/// <param name="assetID"></param>
/// <param name="data"></param>
private void BakedTextureUploaded(UUID assetID, byte[] data)
{
// m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString());
AssetBase asset;
asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
asset.Data = data;
asset.Temporary = true;
asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are
m_assetService.Store(asset);
}
}
class BakedTextureUploader
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public event Action<UUID, byte[]> OnUpLoad;
private string uploaderPath = String.Empty;
private UUID newAssetID;
private IHttpServer httpListener;
public BakedTextureUploader(string path, IHttpServer httpServer)
{
newAssetID = UUID.Random();
uploaderPath = path;
httpListener = httpServer;
// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
}
/// <summary>
/// Handle raw uploaded baked texture data.
/// </summary>
/// <param name="data"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <returns></returns>
public string uploaderCaps(byte[] data, string path, string param)
{
Action<UUID, byte[]> handlerUpLoad = OnUpLoad;
// Don't do this asynchronously, otherwise it's possible for the client to send set appearance information
// on another thread which might send out avatar updates before the asset has been put into the asset
// service.
if (handlerUpLoad != null)
handlerUpLoad(newAssetID, data);
string res = String.Empty;
LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
uploadComplete.new_asset = newAssetID.ToString();
uploadComplete.new_inventory_item = UUID.Zero;
uploadComplete.state = "complete";
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
httpListener.RemoveStreamHandler("POST", uploaderPath);
// m_log.DebugFormat("[BAKED TEXTURE UPLOADER]: baked texture upload completed for {0}", newAssetID);
return res;
}
}
}

View File

@@ -208,7 +208,86 @@ namespace OpenSim.Capabilities.Handlers
containingFolder.Owner = agentID;
containingFolder = m_InventoryService.GetFolder(containingFolder);
if (containingFolder != null)
{
// m_log.DebugFormat(
// "[WEB FETCH INV DESC HANDLER]: Retrieved folder {0} {1} for agent id {2}",
// containingFolder.Name, containingFolder.ID, agentID);
version = containingFolder.Version;
//
// if (fetchItems)
// {
// 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);
// }
// }
//
// foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
// {
// m_log.DebugFormat(
// "[WEB FETCH INV DESC HANDLER]: Inserted linked item {0} for link in folder {1} for agent {2}",
// linkedItem.Name, folderID, agentID);
//
// contents.Items.Add(linkedItem);
// }
//
// // If the folder requested contains links, then we need to send those folders first, otherwise the links
// // will be broken in the viewer.
// HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>();
// 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)
// {
// // We don't need to send the folder if source and destination of the link are in the same
// // folder.
// if (linkedItem.Folder != containingFolder.ID)
// linkedItemFolderIdsToSend.Add(linkedItem.Folder);
// }
// }
// }
//
// foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend)
// {
// m_log.DebugFormat(
// "[WEB FETCH INV DESC HANDLER]: Recursively fetching folder {0} linked by item in folder {1} for agent {2}",
// linkedItemFolderId, folderID, agentID);
//
// int dummyVersion;
// InventoryCollection linkedCollection
// = Fetch(
// agentID, linkedItemFolderId, ownerID, fetchFolders, fetchItems, sortOrder, out dummyVersion);
//
// InventoryFolderBase linkedFolder = new InventoryFolderBase(linkedItemFolderId);
// linkedFolder.Owner = agentID;
// linkedFolder = m_InventoryService.GetFolder(linkedFolder);
//
//// contents.Folders.AddRange(linkedCollection.Folders);
//
// contents.Folders.Add(linkedFolder);
// contents.Items.AddRange(linkedCollection.Items);
// }
// }
}
}
else
{

View File

@@ -38,7 +38,7 @@ namespace OpenSim.Data
{
public abstract AssetBase GetAsset(UUID uuid);
public abstract bool StoreAsset(AssetBase asset);
public abstract void StoreAsset(AssetBase asset);
public abstract bool ExistsAsset(UUID uuid);
public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);

View File

@@ -34,7 +34,7 @@ namespace OpenSim.Data
public interface IAssetDataPlugin : IPlugin
{
AssetBase GetAsset(UUID uuid);
bool StoreAsset(AssetBase asset);
void StoreAsset(AssetBase asset);
bool ExistsAsset(UUID uuid);
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
void Initialise(string connect);

View File

@@ -37,10 +37,30 @@ namespace OpenSim.Data
public UUID RegionID;
public UUID ScopeID;
public string RegionName;
/// <summary>
/// The position in meters of this region.
/// </summary>
public int posX;
/// <summary>
/// The position in meters of this region.
/// </summary>
public int posY;
public int sizeX;
public int sizeY;
/// <summary>
/// Return the x-coordinate of this region.
/// </summary>
public int coordX { get { return posX / (int)Constants.RegionSize; } }
/// <summary>
/// Return the y-coordinate of this region.
/// </summary>
public int coordY { get { return posY / (int)Constants.RegionSize; } }
public Dictionary<string, object> Data;
}

View File

@@ -50,6 +50,5 @@ namespace OpenSim.Data
bool Store(UserAccountData data);
bool Delete(string field, string val);
UserAccountData[] GetUsers(UUID scopeID, string query);
UserAccountData[] GetUsersWhere(UUID scopeID, string where);
}
}

View File

@@ -143,7 +143,7 @@ namespace OpenSim.Data.MSSQL
/// Create asset in m_database
/// </summary>
/// <param name="asset">the asset</param>
override public bool StoreAsset(AssetBase asset)
override public void StoreAsset(AssetBase asset)
{
string sql =
@@ -192,12 +192,10 @@ namespace OpenSim.Data.MSSQL
try
{
command.ExecuteNonQuery();
return true;
}
catch(Exception e)
{
m_log.Error("[ASSET DB]: Error storing item :" + e.Message);
return false;
}
}
}

View File

@@ -43,7 +43,7 @@ namespace OpenSim.Data.MSSQL
public class MSSQLAvatarData : MSSQLGenericTableHandler<AvatarBaseData>,
IAvatarData
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public MSSQLAvatarData(string connectionString, string realm) :
base(connectionString, realm, "Avatar")

View File

@@ -40,8 +40,8 @@ namespace OpenSim.Data.MSSQL
{
public class MSSQLGenericTableHandler<T> where T : class, new()
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log =
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected string m_ConnectionString;
protected MSSQLManager m_database; //used for parameter type translation

View File

@@ -43,7 +43,7 @@ namespace OpenSim.Data.MSSQL
public class MSSQLGridUserData : MSSQLGenericTableHandler<GridUserData>,
IGridUserData
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public MSSQLGridUserData(string connectionString, string realm) :
base(connectionString, realm, "GridUserStore")

View File

@@ -41,7 +41,7 @@ namespace OpenSim.Data.MSSQL
/// </summary>
public class MSSQLManager
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Connection string for ADO.net
@@ -180,8 +180,6 @@ namespace OpenSim.Data.MSSQL
return parameter;
}
private static readonly Dictionary<string, string> emptyDictionary = new Dictionary<string, string>();
/// <summary>
/// Checks if we need to do some migrations to the database
/// </summary>

View File

@@ -43,7 +43,7 @@ namespace OpenSim.Data.MSSQL
public class MSSQLPresenceData : MSSQLGenericTableHandler<PresenceData>,
IPresenceData
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public MSSQLPresenceData(string connectionString, string realm) :
base(connectionString, realm, "Presence")

View File

@@ -242,10 +242,5 @@ namespace OpenSim.Data.MSSQL
return DoQuery(cmd);
}
}
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
{
return null;
}
}
}

View File

@@ -40,8 +40,8 @@ namespace OpenSim.Data.MSSQL
{
public class MSSQLXInventoryData : IXInventoryData
{
private static readonly ILog m_log = LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(
// MethodBase.GetCurrentMethod().DeclaringType);
private MSSQLGenericTableHandler<XInventoryFolder> m_Folders;
private MSSQLItemHandler m_Items;

View File

@@ -155,7 +155,7 @@ namespace OpenSim.Data.MySQL
/// </summary>
/// <param name="asset">Asset UUID to create</param>
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
override public bool StoreAsset(AssetBase asset)
override public void StoreAsset(AssetBase asset)
{
lock (m_dbLock)
{
@@ -203,14 +203,12 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery();
cmd.Dispose();
return true;
}
}
catch (Exception e)
{
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
asset.FullID, asset.Name, e.Message);
return false;
}
}
}

View File

@@ -66,7 +66,7 @@ namespace OpenSim.Data.MySQL
Initialise(connectionString);
}
public virtual void Initialise(string connectionString)
public void Initialise(string connectionString)
{
m_connectionString = connectionString;
@@ -113,7 +113,7 @@ namespace OpenSim.Data.MySQL
public void Dispose() {}
public virtual void StoreObject(SceneObjectGroup obj, UUID regionUUID)
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
{
uint flags = obj.RootPart.GetEffectiveObjectFlags();
@@ -241,7 +241,7 @@ namespace OpenSim.Data.MySQL
}
}
public virtual void RemoveObject(UUID obj, UUID regionUUID)
public void RemoveObject(UUID obj, UUID regionUUID)
{
// m_log.DebugFormat("[REGION DB]: Deleting scene object {0} from {1} in database", obj, regionUUID);
@@ -390,7 +390,7 @@ namespace OpenSim.Data.MySQL
}
}
public virtual List<SceneObjectGroup> LoadObjects(UUID regionID)
public List<SceneObjectGroup> LoadObjects(UUID regionID)
{
const int ROWS_PER_QUERY = 5000;
@@ -559,7 +559,7 @@ namespace OpenSim.Data.MySQL
}
}
public virtual void StoreTerrain(double[,] ter, UUID regionID)
public void StoreTerrain(double[,] ter, UUID regionID)
{
m_log.Info("[REGION DB]: Storing terrain");
@@ -588,7 +588,7 @@ namespace OpenSim.Data.MySQL
}
}
public virtual double[,] LoadTerrain(UUID regionID)
public double[,] LoadTerrain(UUID regionID)
{
double[,] terrain = null;
@@ -638,7 +638,7 @@ namespace OpenSim.Data.MySQL
return terrain;
}
public virtual void RemoveLandObject(UUID globalID)
public void RemoveLandObject(UUID globalID)
{
lock (m_dbLock)
{
@@ -657,7 +657,7 @@ namespace OpenSim.Data.MySQL
}
}
public virtual void StoreLandObject(ILandObject parcel)
public void StoreLandObject(ILandObject parcel)
{
lock (m_dbLock)
{
@@ -714,7 +714,7 @@ namespace OpenSim.Data.MySQL
}
}
public virtual RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
{
RegionLightShareData nWP = new RegionLightShareData();
nWP.OnSave += StoreRegionWindlightSettings;
@@ -736,7 +736,7 @@ namespace OpenSim.Data.MySQL
{
//No result, so store our default windlight profile and return it
nWP.regionID = regionUUID;
// StoreRegionWindlightSettings(nWP);
StoreRegionWindlightSettings(nWP);
return nWP;
}
else
@@ -811,7 +811,7 @@ namespace OpenSim.Data.MySQL
return nWP;
}
public virtual RegionSettings LoadRegionSettings(UUID regionUUID)
public RegionSettings LoadRegionSettings(UUID regionUUID)
{
RegionSettings rs = null;
@@ -849,7 +849,7 @@ namespace OpenSim.Data.MySQL
return rs;
}
public virtual void StoreRegionWindlightSettings(RegionLightShareData wl)
public void StoreRegionWindlightSettings(RegionLightShareData wl)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
@@ -952,7 +952,7 @@ namespace OpenSim.Data.MySQL
}
}
public virtual void RemoveRegionWindlightSettings(UUID regionID)
public void RemoveRegionWindlightSettings(UUID regionID)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
@@ -967,7 +967,7 @@ namespace OpenSim.Data.MySQL
}
}
public virtual void StoreRegionSettings(RegionSettings rs)
public void StoreRegionSettings(RegionSettings rs)
{
lock (m_dbLock)
{
@@ -994,7 +994,7 @@ namespace OpenSim.Data.MySQL
"use_estate_sun, fixed_sun, sun_position, " +
"covenant, Sandbox, sunvectorx, sunvectory, " +
"sunvectorz, loaded_creation_datetime, " +
"loaded_creation_id, map_tile_ID, block_search, casino) values (?RegionUUID, ?BlockTerraform, " +
"loaded_creation_id, map_tile_ID) values (?RegionUUID, ?BlockTerraform, " +
"?BlockFly, ?AllowDamage, ?RestrictPushing, " +
"?AllowLandResell, ?AllowLandJoinDivide, " +
"?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " +
@@ -1009,7 +1009,7 @@ namespace OpenSim.Data.MySQL
"?SunPosition, ?Covenant, ?Sandbox, " +
"?SunVectorX, ?SunVectorY, ?SunVectorZ, " +
"?LoadedCreationDateTime, ?LoadedCreationID, " +
"?TerrainImageID, ?block_search, ?casino)";
"?TerrainImageID)";
FillRegionSettingsCommand(cmd, rs);
@@ -1019,7 +1019,7 @@ namespace OpenSim.Data.MySQL
}
}
public virtual List<LandData> LoadLandObjects(UUID regionUUID)
public List<LandData> LoadLandObjects(UUID regionUUID)
{
List<LandData> landData = new List<LandData>();
@@ -1297,9 +1297,6 @@ namespace OpenSim.Data.MySQL
newSettings.TerrainImageID = DBGuid.FromDB(row["map_tile_ID"]);
newSettings.GodBlockSearch = Convert.ToBoolean(row["block_search"]);
newSettings.Casino = Convert.ToBoolean(row["casino"]);
return newSettings;
}
@@ -1629,8 +1626,6 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("LoadedCreationDateTime", settings.LoadedCreationDateTime);
cmd.Parameters.AddWithValue("LoadedCreationID", settings.LoadedCreationID);
cmd.Parameters.AddWithValue("TerrainImageID", settings.TerrainImageID);
cmd.Parameters.AddWithValue("block_search", settings.GodBlockSearch);
cmd.Parameters.AddWithValue("casino", settings.Casino);
}
@@ -1789,7 +1784,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml());
}
public virtual void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
{
lock (m_dbLock)
{

View File

@@ -46,21 +46,17 @@ namespace OpenSim.Data.MySQL
{
string[] words = query.Split(new char[] {' '});
bool valid = false;
for (int i = 0 ; i < words.Length ; i++)
{
if (words[i].Length > 2)
valid = true;
// if (words[i].Length < 3)
// {
// if (i != words.Length - 1)
// Array.Copy(words, i + 1, words, i, words.Length - i - 1);
// Array.Resize(ref words, words.Length - 1);
// }
if (words[i].Length < 3)
{
if (i != words.Length - 1)
Array.Copy(words, i + 1, words, i, words.Length - i - 1);
Array.Resize(ref words, words.Length - 1);
}
}
if ((!valid) || words.Length == 0)
if (words.Length == 0)
return new UserAccountData[0];
if (words.Length > 2)
@@ -70,34 +66,19 @@ namespace OpenSim.Data.MySQL
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) and active=1", m_Realm);
cmd.Parameters.AddWithValue("?search", words[0] + "%");
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 and LastName like ?searchLast) and active=1", m_Realm);
cmd.Parameters.AddWithValue("?searchFirst", words[0] + "%");
cmd.Parameters.AddWithValue("?searchLast", words[1] + "%");
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);
}
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
{
MySqlCommand cmd = new MySqlCommand();
if (scopeID != UUID.Zero)
{
where = "(ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (" + where + ")";
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
}
cmd.CommandText = String.Format("select * from {0} where " + where, m_Realm);
return DoQuery(cmd);
}
}
}

View File

@@ -717,7 +717,7 @@ ALTER TABLE regionsettings ADD COLUMN loaded_creation_datetime int unsigned NOT
COMMIT;
:VERSION 32 #---------------------
:VERSION 32
BEGIN;
CREATE TABLE `regionwindlight` (

View File

@@ -193,10 +193,5 @@ namespace OpenSim.Data.Null
return false;
}
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
{
return null;
}
}
}

View File

@@ -128,7 +128,7 @@ namespace OpenSim.Data.SQLite
/// Create an asset
/// </summary>
/// <param name="asset">Asset Base</param>
override public bool StoreAsset(AssetBase asset)
override public void StoreAsset(AssetBase asset)
{
//m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString());
if (ExistsAsset(asset.FullID))
@@ -150,7 +150,6 @@ namespace OpenSim.Data.SQLite
cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
cmd.ExecuteNonQuery();
return true;
}
}
}
@@ -171,7 +170,6 @@ namespace OpenSim.Data.SQLite
cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
cmd.ExecuteNonQuery();
return true;
}
}
}

View File

@@ -81,10 +81,5 @@ namespace OpenSim.Data.SQLite
return DoQuery(cmd);
}
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
{
return null;
}
}
}

View File

@@ -297,6 +297,7 @@ namespace OpenSim.Data.Tests
pbshap.ProfileEnd = ushort.MaxValue;
pbshap.ProfileHollow = ushort.MaxValue;
Vector3 scale = new Vector3(random.Next(),random.Next(),random.Next());
byte updatef = (byte) random.Next(127);
RegionInfo regionInfo = new RegionInfo();
regionInfo.RegionID = region3;
@@ -335,6 +336,7 @@ namespace OpenSim.Data.Tests
sop.LinkNum = linknum;
sop.ClickAction = clickaction;
sop.Scale = scale;
sop.UpdateFlag = updatef;
//Tests if local part accepted the parameters:
Assert.That(regionh,Is.EqualTo(sop.RegionHandle), "Assert.That(regionh,Is.EqualTo(sop.RegionHandle))");
@@ -367,6 +369,7 @@ namespace OpenSim.Data.Tests
Assert.That(linknum,Is.EqualTo(sop.LinkNum), "Assert.That(linknum,Is.EqualTo(sop.LinkNum))");
Assert.That(clickaction,Is.EqualTo(sop.ClickAction), "Assert.That(clickaction,Is.EqualTo(sop.ClickAction))");
Assert.That(scale,Is.EqualTo(sop.Scale), "Assert.That(scale,Is.EqualTo(sop.Scale))");
Assert.That(updatef,Is.EqualTo(sop.UpdateFlag), "Assert.That(updatef,Is.EqualTo(sop.UpdateFlag))");
// This is necessary or object will not be inserted in DB
sop.Flags = PrimFlags.None;
@@ -466,6 +469,7 @@ namespace OpenSim.Data.Tests
PrimitiveBaseShape pbshap = new PrimitiveBaseShape();
pbshap = PrimitiveBaseShape.Default;
Vector3 scale = new Vector3(random.Next(),random.Next(),random.Next());
byte updatef = (byte) random.Next(127);
// Updates the region with new values
SceneObjectGroup sog2 = FindSOG("Adam West", region3);
@@ -495,6 +499,7 @@ namespace OpenSim.Data.Tests
sog2.RootPart.LinkNum = linknum;
sog2.RootPart.ClickAction = clickaction;
sog2.RootPart.Scale = scale;
sog2.RootPart.UpdateFlag = updatef;
db.StoreObject(sog2, region3);
List<SceneObjectGroup> sogs = db.LoadObjects(region3);

View File

@@ -311,7 +311,7 @@ namespace OpenSim.Framework
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map))
{
Appearance.Unpack((OSDMap)args["packed_appearance"]);
m_log.InfoFormat("[AGENTCIRCUITDATA] unpacked appearance");
// m_log.InfoFormat("[AGENTCIRCUITDATA] unpacked appearance");
}
else
{

View File

@@ -60,8 +60,6 @@ namespace OpenSim.Framework
/// </summary>
private AssetMetadata m_metadata;
private int m_uploadAttempts;
// This is needed for .NET serialization!!!
// Do NOT "Optimize" away!
public AssetBase()
@@ -200,12 +198,6 @@ namespace OpenSim.Framework
set { m_metadata.Type = value; }
}
public int UploadAttempts
{
get { return m_uploadAttempts; }
set { m_uploadAttempts = value; }
}
/// <summary>
/// Is this a region only asset, or does this exist on the asset server also
/// </summary>

View File

@@ -53,6 +53,7 @@ namespace OpenSim.Framework
protected AvatarWearable[] m_wearables;
protected Dictionary<int, List<AvatarAttachment>> m_attachments;
protected float m_avatarHeight = 0;
protected float m_hipOffset = 0;
public virtual int Serial
{
@@ -88,6 +89,11 @@ namespace OpenSim.Framework
set { m_avatarHeight = value; }
}
public virtual float HipOffset
{
get { return m_hipOffset; }
}
public AvatarAppearance()
{
// m_log.WarnFormat("[AVATAR APPEARANCE]: create empty appearance");
@@ -178,6 +184,7 @@ namespace OpenSim.Framework
m_visualparams = (byte[])appearance.VisualParams.Clone();
m_avatarHeight = appearance.m_avatarHeight;
m_hipOffset = appearance.m_hipOffset;
// Copy the attachment, force append mode since that ensures consistency
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
@@ -240,21 +247,6 @@ namespace OpenSim.Framework
// }
}
/// <summary>
/// Invalidate all of the baked textures in the appearance, useful
/// if you know that none are valid
/// </summary>
public virtual void ResetBakedTextures()
{
SetDefaultTexture();
//for (int i = 0; i < BAKE_INDICES.Length; i++)
// {
// int idx = BAKE_INDICES[i];
// m_texture.FaceTextures[idx].TextureID = UUID.Zero;
// }
}
protected virtual void SetDefaultTexture()
{
m_texture = new Primitive.TextureEntry(new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE));
@@ -340,18 +332,20 @@ namespace OpenSim.Framework
public virtual void SetHeight()
{
// Start with shortest possible female avatar height
m_avatarHeight = 1.14597f;
// Add offset for male avatars
if (m_visualparams[(int)VPElement.SHAPE_MALE] != 0)
m_avatarHeight += 0.0848f;
// Add offsets for visual params
m_avatarHeight += 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f
+ 0.08117f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f
+ 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f
+ 0.07f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f
+ 0.08f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f
+ 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f;
m_avatarHeight = 1.23077f // Shortest possible avatar height
+ 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
+ 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size
+ 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
+ 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
+ 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
+ 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; // Neck length
m_hipOffset = (((1.23077f // Half of avatar
+ 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
+ 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
+ 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
+ 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
) / 2) - m_avatarHeight / 2) * 0.31f - 0.0425f;
}
public virtual void SetWearable(int wearableId, AvatarWearable wearable)
@@ -398,18 +392,19 @@ namespace OpenSim.Framework
/// </remarks>
public List<AvatarAttachment> GetAttachments()
{
List<AvatarAttachment> alist = new List<AvatarAttachment>();
lock (m_attachments)
{
List<AvatarAttachment> alist = new List<AvatarAttachment>();
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
{
foreach (AvatarAttachment attach in kvp.Value)
alist.Add(new AvatarAttachment(attach));
}
return alist;
} }
}
return alist;
}
internal void AppendAttachment(AvatarAttachment attach)
{
@@ -538,6 +533,7 @@ namespace OpenSim.Framework
return kvp.Key;
}
}
return 0;
}
@@ -582,6 +578,7 @@ namespace OpenSim.Framework
data["serial"] = OSD.FromInteger(m_serial);
data["height"] = OSD.FromReal(m_avatarHeight);
data["hipoffset"] = OSD.FromReal(m_hipOffset);
// Wearables
OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
@@ -604,14 +601,12 @@ namespace OpenSim.Framework
OSDBinary visualparams = new OSDBinary(m_visualparams);
data["visualparams"] = visualparams;
lock (m_attachments)
{
// Attachments
OSDArray attachs = new OSDArray(m_attachments.Count);
foreach (AvatarAttachment attach in GetAttachments())
attachs.Add(attach.Pack());
data["attachments"] = attachs;
}
// Attachments
List<AvatarAttachment> attachments = GetAttachments();
OSDArray attachs = new OSDArray(attachments.Count);
foreach (AvatarAttachment attach in GetAttachments())
attachs.Add(attach.Pack());
data["attachments"] = attachs;
return data;
}
@@ -626,6 +621,8 @@ namespace OpenSim.Framework
m_serial = data["serial"].AsInteger();
if ((data != null) && (data["height"] != null))
m_avatarHeight = (float)data["height"].AsReal();
if ((data != null) && (data["hipoffset"] != null))
m_hipOffset = (float)data["hipoffset"].AsReal();
try
{

View File

@@ -335,7 +335,7 @@ namespace OpenSim.Framework
public virtual OSDMap Pack()
{
m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data");
// m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data");
OSDMap args = new OSDMap();
args["message_type"] = OSD.FromString("AgentData");

View File

@@ -363,7 +363,7 @@ namespace OpenSim.Framework.Communications
_request = (HttpWebRequest) WebRequest.Create(buildUri());
_request.KeepAlive = false;
_request.ContentType = "application/xml";
_request.Timeout = 30000;
_request.Timeout = 900000;
_request.Method = RequestMethod;
_asyncException = null;
_request.ContentLength = src.Length;

View File

@@ -565,7 +565,7 @@ namespace OpenSim.Framework.Console
/// </summary>
public class CommandConsole : ConsoleBase, ICommandConsole
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public ICommands Commands { get; private set; }

View File

@@ -58,30 +58,6 @@ namespace OpenSim.Framework
set { m_EstateName = value; }
}
private bool m_AllowLandmark = true;
public bool AllowLandmark
{
get { return m_AllowLandmark; }
set { m_AllowLandmark = value; }
}
private bool m_AllowParcelChanges = true;
public bool AllowParcelChanges
{
get { return m_AllowParcelChanges; }
set { m_AllowParcelChanges = value; }
}
private bool m_AllowSetHome = true;
public bool AllowSetHome
{
get { return m_AllowSetHome; }
set { m_AllowSetHome = value; }
}
private uint m_ParentEstateID = 1;
public uint ParentEstateID
@@ -362,30 +338,11 @@ namespace OpenSim.Framework
return false;
}
public bool IsBanned(UUID avatarID, int userFlags)
public bool IsBanned(UUID avatarID)
{
foreach (EstateBan ban in l_EstateBans)
if (ban.BannedUserID == avatarID)
return true;
if (!IsEstateManager(avatarID) && !HasAccess(avatarID))
{
if (DenyMinors)
{
if ((userFlags & 32) == 0)
{
return true;
}
}
if (DenyAnonymous)
{
if ((userFlags & 4) == 0)
{
return true;
}
}
}
return false;
}
@@ -393,7 +350,7 @@ namespace OpenSim.Framework
{
if (ban == null)
return;
if (!IsBanned(ban.BannedUserID, 32)) //Ignore age-based bans
if (!IsBanned(ban.BannedUserID))
l_EstateBans.Add(ban);
}
@@ -416,14 +373,5 @@ namespace OpenSim.Framework
return l_EstateAccess.Contains(user);
}
public void SetFromFlags(ulong regionFlags)
{
ResetHomeOnTeleport = ((regionFlags & (ulong)RegionFlags.ResetHomeOnTeleport) == (ulong)RegionFlags.ResetHomeOnTeleport);
BlockDwell = ((regionFlags & (ulong)RegionFlags.BlockDwell) == (ulong)RegionFlags.BlockDwell);
AllowLandmark = ((regionFlags & (ulong)RegionFlags.AllowLandmark) == (ulong)RegionFlags.AllowLandmark);
AllowParcelChanges = ((regionFlags & (ulong)RegionFlags.AllowParcelChanges) == (ulong)RegionFlags.AllowParcelChanges);
AllowSetHome = ((regionFlags & (ulong)RegionFlags.AllowSetHome) == (ulong)RegionFlags.AllowSetHome);
}
}
}

View File

@@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
using OpenSim.Framework;
namespace OpenSim.Framework
{
public interface ICallingCardModule
{
UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID);
}
}

View File

@@ -53,7 +53,8 @@ namespace OpenSim.Framework
public delegate ISceneEntity RezSingleAttachmentFromInv(IClientAPI remoteClient, UUID itemID, uint AttachmentPt);
public delegate void RezMultipleAttachmentsFromInv(IClientAPI remoteClient, List<KeyValuePair<UUID, uint>> rezlist );
public delegate void RezMultipleAttachmentsFromInv(IClientAPI remoteClient, RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header,
RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects);
public delegate void ObjectAttach(
IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent);
@@ -264,9 +265,6 @@ namespace OpenSim.Framework
public delegate void MoveInventoryItem(
IClientAPI remoteClient, List<InventoryItemBase> items);
public delegate void MoveItemsAndLeaveCopy(
IClientAPI remoteClient, List<InventoryItemBase> items, UUID destFolder);
public delegate void RemoveInventoryItem(
IClientAPI remoteClient, List<UUID> itemIDs);
@@ -440,7 +438,6 @@ namespace OpenSim.Framework
public delegate void ClassifiedInfoRequest(UUID classifiedID, IClientAPI client);
public delegate void ClassifiedInfoUpdate(UUID classifiedID, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, Vector3 globalPos, byte classifiedFlags, int price, IClientAPI client);
public delegate void ClassifiedDelete(UUID classifiedID, IClientAPI client);
public delegate void ClassifiedGodDelete(UUID classifiedID, UUID queryID, IClientAPI client);
public delegate void EventNotificationAddRequest(uint EventID, IClientAPI client);
public delegate void EventNotificationRemoveRequest(uint EventID, IClientAPI client);
@@ -463,9 +460,9 @@ namespace OpenSim.Framework
public delegate void AgentFOV(IClientAPI client, float verticalAngle);
public delegate void MuteListEntryUpdate(IClientAPI client, UUID MuteID, string Name, int type, uint flags);
public delegate void MuteListEntryUpdate(IClientAPI client, UUID MuteID, string Name, int Flags,UUID AgentID);
public delegate void MuteListEntryRemove(IClientAPI client, UUID MuteID, string Name);
public delegate void MuteListEntryRemove(IClientAPI client, UUID MuteID, string Name, UUID AgentID);
public delegate void AvatarInterestReply(IClientAPI client,UUID target, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages);
@@ -706,6 +703,12 @@ namespace OpenSim.Framework
UUID AgentId { get; }
/// <summary>
/// The scene agent for this client. This will only be set if the client has an agent in a scene (i.e. if it
/// is connected).
/// </summary>
ISceneAgent SceneAgent { get; }
UUID SessionId { get; }
UUID SecureSessionId { get; }
@@ -849,7 +852,6 @@ namespace OpenSim.Framework
event RequestTaskInventory OnRequestTaskInventory;
event UpdateInventoryItem OnUpdateInventoryItem;
event CopyInventoryItem OnCopyInventoryItem;
event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
event MoveInventoryItem OnMoveInventoryItem;
event RemoveInventoryFolder OnRemoveInventoryFolder;
event RemoveInventoryItem OnRemoveInventoryItem;
@@ -968,7 +970,7 @@ namespace OpenSim.Framework
event ClassifiedInfoRequest OnClassifiedInfoRequest;
event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
event ClassifiedDelete OnClassifiedDelete;
event ClassifiedGodDelete OnClassifiedGodDelete;
event ClassifiedDelete OnClassifiedGodDelete;
event EventNotificationAddRequest OnEventNotificationAddRequest;
event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
@@ -1020,7 +1022,6 @@ namespace OpenSim.Framework
void InPacket(object NewPack);
void ProcessInPacket(Packet NewPack);
void Close();
void Close(bool sendStop);
void Kick(string message);
/// <summary>
@@ -1052,7 +1053,7 @@ namespace OpenSim.Framework
/// </summary>
/// <param name="regionHandle"></param>
/// <param name="localID"></param>
void SendKillObject(ulong regionHandle, List<uint> localID);
void SendKillObject(ulong regionHandle, uint localID);
void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs);
void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args);

View File

@@ -40,7 +40,6 @@ namespace OpenSim.Framework
bool AmountCovered(IClientAPI client, int amount);
void ApplyCharge(UUID agentID, int amount, string text);
void ApplyUploadCharge(UUID agentID, int amount, string text);
void MoveMoney(UUID fromUser, UUID toUser, int amount, string text);
int UploadCharge { get; }
int GroupCreationCharge { get; }

View File

@@ -68,12 +68,14 @@ namespace OpenSim.Framework
event restart OnRestart;
/// <summary>
/// Register the new client with the scene. The client starts off as a child agent - the later agent crossing
/// will promote it to a root agent.
/// Add a new client and create a presence for it. All clients except initial login clients will starts off as a child agent
/// - the later agent crossing will promote it to a root agent.
/// </summary>
/// <param name="client"></param>
/// <param name="type">The type of agent to add.</param>
void AddNewClient(IClientAPI client, PresenceType type);
/// <returns>
/// The scene agent if the new client was added or if an agent that already existed.</returns>
ISceneAgent AddNewClient(IClientAPI client, PresenceType type);
/// <summary>
/// Remove the given client from the scene.
@@ -87,27 +89,30 @@ namespace OpenSim.Framework
string GetSimulatorVersion();
/// <summary>
/// Is the agent denoted by the given agentID a child presence in this scene?
/// </summary>
///
/// Used by ClientView when a 'kick everyone' or 'estate message' occurs
///
/// <param name="avatarID">AvatarID to lookup</param>
/// <returns>true if the presence is a child agent, false if the presence is a root exception</returns>
/// <exception cref="System.NullReferenceException">
/// Thrown if the agent does not exist.
/// </exception>
bool PresenceChildStatus(UUID agentId);
bool TryGetScenePresence(UUID agentID, out object scenePresence);
T RequestModuleInterface<T>();
T[] RequestModuleInterfaces<T>();
/// <summary>
/// Register an interface to a region module. This allows module methods to be called directly as
/// well as via events. If there is already a module registered for this interface, it is not replaced
/// (is this the best behaviour?)
/// </summary>
/// <param name="mod"></param>
void RegisterModuleInterface<M>(M mod);
void StackModuleInterface<M>(M mod);
/// <summary>
/// For the given interface, retrieve the region module which implements it.
/// </summary>
/// <returns>null if there is no registered module implementing that interface</returns>
T RequestModuleInterface<T>();
/// <summary>
/// For the given interface, retrieve an array of region modules that implement it.
/// </summary>
/// <returns>an empty array if there are no registered modules implementing that interface</returns>
T[] RequestModuleInterfaces<T>();
// void AddCommand(object module, string command, string shorthelp, string longhelp, CommandDelegate callback);
ISceneObject DeserializeObject(string representation);

View File

@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -26,46 +26,50 @@
*/
using System;
using System.Runtime.Remoting.Lifetime;
using System.Threading;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
namespace OpenSim.Framework
{
public partial class ScriptBaseClass : MarshalByRefObject
/// <summary>
/// An agent in the scene.
/// </summary>
/// <remarks>
/// Interface is a work in progress. Please feel free to add other required properties and methods.
/// </remarks>
public interface ISceneAgent : ISceneEntity
{
public ICM_Api m_CM_Functions;
/// <value>
/// The client controlling this presence
/// </value>
IClientAPI ControllingClient { get; }
public void ApiTypeCM(IScriptApi api)
{
if (!(api is ICM_Api))
return;
/// <summary>
/// What type of presence is this? User, NPC, etc.
/// </summary>
PresenceType PresenceType { get; }
m_CM_Functions = (ICM_Api)api;
}
/// <summary>
/// If true, then the agent has no avatar in the scene.
/// The agent exists to relay data from a region that neighbours the current position of the user's avatar.
/// Occasionally data is relayed, such as which a user clicks an item in a neighbouring region.
/// </summary>
bool IsChildAgent { get; }
public string cmDetectedCountry(int num)
{
return m_CM_Functions.cmDetectedCountry(num);
}
/// <summary>
/// Avatar appearance data.
/// </summary>
/// <remarks>
// Because appearance setting is in a module, we actually need
// to give it access to our appearance directly, otherwise we
// get a synchronization issue.
/// </remarks>
AvatarAppearance Appearance { get; set; }
public string cmGetAgentCountry(key key)
{
return m_CM_Functions.cmGetAgentCountry(key);
}
/// <summary>
/// Send initial scene data to the client controlling this agent
/// </summary>
/// <remarks>
/// This includes scene object data and the appearance data of other avatars.
/// </remarks>
void SendInitialDataToMe();
}
}
}

View File

@@ -34,6 +34,7 @@ namespace OpenSim.Framework
string Name { get; set; }
UUID UUID { get; }
uint LocalId { get; }
Vector3 AbsolutePosition { get; }
}
}

View File

@@ -33,6 +33,12 @@ namespace OpenSim.Framework
public interface ISceneObject
{
UUID UUID { get; }
/// <summary>
/// The owner of this object.
/// </summary>
UUID OwnerID { get; set; }
ISceneObject CloneForNewScene();
string ToXml2();
string ExtraToXmlString();

View File

@@ -60,7 +60,7 @@ namespace OpenSim.Framework
private uint _flags = (uint) ParcelFlags.AllowFly | (uint) ParcelFlags.AllowLandmark |
(uint) ParcelFlags.AllowAPrimitiveEntry |
(uint) ParcelFlags.AllowDeedToGroup |
(uint) ParcelFlags.AllowDeedToGroup | (uint) ParcelFlags.AllowTerraform |
(uint) ParcelFlags.CreateObjects | (uint) ParcelFlags.AllowOtherScripts |
(uint) ParcelFlags.SoundLocal;

View File

@@ -27,7 +27,7 @@
namespace OpenSim.Framework
{
public enum ParcelMediaCommandEnum : int
public enum ParcelMediaCommandEnum
{
Stop = 0,
Pause = 1,

View File

@@ -244,22 +244,13 @@ namespace OpenSim.Framework
// The Mono addin manager (in Mono.Addins.dll version 0.2.0.0)
// occasionally seems to corrupt its addin cache
// Hence, as a temporary solution we'll remove it before each startup
string customDir = Environment.GetEnvironmentVariable ("MONO_ADDINS_REGISTRY");
string v0 = "addin-db-000";
string v1 = "addin-db-001";
if (customDir != null && customDir != String.Empty)
{
v0 = Path.Combine(customDir, v0);
v1 = Path.Combine(customDir, v1);
}
try
{
if (Directory.Exists(v0))
Directory.Delete(v0, true);
if (Directory.Exists("addin-db-000"))
Directory.Delete("addin-db-000", true);
if (Directory.Exists(v1))
Directory.Delete(v1, true);
if (Directory.Exists("addin-db-001"))
Directory.Delete("addin-db-001", true);
}
catch (IOException)
{

View File

@@ -720,12 +720,7 @@ namespace OpenSim.Framework
return _lightColorR;
}
set {
if (value < 0)
_lightColorR = 0;
else if (value > 1.0f)
_lightColorR = 1.0f;
else
_lightColorR = value;
_lightColorR = value;
}
}
@@ -734,12 +729,7 @@ namespace OpenSim.Framework
return _lightColorG;
}
set {
if (value < 0)
_lightColorG = 0;
else if (value > 1.0f)
_lightColorG = 1.0f;
else
_lightColorG = value;
_lightColorG = value;
}
}
@@ -748,12 +738,7 @@ namespace OpenSim.Framework
return _lightColorB;
}
set {
if (value < 0)
_lightColorB = 0;
else if (value > 1.0f)
_lightColorB = 1.0f;
else
_lightColorB = value;
_lightColorB = value;
}
}
@@ -762,12 +747,7 @@ namespace OpenSim.Framework
return _lightColorA;
}
set {
if (value < 0)
_lightColorA = 0;
else if (value > 1.0f)
_lightColorA = 1.0f;
else
_lightColorA = value;
_lightColorA = value;
}
}
@@ -1430,7 +1410,7 @@ namespace OpenSim.Framework
prim.Textures = this.Textures;
prim.Properties = new Primitive.ObjectProperties();
prim.Properties.Name = "Object";
prim.Properties.Name = "Primitive";
prim.Properties.Description = "";
prim.Properties.CreatorID = UUID.Zero;
prim.Properties.GroupID = UUID.Zero;

View File

@@ -40,7 +40,6 @@ using OpenMetaverse.StructuredData;
namespace OpenSim.Framework
{
[Serializable]
public class RegionLightShareData : ICloneable
{
public bool valid = false;
@@ -103,7 +102,6 @@ namespace OpenSim.Framework
public bool commFailTF = false;
public ConfigurationMember configMember;
public string DataStore = String.Empty;
public string RegionFile = String.Empty;
public bool isSandbox = false;
public bool Persistent = true;
@@ -508,10 +506,6 @@ namespace OpenSim.Framework
m_regionLocX = Convert.ToUInt32(locationElements[0]);
m_regionLocY = Convert.ToUInt32(locationElements[1]);
// Datastore (is this implemented? Omitted from example!)
DataStore = config.GetString("Datastore", String.Empty);
// Internal IP
IPAddress address;
@@ -610,9 +604,6 @@ namespace OpenSim.Framework
string location = String.Format("{0},{1}", m_regionLocX, m_regionLocY);
config.Set("Location", location);
if (DataStore != String.Empty)
config.Set("Datastore", DataStore);
config.Set("InternalAddress", m_internalEndPoint.Address.ToString());
config.Set("InternalPort", m_internalEndPoint.Port);
@@ -798,9 +789,6 @@ namespace OpenSim.Framework
case "sim_location_y":
m_regionLocY = (uint) configuration_result;
break;
case "datastore":
DataStore = (string) configuration_result;
break;
case "internal_ip_address":
IPAddress address = (IPAddress) configuration_result;
m_internalEndPoint = new IPEndPoint(address, 0);
@@ -951,11 +939,6 @@ namespace OpenSim.Framework
return regionInfo;
}
public int getInternalEndPointPort()
{
return m_internalEndPoint.Port;
}
public Dictionary<string, object> ToKeyValuePairs()
{
Dictionary<string, object> kvp = new Dictionary<string, object>();
@@ -974,4 +957,4 @@ namespace OpenSim.Framework
return kvp;
}
}
}
}

View File

@@ -48,13 +48,11 @@ namespace OpenSim.Framework.RegionLoader.Filesystem
public RegionInfo[] LoadRegions()
{
string regionConfigPath = Path.Combine(Util.configDir(), "Regions");
bool allowRegionless = false;
try
{
IConfig startupConfig = (IConfig)m_configSource.Configs["Startup"];
regionConfigPath = startupConfig.GetString("regionload_regionsdir", regionConfigPath).Trim();
allowRegionless = startupConfig.GetBoolean("allow_regionless", false);
}
catch (Exception)
{
@@ -70,7 +68,7 @@ namespace OpenSim.Framework.RegionLoader.Filesystem
string[] iniFiles = Directory.GetFiles(regionConfigPath, "*.ini");
// Create an empty Regions.ini if there are no existing config files.
if (!allowRegionless && configFiles.Length == 0 && iniFiles.Length == 0)
if (configFiles.Length == 0 && iniFiles.Length == 0)
{
new RegionInfo("DEFAULT REGION CONFIG", Path.Combine(regionConfigPath, "Regions.ini"), false, m_configSource);
iniFiles = Directory.GetFiles(regionConfigPath, "*.ini");

View File

@@ -48,9 +48,6 @@ namespace OpenSim.Framework.RegionLoader.Web
public RegionInfo[] LoadRegions()
{
int tries = 3;
int wait = 2000;
if (m_configSource == null)
{
m_log.Error("[WEBLOADER]: Unable to load configuration source!");
@@ -60,8 +57,6 @@ namespace OpenSim.Framework.RegionLoader.Web
{
IConfig startupConfig = (IConfig) m_configSource.Configs["Startup"];
string url = startupConfig.GetString("regionload_webserver_url", String.Empty).Trim();
bool allowRegionless = startupConfig.GetBoolean("allow_regionless", false);
if (url == String.Empty)
{
m_log.Error("[WEBLOADER]: Unable to load webserver URL - URL was empty.");
@@ -69,72 +64,37 @@ namespace OpenSim.Framework.RegionLoader.Web
}
else
{
while(tries > 0)
{
RegionInfo[] regionInfos = new RegionInfo[] {};
int regionCount = 0;
HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url);
webRequest.Timeout = 30000; //30 Second Timeout
m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url);
try
{
HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse();
m_log.Debug("[WEBLOADER]: Downloading region information...");
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
string xmlSource = String.Empty;
string tempStr = reader.ReadLine();
while (tempStr != null)
{
xmlSource = xmlSource + tempStr;
tempStr = reader.ReadLine();
}
m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " +
xmlSource.Length);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlSource);
if (xmlDoc.FirstChild.Name == "Regions")
{
regionCount = xmlDoc.FirstChild.ChildNodes.Count;
if (regionCount > 0)
{
regionInfos = new RegionInfo[regionCount];
int i;
for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++)
{
m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml);
regionInfos[i] =
new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i],false,m_configSource);
}
}
}
}
catch (WebException ex)
{
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotFound)
{
if (!allowRegionless)
throw ex;
}
else
throw ex;
}
if (regionCount > 0 | allowRegionless)
return regionInfos;
m_log.Debug("[WEBLOADER]: Request yielded no regions.");
tries--;
if (tries > 0)
HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url);
webRequest.Timeout = 30000; //30 Second Timeout
m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url);
HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse();
m_log.Debug("[WEBLOADER]: Downloading region information...");
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
string xmlSource = String.Empty;
string tempStr = reader.ReadLine();
while (tempStr != null)
{
xmlSource = xmlSource + tempStr;
tempStr = reader.ReadLine();
}
m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " +
xmlSource.Length);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlSource);
if (xmlDoc.FirstChild.Name == "Regions")
{
RegionInfo[] regionInfos = new RegionInfo[xmlDoc.FirstChild.ChildNodes.Count];
int i;
for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++)
{
m_log.Debug("[WEBLOADER]: Retrying");
System.Threading.Thread.Sleep(wait);
m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml);
regionInfos[i] =
new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i],false,m_configSource);
}
}
m_log.Error("[WEBLOADER]: No region configs were available.");
return null;
return regionInfos;
}
return null;
}
}
}

View File

@@ -397,18 +397,5 @@ namespace OpenSim.Framework
set { m_LoadedCreationID = value; }
}
private bool m_GodBlockSearch = false;
public bool GodBlockSearch
{
get { return m_GodBlockSearch; }
set { m_GodBlockSearch = value; }
}
private bool m_Casino = false;
public bool Casino
{
get { return m_Casino; }
set { m_Casino = value; }
}
}
}

View File

@@ -244,16 +244,16 @@ namespace OpenSim.Framework.Servers
protected string GetThreadsReport()
{
// This should be a constant field.
string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}";
string reportFormat = "{0,6} {1,35} {2,16} {3,10} {4,30}";
StringBuilder sb = new StringBuilder();
Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreads();
sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine);
int timeNow = Util.EnvironmentTickCount();
int timeNow = Environment.TickCount & Int32.MaxValue;
sb.AppendFormat(reportFormat, "ID", "NAME", "LAST UPDATE (MS)", "LIFETIME (MS)", "PRIORITY", "STATE");
sb.AppendFormat(reportFormat, "ID", "NAME", "LAST UPDATE (MS)", "PRIORITY", "STATE");
sb.Append(Environment.NewLine);
foreach (Watchdog.ThreadWatchdogInfo twi in threads)
@@ -262,12 +262,8 @@ namespace OpenSim.Framework.Servers
sb.AppendFormat(
reportFormat,
t.ManagedThreadId,
t.Name,
timeNow - twi.LastTick,
timeNow - twi.FirstTick,
t.Priority,
t.ThreadState);
//t.ManagedThreadId, t.Name, string.Format("{0} ms", timeNow - twi.LastTick), t.Priority, t.ThreadState);
t.ManagedThreadId, t.Name, timeNow - twi.LastTick, t.Priority, t.ThreadState);
sb.Append(Environment.NewLine);
}
@@ -304,7 +300,7 @@ namespace OpenSim.Framework.Servers
EnhanceVersionInformation();
m_log.Info("[STARTUP]: Careminster version: " + m_version + Environment.NewLine);
m_log.Info("[STARTUP]: OpenSimulator version: " + m_version + Environment.NewLine);
// clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and
// the clr version number doesn't match the project version number under Mono.
//m_log.Info("[STARTUP]: Virtual machine runtime version: " + Environment.Version + Environment.NewLine);

View File

@@ -79,6 +79,11 @@ 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; }
@@ -442,17 +447,18 @@ namespace OpenSim.Framework.Servers.HttpServer
string path = request.RawUrl;
string handlerKey = GetHandlerKey(request.HttpMethod, path);
// m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
if (TryGetStreamHandler(handlerKey, out requestHandler))
{
//m_log.Debug("[BASE HTTP SERVER]: Found Stream Handler");
if (DebugLevel >= 1)
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;
response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type.
if (requestHandler is IStreamedRequestHandler)
{
IStreamedRequestHandler streamedRequestHandler = requestHandler as IStreamedRequestHandler;
@@ -480,7 +486,6 @@ namespace OpenSim.Framework.Servers.HttpServer
string[] querystringkeys = request.QueryString.AllKeys;
string[] rHeaders = request.Headers.AllKeys;
foreach (string queryname in querystringkeys)
{
keysvals.Add(queryname, request.QueryString[queryname]);
@@ -556,6 +561,7 @@ namespace OpenSim.Framework.Servers.HttpServer
{
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
}
return;
}
@@ -566,7 +572,11 @@ namespace OpenSim.Framework.Servers.HttpServer
if (strAccept.Contains("application/llsd+xml") ||
strAccept.Contains("application/llsd+json"))
{
//m_log.Info("[Debug BASE HTTP SERVER]: Found an application/llsd+xml accept header");
if (DebugLevel >= 1)
m_log.DebugFormat(
"[BASE HTTP SERVER]: Found application/llsd+xml accept header handler for {0} {1}",
request.HttpMethod, request.Url.PathAndQuery);
HandleLLSDRequests(request, response);
return;
}
@@ -577,15 +587,24 @@ namespace OpenSim.Framework.Servers.HttpServer
{
case null:
case "text/html":
// m_log.DebugFormat(
// "[BASE HTTP SERVER]: Found a text/html content type for request {0}", 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;
case "application/llsd+xml":
case "application/xml+llsd":
case "application/llsd+json":
//m_log.Info("[Debug BASE HTTP SERVER]: found a application/llsd+xml content type");
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;
@@ -602,7 +621,11 @@ namespace OpenSim.Framework.Servers.HttpServer
//m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler");
if (DoWeHaveALLSDHandler(request.RawUrl))
{
//m_log.Info("[Debug BASE HTTP SERVER]: Found LLSD Handler");
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;
}
@@ -610,12 +633,20 @@ namespace OpenSim.Framework.Servers.HttpServer
// m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl);
if (DoWeHaveAHTTPHandler(request.RawUrl))
{
// m_log.DebugFormat("[BASE HTTP SERVER]: Found HTTP Handler for request {0}", 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;
}
//m_log.Info("[Debug BASE HTTP SERVER]: Generic XMLRPC");
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);
@@ -872,7 +903,9 @@ namespace OpenSim.Framework.Servers.HttpServer
byte[] buf = Encoding.UTF8.GetBytes("Not found");
response.KeepAlive = false;
m_log.ErrorFormat("[BASE HTTP SERVER]: Handler not found for http request {0}", request.RawUrl);
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;
@@ -978,7 +1011,6 @@ namespace OpenSim.Framework.Servers.HttpServer
if (llsdRequest != null)// && m_defaultLlsdHandler != null)
{
LLSDMethod llsdhandler = null;
if (TryGetLLSDHandler(request.RawUrl, out llsdhandler) && !LegacyLLSDLoginLibOMV)
@@ -1002,13 +1034,14 @@ namespace OpenSim.Framework.Servers.HttpServer
llsdResponse = GenerateNoLLSDHandlerResponse();
}
}
}
else
{
llsdResponse = GenerateNoLLSDHandlerResponse();
}
byte[] buffer = new byte[0];
if (llsdResponse.ToString() == "shutdown404!")
{
response.ContentType = "text/plain";
@@ -1510,34 +1543,11 @@ namespace OpenSim.Framework.Servers.HttpServer
internal void DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
{
int responsecode;
string responseString;
string contentType;
//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 == null)
{
responsecode = 500;
responseString = "No response could be obtained";
contentType = "text/plain";
responsedata = new Hashtable();
}
else
{
try
{
//m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
responsecode = (int)responsedata["int_response_code"];
responseString = (string)responsedata["str_response_string"];
contentType = (string)responsedata["content_type"];
}
catch
{
responsecode = 500;
responseString = "No response could be obtained";
contentType = "text/plain";
responsedata = new Hashtable();
}
}
if (responsedata.ContainsKey("error_status_text"))
{

View File

@@ -44,6 +44,7 @@ namespace OpenSim.Framework.Servers.HttpServer
private uint m_WorkerThreadCount = 0;
private Thread[] m_workerThreads;
private PollServiceWorkerThread[] m_PollServiceWorkerThreads;
private Thread m_watcherThread;
private bool m_running = true;
public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout)
@@ -68,12 +69,13 @@ namespace OpenSim.Framework.Servers.HttpServer
int.MaxValue);
}
Watchdog.StartThread(
this.ThreadStart,
"PollServiceWatcherThread",
ThreadPriority.Normal,
false,
1000 * 60 * 10);
m_watcherThread
= Watchdog.StartThread(
this.ThreadStart,
"PollServiceWatcherThread",
ThreadPriority.Normal,
false,
1000 * 60 * 10);
}
internal void ReQueueEvent(PollServiceHttpRequest req)

View File

@@ -29,11 +29,11 @@ namespace OpenSim
{
public class VersionInfo
{
private const string VERSION_NUMBER = "0.7.3CM";
private const Flavour VERSION_FLAVOUR = Flavour.Dev;
private const string VERSION_NUMBER = "0.7.2";
private const Flavour VERSION_FLAVOUR = Flavour.Post_Fixes;
public enum Flavour
{
{
Unknown,
Dev,
RC1,
@@ -49,7 +49,7 @@ namespace OpenSim
public static string GetVersionString(string versionNumber, Flavour flavour)
{
string versionString = "Careminster " + versionNumber + " " + flavour;
string versionString = "OpenSim " + versionNumber + " " + flavour;
return versionString.PadRight(VERSIONINFO_VERSION_LENGTH);
}

View File

@@ -27,13 +27,9 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Reflection;
using System.Xml;
using System.Diagnostics;
using System.Xml.Schema;
using System.Xml.Serialization;
using log4net;
using OpenMetaverse;
namespace OpenSim.Framework
@@ -49,155 +45,6 @@ namespace OpenSim.Framework
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem));
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Thread LockedByThread;
private string WriterStack;
private Dictionary<Thread, string> ReadLockers =
new Dictionary<Thread, string>();
/// <value>
/// An advanced lock for inventory data
/// </value>
private System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim();
/// <summary>
/// Are we readlocked by the calling thread?
/// </summary>
public bool IsReadLockedByMe()
{
if (m_itemLock.RecursiveReadCount > 0)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// Lock our inventory list for reading (many can read, one can write)
/// </summary>
public void LockItemsForRead(bool locked)
{
if (locked)
{
if (m_itemLock.IsWriteLockHeld && LockedByThread != null)
{
if (!LockedByThread.IsAlive)
{
//Locked by dead thread, reset.
m_itemLock = new System.Threading.ReaderWriterLockSlim();
}
}
if (m_itemLock.RecursiveReadCount > 0)
{
m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
try
{
StackTrace stackTrace = new StackTrace(); // get call stack
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
// write call stack method names
foreach (StackFrame stackFrame in stackFrames)
{
m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name
}
}
catch
{}
m_itemLock.ExitReadLock();
}
if (m_itemLock.RecursiveWriteCount > 0)
{
m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
m_itemLock.ExitWriteLock();
}
while (!m_itemLock.TryEnterReadLock(60000))
{
m_log.Error("Thread lock detected while trying to aquire READ lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
if (m_itemLock.IsWriteLockHeld)
{
m_itemLock = new System.Threading.ReaderWriterLockSlim();
System.Console.WriteLine("------------------------------------------");
System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
System.Console.WriteLine("------------------------------------------");
System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
System.Console.WriteLine("------------------------------------------");
LockedByThread = null;
ReadLockers.Clear();
}
}
}
else
{
if (m_itemLock.RecursiveReadCount>0)
{
m_itemLock.ExitReadLock();
}
}
}
/// <summary>
/// Lock our inventory list for writing (many can read, one can write)
/// </summary>
public void LockItemsForWrite(bool locked)
{
if (locked)
{
//Enter a write lock, wait indefinately for one to open.
if (m_itemLock.RecursiveReadCount > 0)
{
m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
m_itemLock.ExitReadLock();
}
if (m_itemLock.RecursiveWriteCount > 0)
{
m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
m_itemLock.ExitWriteLock();
}
while (!m_itemLock.TryEnterWriteLock(60000))
{
if (m_itemLock.IsWriteLockHeld)
{
m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
System.Console.WriteLine("------------------------------------------");
System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
System.Console.WriteLine("------------------------------------------");
System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
System.Console.WriteLine("------------------------------------------");
}
else
{
m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by a reader. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
System.Console.WriteLine("------------------------------------------");
System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
System.Console.WriteLine("------------------------------------------");
foreach (KeyValuePair<Thread, string> kvp in ReadLockers)
{
System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name);
System.Console.WriteLine("------------------------------------------");
}
}
m_itemLock = new System.Threading.ReaderWriterLockSlim();
ReadLockers.Clear();
}
LockedByThread = Thread.CurrentThread;
WriterStack = Environment.StackTrace;
}
else
{
if (m_itemLock.RecursiveWriteCount > 0)
{
m_itemLock.ExitWriteLock();
}
}
}
#region ICloneable Members
@@ -205,13 +52,14 @@ namespace OpenSim.Framework
{
TaskInventoryDictionary clone = new TaskInventoryDictionary();
m_itemLock.EnterReadLock();
foreach (UUID uuid in Keys)
lock (this)
{
clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
foreach (UUID uuid in Keys)
{
clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
}
}
m_itemLock.ExitReadLock();
return clone;
}

View File

@@ -121,12 +121,9 @@ namespace OpenSim.Framework
private UUID _permsGranter;
private int _permsMask;
private int _type = 0;
private UUID _oldID = UUID.Zero;
private UUID _oldID;
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 {
@@ -390,15 +387,6 @@ namespace OpenSim.Framework
}
}
public bool ScriptRunning {
get {
return _scriptRunning;
}
set {
_scriptRunning = value;
}
}
// See ICloneable
#region ICloneable Members
@@ -416,8 +404,7 @@ namespace OpenSim.Framework
/// <param name="partID">The new part ID to which this item belongs</param>
public void ResetIDs(UUID partID)
{
if (_oldID == UUID.Zero)
_oldID = ItemID;
OldItemID = ItemID;
ItemID = UUID.Random();
ParentPartID = partID;
ParentID = partID;

View File

@@ -217,12 +217,12 @@ namespace OpenSim.Framework.Tests
BannedHostNameMask = string.Empty,
BannedUserID = bannedUserId}
);
Assert.IsTrue(es.IsBanned(bannedUserId, 32), "User Should be banned but is not.");
Assert.IsFalse(es.IsBanned(UUID.Zero, 32), "User Should not be banned but is.");
Assert.IsTrue(es.IsBanned(bannedUserId), "User Should be banned but is not.");
Assert.IsFalse(es.IsBanned(UUID.Zero), "User Should not be banned but is.");
es.RemoveBan(bannedUserId);
Assert.IsFalse(es.IsBanned(bannedUserId, 32), "User Should not be banned but is.");
Assert.IsFalse(es.IsBanned(bannedUserId), "User Should not be banned but is.");
es.AddEstateManager(UUID.Zero);

View File

@@ -58,10 +58,12 @@ namespace OpenSim.Framework
/// <remarks>
/// None is used to execute the method in the same thread that made the call. It should only be used by regression
/// test code that relies on predictable event ordering.
/// RegressionTest is used by regression tests. It fires the call synchronously and does not catch any exceptions.
/// </remarks>
public enum FireAndForgetMethod
{
None,
RegressionTest,
UnsafeQueueUserWorkItem,
QueueUserWorkItem,
BeginInvoke,
@@ -431,25 +433,19 @@ namespace OpenSim.Framework
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static string Md5Hash(string data)
{
return Md5Hash(data, Encoding.Default);
}
public static string Md5Hash(string data, Encoding encoding)
{
byte[] dataMd5 = ComputeMD5Hash(data, encoding);
byte[] dataMd5 = ComputeMD5Hash(data);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < dataMd5.Length; i++)
sb.AppendFormat("{0:x2}", dataMd5[i]);
return sb.ToString();
}
private static byte[] ComputeMD5Hash(string data, Encoding encoding)
private static byte[] ComputeMD5Hash(string data)
{
MD5 md5 = MD5.Create();
return md5.ComputeHash(encoding.GetBytes(data));
return md5.ComputeHash(Encoding.Default.GetBytes(data));
}
/// <summary>
@@ -457,12 +453,6 @@ namespace OpenSim.Framework
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static string SHA1Hash(string data, Encoding enc)
{
return SHA1Hash(enc.GetBytes(data));
}
public static string SHA1Hash(string data)
{
return SHA1Hash(Encoding.Default.GetBytes(data));
@@ -1067,19 +1057,19 @@ namespace OpenSim.Framework
{
string os = String.Empty;
// if (Environment.OSVersion.Platform != PlatformID.Unix)
// {
// os = Environment.OSVersion.ToString();
// }
// else
// {
// os = ReadEtcIssue();
// }
//
// if (os.Length > 45)
// {
// os = os.Substring(0, 45);
// }
if (Environment.OSVersion.Platform != PlatformID.Unix)
{
os = Environment.OSVersion.ToString();
}
else
{
os = ReadEtcIssue();
}
if (os.Length > 45)
{
os = os.Substring(0, 45);
}
return os;
}
@@ -1212,7 +1202,7 @@ namespace OpenSim.Framework
public static Guid GetHashGuid(string data, string salt)
{
byte[] hash = ComputeMD5Hash(data + salt, Encoding.Default);
byte[] hash = ComputeMD5Hash(data + salt);
//string s = BitConverter.ToString(hash);
@@ -1556,27 +1546,38 @@ namespace OpenSim.Framework
public static void FireAndForget(System.Threading.WaitCallback callback, object obj)
{
// When OpenSim interacts with a database or sends data over the wire, it must send this in en_US culture
// so that we don't encounter problems where, for instance, data is saved with a culture that uses commas
// for decimals places but is read by a culture that treats commas as number seperators.
WaitCallback realCallback = delegate(object o)
{
Culture.SetCurrentCulture();
WaitCallback realCallback;
try
if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
{
// If we're running regression tests, then we want any exceptions to rise up to the test code.
realCallback = o => { Culture.SetCurrentCulture(); callback(o); };
}
else
{
// When OpenSim interacts with a database or sends data over the wire, it must send this in en_US culture
// so that we don't encounter problems where, for instance, data is saved with a culture that uses commas
// for decimals places but is read by a culture that treats commas as number seperators.
realCallback = o =>
{
callback(o);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[UTIL]: Continuing after async_call_method thread terminated with exception {0}{1}",
e.Message, e.StackTrace);
}
};
Culture.SetCurrentCulture();
try
{
callback(o);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[UTIL]: Continuing after async_call_method thread terminated with exception {0}{1}",
e.Message, e.StackTrace);
}
};
}
switch (FireAndForgetMethod)
{
case FireAndForgetMethod.RegressionTest:
case FireAndForgetMethod.None:
realCallback.Invoke(obj);
break;
@@ -1663,13 +1664,14 @@ namespace OpenSim.Framework
/// </summary>
public static void PrintCallStack()
{
StackTrace stackTrace = new StackTrace(); // get call stack
StackTrace stackTrace = new StackTrace(true); // get call stack
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
// write call stack method names
foreach (StackFrame stackFrame in stackFrames)
{
m_log.Debug(stackFrame.GetMethod().DeclaringType + "." + stackFrame.GetMethod().Name); // write method name
MethodBase mb = stackFrame.GetMethod();
m_log.DebugFormat("{0}.{1}:{2}", mb.DeclaringType, mb.Name, stackFrame.GetFileLineNumber()); // write method name
}
}

View File

@@ -52,13 +52,10 @@ namespace OpenSim.Framework
/// <summary>
/// Approximate tick when this thread was started.
/// </summary>
/// <remarks>
/// Not terribly good since this quickly wraps around.
/// </remarks>
public int FirstTick { get; private set; }
public int StartTick { get; private set; }
/// <summary>
/// First time this heartbeat update was invoked
/// Last time this heartbeat update was invoked
/// </summary>
public int LastTick { get; set; }
@@ -76,8 +73,8 @@ namespace OpenSim.Framework
{
Thread = thread;
Timeout = timeout;
FirstTick = Environment.TickCount & Int32.MaxValue;
LastTick = FirstTick;
StartTick = Environment.TickCount & Int32.MaxValue;
LastTick = StartTick;
}
}
@@ -240,7 +237,7 @@ namespace OpenSim.Framework
lock (m_threads)
{
int now = Environment.TickCount;
int now = Environment.TickCount & Int32.MaxValue;
foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
{
@@ -266,4 +263,4 @@ namespace OpenSim.Framework
m_watchdogTimer.Start();
}
}
}
}

View File

@@ -243,7 +243,6 @@ namespace OpenSim.Framework
catch (Exception ex)
{
errorMessage = ex.Message;
m_log.Debug("[WEB UTIL]: Exception making request: " + ex.ToString());
}
finally
{
@@ -295,10 +294,10 @@ namespace OpenSim.Framework
return result;
}
}
catch (Exception e)
catch
{
// don't need to treat this as an error... we're just guessing anyway
m_log.DebugFormat("[WEB UTIL] couldn't decode <{0}>: {1}",response,e.Message);
// m_log.DebugFormat("[WEB UTIL] couldn't decode <{0}>: {1}",response,e.Message);
}
return result;
@@ -310,7 +309,7 @@ namespace OpenSim.Framework
/// </summary>
public static OSDMap PostToService(string url, NameValueCollection data)
{
return ServiceFormRequest(url,data, 20000);
return ServiceFormRequest(url,data,10000);
}
public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout)
@@ -923,19 +922,12 @@ namespace OpenSim.Framework
/// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting
/// 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)
{
return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, 0);
}
public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout)
{
Type type = typeof(TRequest);
TResponse deserial = default(TResponse);
WebRequest request = WebRequest.Create(requestUrl);
request.Method = verb;
if (pTimeout != 0)
request.Timeout = pTimeout * 1000;
if ((verb == "POST") || (verb == "PUT"))
{

View File

@@ -31,7 +31,6 @@ using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Timers;
using log4net;
using Nini.Config;
@@ -58,16 +57,6 @@ namespace OpenSim
protected string m_consoleType = "local";
protected uint m_consolePort = 0;
/// <summary>
/// Prompt to use for simulator command line.
/// </summary>
private string m_consolePrompt;
/// <summary>
/// Regex for parsing out special characters in the prompt.
/// </summary>
private Regex m_consolePromptRegex = new Regex(@"([^\\])\\(\w)", RegexOptions.Compiled);
private string m_timedScript = "disabled";
private Timer m_scriptTimer;
@@ -96,9 +85,7 @@ namespace OpenSim
if (networkConfig != null)
m_consolePort = (uint)networkConfig.GetInt("console_port", 0);
m_timedScript = startupConfig.GetString("timer_Script", "disabled");
if (m_logFileAppender != null)
{
if (m_logFileAppender is log4net.Appender.FileAppender)
@@ -121,7 +108,6 @@ namespace OpenSim
Util.FireAndForgetMethod = asyncCallMethod;
stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 15);
m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) ");
}
if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
@@ -242,8 +228,16 @@ namespace OpenSim
+ "If an avatar name is given then only packets from that avatar are logged",
Debug);
m_console.Commands.AddCommand("region", 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("region", false, "debug scene",
"debug scene <cripting> <collisions> <physics>",
"debug scene <scripting> <collisions> <physics>",
"Turn on scene debugging", Debug);
m_console.Commands.AddCommand("region", false, "change region",
@@ -337,7 +331,7 @@ namespace OpenSim
m_console.Commands.AddCommand("region", false, "backup",
"backup",
"Persist objects to the database now", RunCommand);
"Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand);
m_console.Commands.AddCommand("region", false, "create region",
"create region [\"region name\"] <region_file.ini>",
@@ -470,7 +464,7 @@ namespace OpenSim
if (alert != null)
presence.ControllingClient.Kick(alert);
else
presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n");
presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n");
// ...and close on our side
presence.Scene.IncomingCloseAgent(presence.UUID);
@@ -788,6 +782,7 @@ namespace OpenSim
break;
case "backup":
MainConsole.Instance.Output("Triggering save of pending object updates to persistent store");
m_sceneManager.BackupCurrentScene();
break;
@@ -798,7 +793,7 @@ namespace OpenSim
if (m_sceneManager.TryGetScene(regRemoveName, out removeScene))
RemoveRegion(removeScene, false);
else
MainConsole.Instance.Output("no region with that name");
MainConsole.Instance.Output("No region with that name");
break;
case "delete-region":
@@ -845,22 +840,7 @@ namespace OpenSim
string regionName = (m_sceneManager.CurrentScene == null ? "root" : m_sceneManager.CurrentScene.RegionInfo.RegionName);
MainConsole.Instance.Output(String.Format("Currently selected region is {0}", regionName));
// m_log.DebugFormat("Original prompt is {0}", m_consolePrompt);
string prompt = m_consolePrompt;
// Replace "\R" with the region name
// Replace "\\" with "\"
prompt = m_consolePromptRegex.Replace(prompt, m =>
{
// m_log.DebugFormat("Matched {0}", m.Groups[2].Value);
if (m.Groups[2].Value == "R")
return m.Groups[1].Value + regionName;
else
return m.Groups[0].Value;
});
m_console.DefaultPrompt = prompt;
m_console.DefaultPrompt = String.Format("Region ({0}) ", regionName);
m_console.ConsoleScene = m_sceneManager.CurrentScene;
}
@@ -886,15 +866,32 @@ namespace OpenSim
if (int.TryParse(args[2], out newDebug))
{
m_sceneManager.SetDebugPacketLevelOnCurrentScene(newDebug, name);
// We provide user information elsewhere if any clients had their debug level set.
// MainConsole.Instance.OutputFormat("Debug packet level set to {0}", newDebug);
}
else
{
MainConsole.Instance.Output("packet debug should be 0..255");
MainConsole.Instance.Output("Usage: debug packet 0..255");
}
}
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 == 5)
{
@@ -917,13 +914,13 @@ namespace OpenSim
}
else
{
MainConsole.Instance.Output("debug scene <scripting> <collisions> <physics> (where inside <> is true/false)");
MainConsole.Instance.Output("Usage: debug scene <scripting> <collisions> <physics> (where inside <> is true/false)");
}
break;
default:
MainConsole.Instance.Output("Unknown debug");
MainConsole.Instance.Output("Unknown debug command");
break;
}
}
@@ -1049,6 +1046,24 @@ namespace OpenSim
MainConsole.Instance.Output(handlers.ToString());
break;
case "pending-objects":
System.Text.StringBuilder pending = new System.Text.StringBuilder("Pending objects:\n");
m_sceneManager.ForEachScene(
delegate(Scene scene)
{
scene.ForEachScenePresence(
delegate(ScenePresence sp)
{
pending.AppendFormat("{0}: {1} {2} pending\n",
scene.RegionInfo.RegionName, sp.Name, sp.SceneViewer.GetPendingObjectsCount());
}
);
}
);
MainConsole.Instance.Output(pending.ToString());
break;
case "modules":
MainConsole.Instance.Output("The currently loaded shared modules are:");
foreach (IRegionModule module in m_moduleLoader.GetLoadedSharedModules)
@@ -1056,19 +1071,6 @@ namespace OpenSim
MainConsole.Instance.Output("Shared Module: " + module.Name);
}
m_sceneManager.ForEachScene(
delegate(Scene scene)
{
m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:");
foreach (IRegionModule module in scene.Modules.Values)
{
if (!module.IsSharedModule)
{
m_log.Error("Region Module: " + module.Name);
}
}
});
MainConsole.Instance.Output("");
break;
@@ -1181,7 +1183,7 @@ namespace OpenSim
MainConsole.Instance.Output(String.Format("loadOffsets <X,Y,Z> = <{0},{1},{2}>",loadOffset.X,loadOffset.Y,loadOffset.Z));
}
}
m_sceneManager.LoadCurrentSceneFromXml(cmdparams[0], generateNewIDS, loadOffset);
m_sceneManager.LoadCurrentSceneFromXml(cmdparams[2], generateNewIDS, loadOffset);
}
else
{

View File

@@ -46,7 +46,7 @@ using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Physics.Manager;
using OpenSim.Server.Base;
using OpenSim.Server.Base;
using OpenSim.Services.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Services.UserAccountService;
@@ -92,10 +92,6 @@ namespace OpenSim
protected List<IApplicationPlugin> m_plugins = new List<IApplicationPlugin>();
private List<string> m_permsModules;
private bool m_securePermissionsLoading = true;
/// <value>
/// The config information passed into the OpenSimulator region server.
/// </value>
@@ -193,11 +189,6 @@ namespace OpenSim
CreatePIDFile(pidFile);
userStatsURI = startupConfig.GetString("Stats_URI", String.Empty);
m_securePermissionsLoading = startupConfig.GetBoolean("SecurePermissionsLoading", true);
string permissionModules = startupConfig.GetString("permissionmodules", "DefaultPermissionsModule");
m_permsModules = new List<string>(permissionModules.Split(','));
}
// Load the simulation data service
@@ -226,12 +217,6 @@ namespace OpenSim
m_moduleLoader = new ModuleLoader(m_config.Source);
LoadPlugins();
if (m_plugins.Count == 0) // We failed to load any modules. Mono Addins glitch!
{
Environment.Exit(1);
}
foreach (IApplicationPlugin plugin in m_plugins)
{
plugin.PostInitialise();
@@ -379,41 +364,7 @@ namespace OpenSim
}
else m_log.Error("[REGIONMODULES]: The new RegionModulesController is missing...");
if (m_securePermissionsLoading)
{
foreach (string s in m_permsModules)
{
if (!scene.RegionModules.ContainsKey(s))
{
bool found = false;
foreach (IRegionModule m in modules)
{
if (m.Name == s)
{
found = true;
}
}
if (!found)
{
m_log.Fatal("[MODULES]: Required module " + s + " not found.");
Environment.Exit(0);
}
}
}
}
scene.SetModuleInterfaces();
// First Step of bootreport sequence
if (scene.SnmpService != null)
{
scene.SnmpService.ColdStart(1,scene);
scene.SnmpService.LinkDown(scene);
}
if (scene.SnmpService != null)
{
scene.SnmpService.BootInfo("Loading prins", scene);
}
while (regionInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null)
SetUpEstateOwner(scene);
@@ -424,10 +375,6 @@ namespace OpenSim
// TODO : Try setting resource for region xstats here on scene
MainServer.Instance.AddStreamHandler(new Region.Framework.Scenes.RegionStatsHandler(regionInfo));
if (scene.SnmpService != null)
{
scene.SnmpService.BootInfo("Grid Registration in progress", scene);
}
try
{
scene.RegisterRegionWithGrid();
@@ -438,20 +385,11 @@ namespace OpenSim
"[STARTUP]: Registration of region with grid failed, aborting startup due to {0} {1}",
e.Message, e.StackTrace);
if (scene.SnmpService != null)
{
scene.SnmpService.Critical("Grid registration failed. Startup aborted.", scene);
}
// Carrying on now causes a lot of confusion down the
// line - we need to get the user's attention
Environment.Exit(1);
}
if (scene.SnmpService != null)
{
scene.SnmpService.BootInfo("Grid Registration done", scene);
}
scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
scene.EventManager.TriggerParcelPrimCountUpdate();
@@ -459,11 +397,6 @@ namespace OpenSim
// scripting engines.
scene.CreateScriptInstances();
if (scene.SnmpService != null)
{
scene.SnmpService.BootInfo("ScriptEngine started", scene);
}
m_sceneManager.Add(scene);
if (m_autoCreateClientStack)
@@ -472,10 +405,6 @@ namespace OpenSim
clientServer.Start();
}
if (scene.SnmpService != null)
{
scene.SnmpService.BootInfo("Initializing region modules", scene);
}
if (do_post_init)
{
foreach (IRegionModule module in modules)
@@ -487,14 +416,7 @@ namespace OpenSim
mscene = scene;
if (scene.SnmpService != null)
{
scene.SnmpService.BootInfo("The region is operational", scene);
scene.SnmpService.LinkUp(scene);
}
scene.StartTimer();
scene.StartTimerWatchdog();
scene.StartScripts();
@@ -571,11 +493,6 @@ namespace OpenSim
private void ShutdownRegion(Scene scene)
{
m_log.DebugFormat("[SHUTDOWN]: Shutting down region {0}", scene.RegionInfo.RegionName);
if (scene.SnmpService != null)
{
scene.SnmpService.BootInfo("The region is shutting down", scene);
scene.SnmpService.LinkDown(scene);
}
IRegionModulesController controller;
if (ApplicationRegistry.TryGet<IRegionModulesController>(out controller))
{
@@ -1019,7 +936,7 @@ namespace OpenSim
= MainConsole.Instance.CmdPrompt(
string.Format(
"Do you wish to join region {0} to an existing estate (yes/no)?", regInfo.RegionName),
"no",
"yes",
new List<string>() { "yes", "no" });
if (response == "no")
@@ -1035,15 +952,12 @@ namespace OpenSim
= MainConsole.Instance.CmdPrompt(
string.Format(
"Name of estate to join. Existing estate names are ({0})", string.Join(", ", estateNames.ToArray())),
"None");
if (response == "None")
continue;
estateNames[0]);
List<int> estateIDs = EstateDataService.GetEstates(response);
if (estateIDs.Count < 1)
{
MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again.");
MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again.");
continue;
}

View File

@@ -56,8 +56,6 @@ namespace OpenSim.Region.ClientStack.Linden
string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder,
byte[] data, string inventoryType, string assetType);
public delegate void UploadedBakedTexture(UUID assetID, byte[] data);
public delegate UUID UpdateItem(UUID itemID, byte[] data);
public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
@@ -97,7 +95,6 @@ namespace OpenSim.Region.ClientStack.Linden
private static readonly string m_notecardTaskUpdatePath = "0005/";
// private static readonly string m_fetchInventoryPath = "0006/";
// private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule.
// These are callbacks which will be setup by the scene so that we can update scene data when we
@@ -135,7 +132,7 @@ namespace OpenSim.Region.ClientStack.Linden
ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset;
TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
CAPSFetchInventoryDescendents = m_Scene.HandleFetchInventoryDescendentsCAPS;
GetClient = m_Scene.SceneGraph.GetControllingClient;
GetClient = m_Scene.SceneContents.GetControllingClient;
}
/// <summary>
@@ -165,8 +162,6 @@ namespace OpenSim.Region.ClientStack.Linden
IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory);
m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
m_HostCapsObj.RegisterHandler("UploadBakedTexture", new RestStreamHandler("POST", capsBase + m_uploadBakedTexturePath, UploadBakedTexture));
}
catch (Exception e)
{
@@ -239,7 +234,8 @@ namespace OpenSim.Region.ClientStack.Linden
return string.Empty;
}
Hashtable caps = m_HostCapsObj.CapsHandlers.CapsDetails;
Hashtable caps = m_HostCapsObj.CapsHandlers.GetCapsDetails(true);
// Add the external too
foreach (KeyValuePair<string, string> kvp in m_HostCapsObj.ExternalCapsHandlers)
caps[kvp.Key] = kvp.Value;
@@ -330,74 +326,6 @@ namespace OpenSim.Region.ClientStack.Linden
}
}
/// <summary>
/// Handle a request from the client for a Uri to upload a baked texture.
/// </summary>
/// <param name="request"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <param name="httpRequest"></param>
/// <param name="httpResponse"></param>
/// <returns>The upload response if the request is successful, null otherwise.</returns>
public string UploadBakedTexture(string request, string path,
string param, OSHttpRequest httpRequest,
OSHttpResponse httpResponse)
{
try
{
// m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " + m_regionName);
string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
BakedTextureUploader uploader =
new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener);
uploader.OnUpLoad += BakedTextureUploaded;
m_HostCapsObj.HttpListener.AddStreamHandler(
new BinaryStreamHandler("POST", capsBase + uploaderPath,
uploader.uploaderCaps));
string protocol = "http://";
if (m_HostCapsObj.SSLCaps)
protocol = "https://";
string uploaderURL = protocol + m_HostCapsObj.HostName + ":" +
m_HostCapsObj.Port.ToString() + capsBase + uploaderPath;
LLSDAssetUploadResponse uploadResponse =
new LLSDAssetUploadResponse();
uploadResponse.uploader = uploaderURL;
uploadResponse.state = "upload";
return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
}
catch (Exception e)
{
m_log.Error("[CAPS]: " + e.ToString());
}
return null;
}
/// <summary>
/// Called when a baked texture has been successfully uploaded by a client.
/// </summary>
/// <param name="assetID"></param>
/// <param name="data"></param>
public void BakedTextureUploaded(UUID assetID, byte[] data)
{
// m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString());
AssetBase asset;
asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
asset.Data = data;
asset.Temporary = true;
asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are
m_assetService.Store(asset);
}
/// <summary>
/// Called when new asset data for an agent inventory item update has been uploaded.
/// </summary>
@@ -1067,6 +995,7 @@ namespace OpenSim.Region.ClientStack.Linden
// XXX Maybe this should be some meaningful error packet
return null;
}
///Left this in and commented in case there are unforseen issues
//private void SaveAssetToFile(string filename, byte[] data)
//{
@@ -1090,53 +1019,4 @@ namespace OpenSim.Region.ClientStack.Linden
fs.Close();
}
}
public class BakedTextureUploader
{
public event UploadedBakedTexture OnUpLoad;
private UploadedBakedTexture handlerUpLoad = null;
private string uploaderPath = String.Empty;
private UUID newAssetID;
private IHttpServer httpListener;
public BakedTextureUploader(string path, IHttpServer httpServer)
{
newAssetID = UUID.Random();
uploaderPath = path;
httpListener = httpServer;
// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
}
/// <summary>
/// Handle raw uploaded baked texture data.
/// </summary>
/// <param name="data"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <returns></returns>
public string uploaderCaps(byte[] data, string path, string param)
{
handlerUpLoad = OnUpLoad;
if (handlerUpLoad != null)
{
Util.FireAndForget(delegate(object o) { handlerUpLoad(newAssetID, data); });
}
string res = String.Empty;
LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
uploadComplete.new_asset = newAssetID.ToString();
uploadComplete.new_inventory_item = UUID.Zero;
uploadComplete.state = "complete";
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
httpListener.RemoveStreamHandler("POST", uploaderPath);
// m_log.InfoFormat("[CAPS] baked texture upload completed for {0}",newAssetID);
return res;
}
}
}

View File

@@ -39,6 +39,7 @@ using OpenMetaverse.Messages.Linden;
using OpenMetaverse.Packets;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
@@ -58,9 +59,15 @@ namespace OpenSim.Region.ClientStack.Linden
public class EventQueueGetModule : IEventQueue, IRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected Scene m_scene = null;
/// <value>
/// Debug level.
/// </value>
public int DebugLevel { get; set; }
protected Scene m_scene;
private IConfigSource m_gConfig;
bool enabledYN = false;
bool enabledYN;
private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
@@ -97,6 +104,16 @@ namespace OpenSim.Region.ClientStack.Linden
scene.EventManager.OnClientClosed += ClientClosed;
scene.EventManager.OnMakeChildAgent += MakeChildAgent;
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
MainConsole.Instance.Commands.AddCommand(
"event queue",
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.",
HandleDebugEq);
}
else
{
@@ -128,6 +145,22 @@ namespace OpenSim.Region.ClientStack.Linden
}
#endregion
protected void HandleDebugEq(string module, string[] args)
{
int debugLevel;
if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel)))
{
MainConsole.Instance.OutputFormat("Usage: debug eq [0|1]");
}
else
{
DebugLevel = debugLevel;
MainConsole.Instance.OutputFormat(
"Set event queue debug level to {0} in {1}", DebugLevel, m_scene.RegionInfo.RegionName);
}
}
/// <summary>
/// Always returns a valid queue
/// </summary>
@@ -323,7 +356,9 @@ namespace OpenSim.Region.ClientStack.Linden
// This will persist this beyond the expiry of the caps handlers
MainServer.Instance.AddPollServiceHTTPHandler(
capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePoll, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
capsBase + EventQueueGetUUID.ToString() + "/",
EventQueuePoll,
new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
Random rnd = new Random(Environment.TickCount);
lock (m_ids)
@@ -370,12 +405,31 @@ 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);
}
array.Add(element);
lock (queue)
{
while (queue.Count > 0)
{
array.Add(queue.Dequeue());
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);
}
array.Add(element);
thisID++;
}
}
@@ -471,11 +525,29 @@ namespace OpenSim.Region.ClientStack.Linden
{
array.Add(element);
if (element is OSDMap)
{
OSDMap ev = (OSDMap)element;
m_log.DebugFormat(
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
ev["message"], m_scene.GetScenePresence(agentID).Name);
}
lock (queue)
{
while (queue.Count > 0)
{
array.Add(queue.Dequeue());
element = queue.Dequeue();
if (element is OSDMap)
{
OSDMap ev = (OSDMap)element;
m_log.DebugFormat(
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
ev["message"], m_scene.GetScenePresence(agentID).Name);
}
array.Add(element);
thisID++;
}
}
@@ -494,7 +566,8 @@ namespace OpenSim.Region.ClientStack.Linden
responsedata["content_type"] = "application/xml";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
//m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
return responsedata;
}
@@ -717,6 +790,7 @@ namespace OpenSim.Region.ClientStack.Linden
OSD item = EventQueueHelper.GroupMembership(groupUpdate);
Enqueue(item, avatarID);
}
public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID)
{
OSD item = EventQueueHelper.PlacesQuery(groupUpdate);

View File

@@ -75,20 +75,5 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
// TODO: Add more assertions for the other aspects of event queues
Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(1));
}
[Test]
public void RemoveForClient()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
UUID spId = TestHelpers.ParseTail(0x1);
SceneHelpers.AddScenePresence(m_scene, spId);
m_scene.IncomingCloseAgent(spId);
// TODO: Add more assertions for the other aspects of event queues
Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
}
}
}

View File

@@ -332,7 +332,7 @@ namespace OpenSim.Region.ClientStack.Linden
grp.IsAttachment = false;
// Required for linking
grp.RootPart.ClearUpdateSchedule();
grp.RootPart.UpdateFlag = 0;
if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos))
{
@@ -345,9 +345,8 @@ namespace OpenSim.Region.ClientStack.Linden
for (int j = 1; j < allparts.Length; j++)
{
// Required for linking
rootGroup.RootPart.ClearUpdateSchedule();
allparts[j].RootPart.ClearUpdateSchedule();
rootGroup.RootPart.UpdateFlag = 0;
allparts[j].RootPart.UpdateFlag = 0;
rootGroup.LinkToGroup(allparts[j]);
}

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;
using System.Collections.Specialized;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
using System.IO;
using System.Web;
using log4net;
using Nini.Config;
using Mono.Addins;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenMetaverse.Imaging;
using OpenSim.Framework;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
using OpenSim.Capabilities.Handlers;
namespace OpenSim.Region.ClientStack.Linden
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class UploadBakedTextureModule : INonSharedRegionModule
{
// private static readonly ILog m_log =
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// For historical reasons this is fixed, but there
/// </summary>
private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule.
private Scene m_scene;
private bool m_persistBakedTextures;
public void Initialise(IConfigSource source)
{
IConfig sconfig = source.Configs["Startup"];
if (sconfig != null)
m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
}
public void AddRegion(Scene s)
{
m_scene = s;
}
public void RemoveRegion(Scene s)
{
}
public void RegionLoaded(Scene s)
{
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
}
public void PostInitialise()
{
}
public void Close() { }
public string Name { get { return "UploadBakedTextureModule"; } }
public Type ReplaceableInterface
{
get { return null; }
}
public void RegisterCaps(UUID agentID, Caps caps)
{
caps.RegisterHandler(
"UploadBakedTexture",
new RestStreamHandler(
"POST",
"/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
new UploadBakedTextureHandler(
caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture));
}
}
}

View File

@@ -45,6 +45,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private const int IMAGE_PACKET_SIZE = 1000;
private const int FIRST_PACKET_SIZE = 600;
/// <summary>
/// If we've requested an asset but not received it in this ticks timeframe, then allow a duplicate
/// request from the client to trigger a fresh asset request.
/// </summary>
/// <remarks>
/// There are 10,000 ticks in a millisecond
/// </remarks>
private const int ASSET_REQUEST_TIMEOUT = 100000000;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public uint LastSequence;
@@ -56,9 +65,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public IAssetService AssetService;
public UUID AgentID;
public IInventoryAccessModule InventoryAccessModule;
public OpenJPEG.J2KLayerInfo[] Layers;
public bool IsDecoded;
public bool HasAsset;
private OpenJPEG.J2KLayerInfo[] m_layers;
/// <summary>
/// Has this request decoded the asset data?
/// </summary>
public bool IsDecoded { get; private set; }
/// <summary>
/// Has this request received the required asset data?
/// </summary>
public bool HasAsset { get; private set; }
/// <summary>
/// Time in milliseconds at which the asset was requested.
/// </summary>
public long AssetRequestTime { get; private set; }
public C5.IPriorityQueueHandle<J2KImage> PriorityQueueHandle;
private uint m_currentPacket;
@@ -82,7 +105,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name="packetsToSend">Maximum number of packets to send during this call</param>
/// <param name="packetsSent">Number of packets sent during this call</param>
/// <returns>True if the transfer completes at the current discard level, otherwise false</returns>
public bool SendPackets(LLClientView client, int packetsToSend, out int packetsSent)
public bool SendPackets(IClientAPI client, int packetsToSend, out int packetsSent)
{
packetsSent = 0;
@@ -102,7 +125,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
m_currentPacket = 2;
}
while (sendMore && packetsSent < packetsToSend && m_currentPacket <= m_stopPacket)
{
sendMore = SendPacket(client);
@@ -114,17 +137,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return (m_currentPacket > m_stopPacket);
}
/// <summary>
/// This is where we decide what we need to update
/// and assign the real discardLevel and packetNumber
/// assuming of course that the connected client might be bonkers
/// </summary>
public void RunUpdate()
{
//This is where we decide what we need to update
//and assign the real discardLevel and packetNumber
//assuming of course that the connected client might be bonkers
if (!HasAsset)
{
if (!m_assetRequested)
if (!m_assetRequested || DateTime.UtcNow.Ticks > AssetRequestTime + ASSET_REQUEST_TIMEOUT)
{
// m_log.DebugFormat(
// "[J2KIMAGE]: Requesting asset {0} from request in packet {1}, already requested? {2}, due to timeout? {3}",
// TextureID, LastSequence, m_assetRequested, DateTime.UtcNow.Ticks > AssetRequestTime + ASSET_REQUEST_TIMEOUT);
m_assetRequested = true;
AssetRequestTime = DateTime.UtcNow.Ticks;
AssetService.Get(TextureID.ToString(), this, AssetReceived);
}
}
@@ -137,6 +167,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
//Request decode
m_decodeRequested = true;
// m_log.DebugFormat("[J2KIMAGE]: Requesting decode of asset {0}", TextureID);
// Do we have a jpeg decoder?
if (J2KDecoder != null)
{
@@ -149,7 +182,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Send it off to the jpeg decoder
J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback);
}
}
else
{
@@ -170,14 +202,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (DiscardLevel >= 0 || m_stopPacket == 0)
{
// This shouldn't happen, but if it does, we really can't proceed
if (Layers == null)
if (m_layers == null)
{
m_log.Warn("[J2KIMAGE]: RunUpdate() called with missing Layers. Canceling texture transfer");
m_currentPacket = m_stopPacket;
return;
}
int maxDiscardLevel = Math.Max(0, Layers.Length - 1);
int maxDiscardLevel = Math.Max(0, m_layers.Length - 1);
// Treat initial texture downloads with a DiscardLevel of -1 a request for the highest DiscardLevel
if (DiscardLevel < 0 && m_stopPacket == 0)
@@ -187,9 +219,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
DiscardLevel = (sbyte)Math.Min(DiscardLevel, maxDiscardLevel);
//Calculate the m_stopPacket
if (Layers.Length > 0)
if (m_layers.Length > 0)
{
m_stopPacket = (uint)GetPacketForBytePosition(Layers[(Layers.Length - 1) - DiscardLevel].End);
m_stopPacket = (uint)GetPacketForBytePosition(m_layers[(m_layers.Length - 1) - DiscardLevel].End);
//I don't know why, but the viewer seems to expect the final packet if the file
//is just one packet bigger.
if (TexturePacketCount() == m_stopPacket + 1)
@@ -202,16 +234,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_stopPacket = TexturePacketCount();
}
//Give them at least two packets, to play nice with some broken viewers (SL also behaves this way)
if (m_stopPacket == 1 && Layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++;
m_currentPacket = StartPacket;
}
}
}
}
private bool SendFirstPacket(LLClientView client)
private bool SendFirstPacket(IClientAPI client)
{
if (client == null)
return false;
@@ -246,7 +275,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return false;
}
private bool SendPacket(LLClientView client)
private bool SendPacket(IClientAPI client)
{
if (client == null)
return false;
@@ -331,20 +360,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
if (m_currentPacket == 0)
return 0;
if (m_currentPacket == 1)
return FIRST_PACKET_SIZE;
int result = FIRST_PACKET_SIZE + ((int)m_currentPacket - 2) * IMAGE_PACKET_SIZE;
if (result < 0)
{
result = FIRST_PACKET_SIZE;
}
return result;
}
private void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers)
{
Layers = layers;
m_layers = layers;
IsDecoded = true;
RunUpdate();
}
@@ -375,9 +405,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private void AssetReceived(string id, Object sender, AssetBase asset)
{
// m_log.DebugFormat(
// "[J2KIMAGE]: Received asset {0} ({1} bytes)", id, asset != null ? asset.Data.Length.ToString() : "n/a");
UUID assetID = UUID.Zero;
if (asset != null)
{
assetID = asset.FullID;
}
else if ((InventoryAccessModule != null) && (sender != InventoryAccessModule))
{
// Unfortunately we need this here, there's no other way.
@@ -395,7 +430,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
AssetDataCallback(assetID, asset);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -39,6 +39,9 @@ using log4net;
namespace OpenSim.Region.ClientStack.LindenUDP
{
/// <summary>
/// This class handles UDP texture requests.
/// </summary>
public class LLImageManager
{
private sealed class J2KImageComparer : IComparer<J2KImage>
@@ -52,18 +55,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private bool m_shuttingdown;
private AssetBase m_missingImage;
private LLClientView m_client; //Client we're assigned to
private IAssetService m_assetCache; //Asset Cache
private IJ2KDecoder m_j2kDecodeModule; //Our J2K module
private IAssetService m_assetCache;
private IJ2KDecoder m_j2kDecodeModule;
/// <summary>
/// Priority queue for determining which image to send first.
/// </summary>
private C5.IntervalHeap<J2KImage> m_priorityQueue = new C5.IntervalHeap<J2KImage>(10, new J2KImageComparer());
/// <summary>
/// Used to control thread access to the priority queue.
/// </summary>
private object m_syncRoot = new object();
public LLClientView Client { get { return m_client; } }
/// <summary>
/// Client served by this image manager
/// </summary>
public IClientAPI Client { get; private set; }
public AssetBase MissingImage { get { return m_missingImage; } }
public LLImageManager(LLClientView client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule)
public LLImageManager(IClientAPI client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule)
{
m_client = client;
Client = client;
m_assetCache = pAssetCache;
if (pAssetCache != null)
@@ -81,7 +95,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name="newRequest"></param>
public void EnqueueReq(TextureRequestArgs newRequest)
{
//Make sure we're not shutting down..
if (!m_shuttingdown)
{
J2KImage imgrequest;
@@ -96,19 +109,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
//m_log.Debug("[TEX]: (CAN) ID=" + newRequest.RequestedAssetID);
try
try
{
lock (m_syncRoot)
m_priorityQueue.Delete(imgrequest.PriorityQueueHandle);
m_priorityQueue.Delete(imgrequest.PriorityQueueHandle);
}
catch (Exception) { }
}
else
{
//m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}",
// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
// m_log.DebugFormat(
// "[LL IMAGE MANAGER]: Received duplicate of existing request for {0}, start packet {1} from {2}",
// newRequest.RequestedAssetID, newRequest.PacketNumber, m_client.Name);
//Check the packet sequence to make sure this isn't older than
// m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}",
// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
//Check the packet sequence to make sure this isn't older than
//one we've already received
if (newRequest.requestSequence > imgrequest.LastSequence)
{
@@ -123,11 +140,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//Update the requested priority
imgrequest.Priority = newRequest.Priority;
UpdateImageInQueue(imgrequest);
//Run an update
imgrequest.RunUpdate();
// J2KImage imgrequest2 = new J2KImage(this);
// imgrequest2.J2KDecoder = m_j2kDecodeModule;
// imgrequest2.AssetService = m_assetCache;
// imgrequest2.AgentID = m_client.AgentId;
// imgrequest2.InventoryAccessModule = m_client.Scene.RequestModuleInterface<IInventoryAccessModule>();
// imgrequest2.DiscardLevel = newRequest.DiscardLevel;
// imgrequest2.StartPacket = Math.Max(1, newRequest.PacketNumber);
// imgrequest2.Priority = newRequest.Priority;
// imgrequest2.TextureID = newRequest.RequestedAssetID;
// imgrequest2.Priority = newRequest.Priority;
//
// //Add this download to the priority queue
// AddImageToQueue(imgrequest2);
//
// imgrequest2.RunUpdate();
}
// else
// {
// m_log.DebugFormat(
// "[LL IMAGE MANAGER]: Ignoring duplicate of existing request for {0} (sequence {1}) from {2} as its request sequence {3} is not greater",
// newRequest.RequestedAssetID, imgrequest.LastSequence, m_client.Name, newRequest.requestSequence);
// }
}
}
else
@@ -139,14 +179,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
else
{
// m_log.DebugFormat(
// "[LL IMAGE MANAGER]: Received request for {0}, start packet {1} from {2}",
// newRequest.RequestedAssetID, newRequest.PacketNumber, m_client.Name);
//m_log.DebugFormat("[TEX]: (NEW) ID={0}: D={1}, S={2}, P={3}",
// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
imgrequest = new J2KImage(this);
imgrequest.J2KDecoder = m_j2kDecodeModule;
imgrequest.AssetService = m_assetCache;
imgrequest.AgentID = m_client.AgentId;
imgrequest.InventoryAccessModule = m_client.Scene.RequestModuleInterface<IInventoryAccessModule>();
imgrequest.AgentID = Client.AgentId;
imgrequest.InventoryAccessModule = Client.Scene.RequestModuleInterface<IInventoryAccessModule>();
imgrequest.DiscardLevel = newRequest.DiscardLevel;
imgrequest.StartPacket = Math.Max(1, newRequest.PacketNumber);
imgrequest.Priority = newRequest.Priority;
@@ -156,7 +200,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//Add this download to the priority queue
AddImageToQueue(imgrequest);
//Run an update
imgrequest.RunUpdate();
}
}
@@ -173,12 +216,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// If null was returned, the texture priority queue is currently empty
if (image == null)
return false;
break;
if (image.IsDecoded)
{
int sent;
bool imageDone = image.SendPackets(m_client, packetsToSend - packetsSent, out sent);
bool imageDone = image.SendPackets(Client, packetsToSend - packetsSent, out sent);
packetsSent += sent;
// If the send is complete, destroy any knowledge of this transfer
@@ -191,10 +234,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// written. Undecoded textures should not be going into the priority
// queue, because a high priority undecoded texture will clog up the
// pipeline for a client
return true;
// m_log.DebugFormat(
// "[LL IMAGE MANAGER]: Exiting image queue processing early on encountering undecoded image {0}",
// image.TextureID);
break;
}
}
// if (packetsSent != 0)
// m_log.DebugFormat("[LL IMAGE MANAGER]: Processed {0} packets from image queue", packetsSent);
return m_priorityQueue.Count > 0;
}
@@ -206,9 +256,39 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_shuttingdown = true;
}
/// <summary>
/// Clear the image queue.
/// </summary>
/// <returns>The number of requests cleared.</returns>
public int ClearImageQueue()
{
int requestsDeleted;
lock (m_priorityQueue)
{
requestsDeleted = m_priorityQueue.Count;
// Surprisingly, there doesn't seem to be a clear method at this time.
while (!m_priorityQueue.IsEmpty)
m_priorityQueue.DeleteMax();
}
return requestsDeleted;
}
/// <summary>
/// Returns an array containing all the images in the queue.
/// </summary>
/// <returns></returns>
public J2KImage[] GetImages()
{
lock (m_priorityQueue)
return m_priorityQueue.ToArray();
}
#region Priority Queue Helpers
J2KImage GetHighestPriorityImage()
private J2KImage GetHighestPriorityImage()
{
J2KImage image = null;
@@ -216,34 +296,50 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
if (m_priorityQueue.Count > 0)
{
try { image = m_priorityQueue.FindMax(); }
try
{
image = m_priorityQueue.FindMax();
}
catch (Exception) { }
}
}
return image;
}
void AddImageToQueue(J2KImage image)
private void AddImageToQueue(J2KImage image)
{
image.PriorityQueueHandle = null;
lock (m_syncRoot)
try { m_priorityQueue.Add(ref image.PriorityQueueHandle, image); }
{
try
{
m_priorityQueue.Add(ref image.PriorityQueueHandle, image);
}
catch (Exception) { }
}
}
void RemoveImageFromQueue(J2KImage image)
{
lock (m_syncRoot)
try { m_priorityQueue.Delete(image.PriorityQueueHandle); }
catch (Exception) { }
}
void UpdateImageInQueue(J2KImage image)
private void RemoveImageFromQueue(J2KImage image)
{
lock (m_syncRoot)
{
try { m_priorityQueue.Replace(image.PriorityQueueHandle, image); }
try
{
m_priorityQueue.Delete(image.PriorityQueueHandle);
}
catch (Exception) { }
}
}
private void UpdateImageInQueue(J2KImage image)
{
lock (m_syncRoot)
{
try
{
m_priorityQueue.Replace(image.PriorityQueueHandle, image);
}
catch (Exception)
{
image.PriorityQueueHandle = null;
@@ -254,4 +350,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion Priority Queue Helpers
}
}
}

View File

@@ -158,7 +158,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC
private int m_maxRTO = 60000;
public bool m_deliverPackets = true;
/// <summary>
/// Default constructor
@@ -440,13 +439,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (category >= 0 && category < m_packetOutboxes.Length)
{
OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
if (m_deliverPackets == false)
{
queue.Enqueue(packet);
return true;
}
TokenBucket bucket = m_throttleCategories[category];
// Don't send this packet if there is already a packet waiting in the queue
@@ -496,8 +488,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <returns>True if any packets were sent, otherwise false</returns>
public bool DequeueOutgoing()
{
if (m_deliverPackets == false) return false;
OutgoingPacket packet;
OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
TokenBucket bucket;
@@ -530,7 +520,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// No dequeued packet waiting to be sent, try to pull one off
// this queue
queue = m_packetOutboxes[i];
if (queue != null && queue.Dequeue(out packet))
if (queue.Dequeue(out packet))
{
// A packet was pulled off the queue. See if we have
// enough tokens in the bucket to send it out

View File

@@ -328,7 +328,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// The method to call if the packet is not acked by the client. If null, then a standard
/// resend of the packet is done.
/// </param>
public void SendPacket(
public virtual void SendPacket(
LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method)
{
// CoarseLocationUpdate packets cannot be split in an automated way
@@ -492,6 +492,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60)
{
m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
RemoveClient(udpClient);
return;
@@ -611,11 +612,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
}
protected override void PacketReceived(UDPPacketBuffer buffer)
public override void PacketReceived(UDPPacketBuffer buffer)
{
// Debugging/Profiling
//try { Thread.CurrentThread.Name = "PacketReceived (" + m_scene.RegionInfo.RegionName + ")"; }
//catch (Exception) { }
// m_log.DebugFormat(
// "[LLUDPSERVER]: Packet received from {0} in {1}", buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
LLUDPClient udpClient = null;
Packet packet = null;
@@ -625,7 +628,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Decoding
if (buffer.DataLength < 7)
{
// m_log.WarnFormat(
// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}",
// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
return; // Drop undersizd packet
}
int headerLen = 7;
if (buffer.Data[6] == 0xFF)
@@ -637,7 +646,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
if (buffer.DataLength < headerLen)
{
// m_log.WarnFormat(
// "[LLUDPSERVER]: Dropping packet with malformed header received from {0} in {1}",
// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
return; // Malformed header
}
try
{
@@ -650,6 +665,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
catch (IndexOutOfRangeException)
{
// m_log.WarnFormat(
// "[LLUDPSERVER]: Dropping short packet received from {0} in {1}",
// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
return; // Drop short packet
}
catch(Exception e)
@@ -887,23 +906,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// DateTime startTime = DateTime.Now;
object[] array = (object[])o;
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
UseCircuitCodePacket packet = (UseCircuitCodePacket)array[1];
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint);
IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
// Begin the process of adding the client to the simulator
AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint);
// Send ack
SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
AuthenticateResponse sessionInfo;
if (IsClientAuthorized(uccp, out sessionInfo))
{
// Begin the process of adding the client to the simulator
IClientAPI client
= AddClient(
uccp.CircuitCode.Code,
uccp.CircuitCode.ID,
uccp.CircuitCode.SessionID,
remoteEndPoint,
sessionInfo);
// Send ack straight away to let the viewer know that the connection is active.
// The client will be null if it already exists (e.g. if on a region crossing the client sends a use
// circuit code to the existing child agent. This is not particularly obvious.
SendAckImmediate(remoteEndPoint, uccp.Header.Sequence);
// We only want to send initial data to new clients, not ones which are being converted from child to root.
if (client != null)
client.SceneAgent.SendInitialDataToMe();
}
else
{
// 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);
}
// m_log.DebugFormat(
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
}
/// <summary>
/// Send an ack immediately to the given endpoint.
/// </summary>
/// <remarks>
/// FIXME: Might be possible to use SendPacketData() like everything else, but this will require refactoring so
/// that we can obtain the UDPClient easily at this point.
/// </remarks>
/// <param name="remoteEndpoint"></param>
/// <param name="sequenceNumber"></param>
private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber)
{
PacketAckPacket ack = new PacketAckPacket();
@@ -912,6 +963,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ack.Packets[0] = new PacketAckPacket.PacketsBlock();
ack.Packets[0].ID = sequenceNumber;
SendAckImmediate(remoteEndpoint, ack);
}
public virtual void SendAckImmediate(IPEndPoint remoteEndpoint, PacketAckPacket ack)
{
byte[] packetData = ack.ToBytes();
int length = packetData.Length;
@@ -933,55 +989,39 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return sessionInfo.Authorised;
}
private void AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint)
/// <summary>
/// Add a client.
/// </summary>
/// <param name="circuitCode"></param>
/// <param name="agentID"></param>
/// <param name="sessionID"></param>
/// <param name="remoteEndPoint"></param>
/// <param name="sessionInfo"></param>
/// <returns>The client if it was added. Null if the client already existed.</returns>
protected virtual IClientAPI AddClient(
uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
{
UUID agentID = useCircuitCode.CircuitCode.ID;
UUID sessionID = useCircuitCode.CircuitCode.SessionID;
uint circuitCode = useCircuitCode.CircuitCode.Code;
IClientAPI client = null;
AuthenticateResponse sessionInfo;
if (IsClientAuthorized(useCircuitCode, out sessionInfo))
{
AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo);
}
else
{
// Don't create circuits for unauthorized clients
m_log.WarnFormat(
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
}
}
protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
{
// In priciple there shouldn't be more than one thread here, ever.
// But in case that happens, we need to synchronize this piece of code
// because it's too important
lock (this)
{
IClientAPI existingClient;
if (!m_scene.TryGetClient(agentID, out existingClient))
if (!m_scene.TryGetClient(agentID, out client))
{
// Create the LLUDPClient
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
// Create the LLClientView
LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client.OnLogout += LogoutHandler;
client.DisableFacelights = m_disableFacelights;
((LLClientView)client).DisableFacelights = m_disableFacelights;
// Start the IClientAPI
client.Start();
}
else
{
m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}",
existingClient.AgentId, remoteEndPoint, circuitCode);
}
}
return client;
}
private void RemoveClient(LLUDPClient udpClient)
@@ -991,7 +1031,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (m_scene.TryGetClient(udpClient.AgentID, out client))
{
client.IsLoggingOut = true;
client.Close(false);
client.Close();
}
}
@@ -1003,7 +1043,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
while (base.IsRunning)
{
m_scene.ThreadAlive(1);
try
{
IncomingPacket incomingPacket = null;
@@ -1046,7 +1085,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
while (base.IsRunning)
{
m_scene.ThreadAlive(2);
try
{
m_packetSent = false;

View File

@@ -44,7 +44,7 @@ namespace OpenMetaverse
/// This method is called when an incoming packet is received
/// </summary>
/// <param name="buffer">Incoming packet buffer</param>
protected abstract void PacketReceived(UDPPacketBuffer buffer);
public abstract void PacketReceived(UDPPacketBuffer buffer);
/// <summary>UDP port to bind to in server mode</summary>
protected int m_udpPort;
@@ -100,6 +100,10 @@ namespace OpenMetaverse
const int SIO_UDP_CONNRESET = -1744830452;
IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
m_log.DebugFormat(
"[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
ipep.Address, ipep.Port);
m_udpSocket = new Socket(
AddressFamily.InterNetwork,

View File

@@ -25,6 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Net;
using log4net.Config;
using Nini.Config;
@@ -32,6 +33,7 @@ using NUnit.Framework;
using OpenMetaverse;
using OpenMetaverse.Packets;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
@@ -43,19 +45,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
[TestFixture]
public class BasicCircuitTests
{
[SetUp]
public void Init()
[TestFixtureSetUp]
public void FixtureInit()
{
try
{
XmlConfigurator.Configure();
}
catch
{
// I don't care, just leave log4net off
}
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
}
[TestFixtureTearDown]
public void TearDown()
{
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
// threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
// tests really shouldn't).
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
}
// /// <summary>
// /// Add a client for testing
// /// </summary>
@@ -78,54 +83,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
// 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 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);
}
// /// <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);
// }
/// <summary>
/// Build an object name packet for test purposes
@@ -144,54 +149,69 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
return onp;
}
// /// <summary>
// /// Test adding a client to the stack
// /// </summary>
// [Test]
// public void TestAddClient()
// {
// TestHelper.InMethod();
//
// uint myCircuitCode = 123456;
// UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
// UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
//
// TestLLUDPServer testLLUDPServer;
// TestLLPacketServer testLLPacketServer;
// AgentCircuitManager acm;
// SetupStack(new MockScene(), out testLLUDPServer, out testLLPacketServer, out acm);
//
// AgentCircuitData acd = new AgentCircuitData();
// acd.AgentID = myAgentUuid;
// acd.SessionID = mySessionUuid;
//
// UseCircuitCodePacket uccp = new UseCircuitCodePacket();
//
// UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
// = new UseCircuitCodePacket.CircuitCodeBlock();
// uccpCcBlock.Code = myCircuitCode;
// uccpCcBlock.ID = myAgentUuid;
// uccpCcBlock.SessionID = mySessionUuid;
// uccp.CircuitCode = uccpCcBlock;
//
// EndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
//
// testLLUDPServer.LoadReceive(uccp, testEp);
// testLLUDPServer.ReceiveData(null);
//
// // Circuit shouildn't exist since the circuit manager doesn't know about this circuit for authentication yet
// Assert.IsFalse(testLLUDPServer.HasCircuit(myCircuitCode));
//
// acm.AddNewCircuit(myCircuitCode, acd);
//
// testLLUDPServer.LoadReceive(uccp, testEp);
// testLLUDPServer.ReceiveData(null);
//
// // Should succeed now
// Assert.IsTrue(testLLUDPServer.HasCircuit(myCircuitCode));
// Assert.IsFalse(testLLUDPServer.HasCircuit(101));
// }
//
/// <summary>
/// Test adding a client to the stack
/// </summary>
[Test]
public void TestAddClient()
{
TestHelpers.InMethod();
// XmlConfigurator.Configure();
TestScene scene = SceneHelpers.SetupScene();
uint myCircuitCode = 123456;
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
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
= 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);
llUdpServer.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);
AgentCircuitData acd = new AgentCircuitData();
acd.AgentID = myAgentUuid;
acd.SessionID = mySessionUuid;
acm.AddNewCircuit(myCircuitCode, acd);
llUdpServer.PacketReceived(upb);
// Should succeed now
ScenePresence sp = scene.GetScenePresence(myAgentUuid);
Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));
Assert.That(llUdpServer.PacketsSent.Count, Is.EqualTo(1));
Packet packet = llUdpServer.PacketsSent[0];
Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));
PacketAckPacket ackPacket = packet as PacketAckPacket;
Assert.That(ackPacket.Packets.Length, Is.EqualTo(1));
Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0));
}
// /// <summary>
// /// Test removing a client from the stack
// /// </summary>

View File

@@ -0,0 +1,160 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.IO;
using System.Net;
using System.Reflection;
using log4net.Config;
using Nini.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenMetaverse.Packets;
using OpenSim.Framework;
using OpenSim.Region.CoreModules.Agent.TextureSender;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
{
[TestFixture]
public class LLImageManagerTests
{
private AssetBase m_testImageAsset;
private Scene scene;
private LLImageManager llim;
private TestClient tc;
[TestFixtureSetUp]
public void FixtureInit()
{
using (
Stream resource
= GetType().Assembly.GetManifestResourceStream(
"OpenSim.Region.ClientStack.LindenUDP.Tests.Resources.4-tile2.jp2"))
{
using (BinaryReader br = new BinaryReader(resource))
{
m_testImageAsset
= new AssetBase(
TestHelpers.ParseTail(0x1),
"Test Image",
(sbyte)AssetType.Texture,
TestHelpers.ParseTail(0x2).ToString());
m_testImageAsset.Data = br.ReadBytes(99999999);
}
}
}
[SetUp]
public void SetUp()
{
UUID userId = TestHelpers.ParseTail(0x3);
J2KDecoderModule j2kdm = new J2KDecoderModule();
scene = SceneHelpers.SetupScene();
SceneHelpers.SetupSceneModules(scene, j2kdm);
tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene);
llim = new LLImageManager(tc, scene.AssetService, j2kdm);
}
[Test]
public void TestSendImage()
{
TestHelpers.InMethod();
// XmlConfigurator.Configure();
scene.AssetService.Store(m_testImageAsset);
TextureRequestArgs args = new TextureRequestArgs();
args.RequestedAssetID = m_testImageAsset.FullID;
args.DiscardLevel = 0;
args.PacketNumber = 1;
args.Priority = 5;
args.requestSequence = 1;
llim.EnqueueReq(args);
llim.ProcessImageQueue(20);
Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(1));
}
[Test]
public void TestDiscardImage()
{
TestHelpers.InMethod();
// XmlConfigurator.Configure();
scene.AssetService.Store(m_testImageAsset);
TextureRequestArgs args = new TextureRequestArgs();
args.RequestedAssetID = m_testImageAsset.FullID;
args.DiscardLevel = 0;
args.PacketNumber = 1;
args.Priority = 5;
args.requestSequence = 1;
llim.EnqueueReq(args);
// Now create a discard request
TextureRequestArgs discardArgs = new TextureRequestArgs();
discardArgs.RequestedAssetID = m_testImageAsset.FullID;
discardArgs.DiscardLevel = -1;
discardArgs.PacketNumber = 1;
discardArgs.Priority = 0;
discardArgs.requestSequence = 2;
llim.EnqueueReq(discardArgs);
llim.ProcessImageQueue(20);
Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(0));
}
[Test]
public void TestMissingImage()
{
TestHelpers.InMethod();
// XmlConfigurator.Configure();
TextureRequestArgs args = new TextureRequestArgs();
args.RequestedAssetID = m_testImageAsset.FullID;
args.DiscardLevel = 0;
args.PacketNumber = 1;
args.Priority = 5;
args.requestSequence = 1;
llim.EnqueueReq(args);
llim.ProcessImageQueue(20);
Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(0));
Assert.That(tc.SentImageNotInDatabasePackets.Count, Is.EqualTo(1));
}
}
}

View File

@@ -53,9 +53,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
public override void Update() {}
public override void LoadWorldMap() {}
public override void AddNewClient(IClientAPI client, PresenceType type)
public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
{
client.OnObjectName += RecordObjectNameCall;
// FIXME
return null;
}
public override void RemoveClient(UUID agentID, bool someReason) {}

View File

@@ -36,107 +36,106 @@ using OpenSim.Framework;
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
{
/// <summary>
/// This class enables synchronous testing of the LLUDPServer by allowing us to load our own data into the end
/// receive event
/// This class enables regression testing of the LLUDPServer by allowing us to intercept outgoing data.
/// </summary>
public class TestLLUDPServer : LLUDPServer
{
public List<Packet> PacketsSent { get; private set; }
public TestLLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
: base(listenIP, ref port, proxyPortOffsetParm, allow_alternate_port, configSource, circuitManager)
{}
{
PacketsSent = new List<Packet>();
}
/// <summary>
/// The chunks of data to pass to the LLUDPServer when it calls EndReceive
/// </summary>
protected Queue<ChunkSenderTuple> m_chunksToLoad = new Queue<ChunkSenderTuple>();
// protected override void BeginReceive()
// {
// if (m_chunksToLoad.Count > 0 && m_chunksToLoad.Peek().BeginReceiveException)
// {
// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
// reusedEpSender = tuple.Sender;
// throw new SocketException();
// }
// }
// protected override bool EndReceive(out int numBytes, IAsyncResult result, ref EndPoint epSender)
// {
// numBytes = 0;
//
// //m_log.Debug("Queue size " + m_chunksToLoad.Count);
//
// if (m_chunksToLoad.Count <= 0)
// return false;
//
// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
// RecvBuffer = tuple.Data;
// numBytes = tuple.Data.Length;
// epSender = tuple.Sender;
//
// return true;
// }
// public override void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)
// {
// // Don't do anything just yet
// }
/// <summary>
/// Signal that this chunk should throw an exception on Socket.BeginReceive()
/// </summary>
/// <param name="epSender"></param>
public void LoadReceiveWithBeginException(EndPoint epSender)
public override void SendAckImmediate(IPEndPoint remoteEndpoint, PacketAckPacket ack)
{
ChunkSenderTuple tuple = new ChunkSenderTuple(epSender);
tuple.BeginReceiveException = true;
m_chunksToLoad.Enqueue(tuple);
PacketsSent.Add(ack);
}
/// <summary>
/// Load some data to be received by the LLUDPServer on the next receive call
/// </summary>
/// <param name="data"></param>
/// <param name="epSender"></param>
public void LoadReceive(byte[] data, EndPoint epSender)
{
m_chunksToLoad.Enqueue(new ChunkSenderTuple(data, epSender));
}
/// <summary>
/// Load a packet to be received by the LLUDPServer on the next receive call
/// </summary>
/// <param name="packet"></param>
public void LoadReceive(Packet packet, EndPoint epSender)
{
LoadReceive(packet.ToBytes(), epSender);
}
/// <summary>
/// Calls the protected asynchronous result method. This fires out all data chunks currently queued for send
/// </summary>
/// <param name="result"></param>
public void ReceiveData(IAsyncResult result)
{
// Doesn't work the same way anymore
// while (m_chunksToLoad.Count > 0)
// OnReceivedData(result);
}
/// <summary>
/// Has a circuit with the given code been established?
/// </summary>
/// <param name="circuitCode"></param>
/// <returns></returns>
public bool HasCircuit(uint circuitCode)
{
// lock (clientCircuits_reverse)
// {
// return clientCircuits_reverse.ContainsKey(circuitCode);
// }
return true;
public override void SendPacket(
LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method)
{
PacketsSent.Add(packet);
}
//// /// <summary>
//// /// The chunks of data to pass to the LLUDPServer when it calls EndReceive
//// /// </summary>
//// protected Queue<ChunkSenderTuple> m_chunksToLoad = new Queue<ChunkSenderTuple>();
//
//// protected override void BeginReceive()
//// {
//// if (m_chunksToLoad.Count > 0 && m_chunksToLoad.Peek().BeginReceiveException)
//// {
//// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
//// reusedEpSender = tuple.Sender;
//// throw new SocketException();
//// }
//// }
//
//// protected override bool EndReceive(out int numBytes, IAsyncResult result, ref EndPoint epSender)
//// {
//// numBytes = 0;
////
//// //m_log.Debug("Queue size " + m_chunksToLoad.Count);
////
//// if (m_chunksToLoad.Count <= 0)
//// return false;
////
//// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
//// RecvBuffer = tuple.Data;
//// numBytes = tuple.Data.Length;
//// epSender = tuple.Sender;
////
//// return true;
//// }
//
//// public override void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)
//// {
//// // Don't do anything just yet
//// }
//
// /// <summary>
// /// Signal that this chunk should throw an exception on Socket.BeginReceive()
// /// </summary>
// /// <param name="epSender"></param>
// public void LoadReceiveWithBeginException(EndPoint epSender)
// {
// ChunkSenderTuple tuple = new ChunkSenderTuple(epSender);
// tuple.BeginReceiveException = true;
// m_chunksToLoad.Enqueue(tuple);
// }
//
// /// <summary>
// /// Load some data to be received by the LLUDPServer on the next receive call
// /// </summary>
// /// <param name="data"></param>
// /// <param name="epSender"></param>
// public void LoadReceive(byte[] data, EndPoint epSender)
// {
// m_chunksToLoad.Enqueue(new ChunkSenderTuple(data, epSender));
// }
//
// /// <summary>
// /// Load a packet to be received by the LLUDPServer on the next receive call
// /// </summary>
// /// <param name="packet"></param>
// public void LoadReceive(Packet packet, EndPoint epSender)
// {
// LoadReceive(packet.ToBytes(), epSender);
// }
//
// /// <summary>
// /// Calls the protected asynchronous result method. This fires out all data chunks currently queued for send
// /// </summary>
// /// <param name="result"></param>
// public void ReceiveData(IAsyncResult result)
// {
// // Doesn't work the same way anymore
//// while (m_chunksToLoad.Count > 0)
//// OnReceivedData(result);
// }
}
/// <summary>

View File

@@ -46,6 +46,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
// Fields
private bool m_dumpAssetsToFile;
private Scene m_Scene;
private UUID UserID;
private Dictionary<UUID, AssetXferUploader> XferUploaders = new Dictionary<UUID, AssetXferUploader>();
// Methods
@@ -53,6 +54,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
bool dumpAssetsToFile)
{
m_Scene = scene;
UserID = agentID;
m_dumpAssetsToFile = dumpAssetsToFile;
}

View File

@@ -28,7 +28,6 @@
using System;
using System.IO;
using System.Reflection;
using System.Collections.Generic;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
@@ -39,13 +38,6 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
{
public class AssetXferUploader
{
// Viewer's notion of the default texture
private List<UUID> defaultIDs = new List<UUID> {
new UUID("5748decc-f629-461c-9a36-a35a221fe21f"),
new UUID("7ca39b4c-bd19-4699-aff7-f93fd03d3e7b"),
new UUID("6522e74d-1660-4e7f-b601-6f48c1659a77"),
new UUID("c228d1cf-4b5d-4ba8-84f4-899a0796aa97")
};
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
@@ -73,7 +65,6 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
private UUID TransactionID = UUID.Zero;
private sbyte type = 0;
private byte wearableType = 0;
private byte[] m_oldData = null;
public ulong XferID;
private Scene m_Scene;
@@ -311,7 +302,6 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
private void DoCreateItem(uint callbackID)
{
ValidateAssets();
m_Scene.AssetService.Store(m_asset);
InventoryItemBase item = new InventoryItemBase();
@@ -332,84 +322,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
item.Flags = (uint) wearableType;
item.CreationDate = Util.UnixTimeSinceEpoch();
m_log.DebugFormat("[XFER]: Created item {0} with asset {1}",
item.ID, item.AssetID);
if (m_Scene.AddInventoryItem(item))
ourClient.SendInventoryItemCreateUpdate(item, callbackID);
else
ourClient.SendAlertMessage("Unable to create inventory item");
}
private void ValidateAssets()
{
if (m_asset.Type == (sbyte)AssetType.Clothing ||
m_asset.Type == (sbyte)AssetType.Bodypart)
{
string content = System.Text.Encoding.ASCII.GetString(m_asset.Data);
string[] lines = content.Split(new char[] {'\n'});
List<string> validated = new List<string>();
Dictionary<int, UUID> allowed = ExtractTexturesFromOldData();
int textures = 0;
foreach (string line in lines)
{
try
{
if (line.StartsWith("textures "))
{
textures = Convert.ToInt32(line.Substring(9));
validated.Add(line);
}
else if (textures > 0)
{
string[] parts = line.Split(new char[] {' '});
UUID tx = new UUID(parts[1]);
int id = Convert.ToInt32(parts[0]);
if (defaultIDs.Contains(tx) || tx == UUID.Zero ||
(allowed.ContainsKey(id) && allowed[id] == tx))
{
validated.Add(parts[0] + " " + tx.ToString());
}
else
{
int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
if ((perms & full) != full)
{
m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId);
validated.Add(parts[0] + " " + UUID.Zero.ToString());
}
else
{
validated.Add(line);
}
}
textures--;
}
else
{
validated.Add(line);
}
}
catch
{
// If it's malformed, skip it
}
}
string final = String.Join("\n", validated.ToArray());
m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final);
}
}
/// <summary>
/// Get the asset data uploaded in this transfer.
/// </summary>
@@ -418,55 +336,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
{
if (m_finished)
{
ValidateAssets();
return m_asset;
}
return null;
}
public void SetOldData(byte[] d)
{
m_oldData = d;
}
private Dictionary<int,UUID> ExtractTexturesFromOldData()
{
Dictionary<int,UUID> result = new Dictionary<int,UUID>();
if (m_oldData == null)
return result;
string content = System.Text.Encoding.ASCII.GetString(m_oldData);
string[] lines = content.Split(new char[] {'\n'});
int textures = 0;
foreach (string line in lines)
{
try
{
if (line.StartsWith("textures "))
{
textures = Convert.ToInt32(line.Substring(9));
}
else if (textures > 0)
{
string[] parts = line.Split(new char[] {' '});
UUID tx = new UUID(parts[1]);
int id = Convert.ToInt32(parts[0]);
result[id] = tx;
textures--;
}
}
catch
{
// If it's malformed, skip it
}
}
return result;
}
}
}

View File

@@ -103,6 +103,10 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
// If it's cached, return the cached results
if (m_decodedCache.TryGetValue(assetID, out result))
{
// m_log.DebugFormat(
// "[J2KDecoderModule]: Returning existing cached {0} layers j2k decode for {1}",
// result.Length, assetID);
callback(assetID, result);
}
else
@@ -129,18 +133,20 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
// Do Decode!
if (decode)
DoJ2KDecode(assetID, j2kData);
Decode(assetID, j2kData);
}
}
/// <summary>
/// Provides a synchronous decode so that caller can be assured that this executes before the next line
/// </summary>
/// <param name="assetID"></param>
/// <param name="j2kData"></param>
public void Decode(UUID assetID, byte[] j2kData)
public bool Decode(UUID assetID, byte[] j2kData)
{
DoJ2KDecode(assetID, j2kData);
OpenJPEG.J2KLayerInfo[] layers;
int components;
return Decode(assetID, j2kData, out layers, out components);
}
public bool Decode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers, out int components)
{
return DoJ2KDecode(assetID, j2kData, out layers, out components);
}
#endregion IJ2KDecoder
@@ -150,11 +156,21 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
/// </summary>
/// <param name="assetID">UUID of Asset</param>
/// <param name="j2kData">JPEG2000 data</param>
private void DoJ2KDecode(UUID assetID, byte[] j2kData)
/// <param name="layers">layer data</param>
/// <param name="components">number of components</param>
/// <returns>true if decode was successful. false otherwise.</returns>
private bool DoJ2KDecode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers, out int components)
{
// m_log.DebugFormat(
// "[J2KDecoderModule]: Doing J2K decoding of {0} bytes for asset {1}", j2kData.Length, assetID);
bool decodedSuccessfully = true;
//int DecodeTime = 0;
//DecodeTime = Environment.TickCount;
OpenJPEG.J2KLayerInfo[] layers;
// We don't get this from CSJ2K. Is it relevant?
components = 0;
if (!TryLoadCacheForAsset(assetID, out layers))
{
@@ -189,14 +205,15 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
catch (Exception ex)
{
m_log.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message);
decodedSuccessfully = false;
}
}
else
{
int components;
if (!OpenJPEG.DecodeLayerBoundaries(j2kData, out layers, out components))
{
m_log.Warn("[J2KDecoderModule]: OpenJPEG failed to decode texture " + assetID);
decodedSuccessfully = false;
}
}
@@ -205,6 +222,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults");
// Layer decoding completely failed. Guess at sane defaults for the layer boundaries
layers = CreateDefaultLayers(j2kData.Length);
decodedSuccessfully = false;
}
// Cache Decoded layers
@@ -224,6 +242,8 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
m_notifyList.Remove(assetID);
}
}
return decodedSuccessfully;
}
private OpenJPEG.J2KLayerInfo[] CreateDefaultLayers(int j2kLength)

View File

@@ -257,66 +257,53 @@ namespace Flotsam.RegionModules.AssetCache
private void UpdateFileCache(string key, AssetBase asset)
{
// TODO: Spawn this off to some seperate thread to do the actual writing
if (asset != null)
string filename = GetFileName(asset.ID);
try
{
string filename = GetFileName(key);
try
// If the file is already cached, don't cache it, just touch it so access time is updated
if (File.Exists(filename))
{
// If the file is already cached, don't cache it, just touch it so access time is updated
if (File.Exists(filename))
File.SetLastAccessTime(filename, DateTime.Now);
}
else
{
// Once we start writing, make sure we flag that we're writing
// that object to the cache so that we don't try to write the
// same file multiple times.
lock (m_CurrentlyWriting)
{
// We don't really want to know about sharing
// violations here. If the file is locked, then
// the other thread has updated the time for us.
try
{
File.SetLastAccessTime(filename, DateTime.Now);
}
catch
{
}
} else {
// Once we start writing, make sure we flag that we're writing
// that object to the cache so that we don't try to write the
// same file multiple times.
lock (m_CurrentlyWriting)
{
#if WAIT_ON_INPROGRESS_REQUESTS
if (m_CurrentlyWriting.ContainsKey(filename))
{
return;
}
else
{
m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
}
if (m_CurrentlyWriting.ContainsKey(filename))
{
return;
}
else
{
m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
}
#else
if (m_CurrentlyWriting.Contains(filename))
{
return;
}
else
{
m_CurrentlyWriting.Add(filename);
}
#endif
if (m_CurrentlyWriting.Contains(filename))
{
return;
}
Util.FireAndForget(
delegate { WriteFileCache(filename, asset); });
else
{
m_CurrentlyWriting.Add(filename);
}
#endif
}
Util.FireAndForget(
delegate { WriteFileCache(filename, asset); });
}
catch (Exception e)
{
m_log.ErrorFormat(
"[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
asset.ID, e.Message, e.StackTrace);
}
}
catch (Exception e)
{
m_log.ErrorFormat(
"[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
asset.ID, e.Message, e.StackTrace);
}
}

View File

@@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup;
m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false);
m_attMod.AttachObject(m_presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false);
// Check status on scene presence
Assert.That(m_presence.HasAttachments(), Is.True);
@@ -140,7 +140,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
m_attMod.RezSingleAttachmentFromInventory(
m_presence, attItemId, (uint)AttachmentPoint.Chest);
m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
// Check scene presence status
Assert.That(m_presence.HasAttachments(), Is.True);
@@ -174,8 +174,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory(
m_presence, attItemId, (uint)AttachmentPoint.Chest);
m_attMod.DetachSingleAttachmentToGround(m_presence, so.LocalId);
m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
m_attMod.DetachSingleAttachmentToGround(so.LocalId, m_presence.ControllingClient);
// Check scene presence status
Assert.That(m_presence.HasAttachments(), Is.False);
@@ -208,8 +208,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
m_attMod.RezSingleAttachmentFromInventory(
m_presence, attItemId, (uint)AttachmentPoint.Chest);
m_attMod.DetachSingleAttachmentToInv(m_presence, attItemId);
m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient);
// Check status on scene presence
Assert.That(m_presence.HasAttachments(), Is.False);

View File

@@ -42,7 +42,7 @@ using OpenSim.Services.Interfaces;
namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
{
public class AvatarFactoryModule : IAvatarFactoryModule, IRegionModule
public class AvatarFactoryModule : IAvatarFactory, IRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene = null;
@@ -57,19 +57,22 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
private object m_setAppearanceLock = new object();
#region IRegionModule
#region RegionModule Members
public void Initialise(Scene scene, IConfigSource config)
{
scene.RegisterModuleInterface<IAvatarFactoryModule>(this);
scene.EventManager.OnNewClient += SubscribeToClientEvents;
scene.RegisterModuleInterface<IAvatarFactory>(this);
scene.EventManager.OnNewClient += NewClient;
IConfig sconfig = config.Configs["Startup"];
if (sconfig != null)
if (config != null)
{
m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
// m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
IConfig sconfig = config.Configs["Startup"];
if (sconfig != null)
{
m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
// m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
}
}
if (m_scene == null)
@@ -98,26 +101,127 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
get { return false; }
}
private void SubscribeToClientEvents(IClientAPI client)
public void NewClient(IClientAPI client)
{
client.OnRequestWearables += Client_OnRequestWearables;
client.OnSetAppearance += Client_OnSetAppearance;
client.OnAvatarNowWearing += Client_OnAvatarNowWearing;
client.OnRequestWearables += SendWearables;
client.OnSetAppearance += SetAppearanceFromClient;
client.OnAvatarNowWearing += AvatarIsWearing;
}
public void RemoveClient(IClientAPI client)
{
// client.OnAvatarNowWearing -= AvatarIsWearing;
}
#endregion
#region IAvatarFactoryModule
public bool ValidateBakedTextureCache(IClientAPI client)
{
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp == null)
{
m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId);
return false;
}
bool defonly = true; // are we only using default textures
// Process the texture entry
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{
int idx = AvatarAppearance.BAKE_INDICES[i];
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
// if there is no texture entry, skip it
if (face == null)
continue;
// m_log.DebugFormat(
// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
// face.TextureID, idx, client.Name, client.AgentId);
// if the texture is one of the "defaults" then skip it
// this should probably be more intelligent (skirt texture doesnt matter
// if the avatar isnt wearing a skirt) but if any of the main baked
// textures is default then the rest should be as well
if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
continue;
defonly = false; // found a non-default texture reference
if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
return false;
}
m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0}", client.AgentId);
// If we only found default textures, then the appearance is not cached
return (defonly ? false : true);
}
public int RequestRebake(IScenePresence sp, bool missingTexturesOnly)
{
int texturesRebaked = 0;
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{
int idx = AvatarAppearance.BAKE_INDICES[i];
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
// if there is no texture entry, skip it
if (face == null)
continue;
// m_log.DebugFormat(
// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
// face.TextureID, idx, client.Name, client.AgentId);
// if the texture is one of the "defaults" then skip it
// this should probably be more intelligent (skirt texture doesnt matter
// if the avatar isnt wearing a skirt) but if any of the main baked
// textures is default then the rest should be as well
if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
continue;
if (missingTexturesOnly)
{
if (m_scene.AssetService.Get(face.TextureID.ToString()) != null)
continue;
else
m_log.DebugFormat(
"[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
face.TextureID, idx, sp.Name);
}
else
{
m_log.DebugFormat(
"[AVFACTORY]: Requesting rebake of {0} ({1}) for {2}.",
face.TextureID, idx, sp.Name);
}
texturesRebaked++;
sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
}
return texturesRebaked;
}
/// <summary>
/// Set appearance data (texture asset IDs and slider settings)
/// Set appearance data (texture asset IDs and slider settings) received from the client
/// </summary>
/// <param name="sp"></param>
/// <param name="client"></param>
/// <param name="texture"></param>
/// <param name="visualParam"></param>
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams)
public void SetAppearanceFromClient(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
{
// m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId);
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp == null)
{
m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId);
return;
}
// m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId);
// TODO: This is probably not necessary any longer, just assume the
// textureEntry set implies that the appearance transaction is complete
@@ -130,18 +234,18 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// Process the visual params, this may change height as well
if (visualParams != null)
{
// string[] visualParamsStrings = new string[visualParams.Length];
// for (int i = 0; i < visualParams.Length; i++)
// visualParamsStrings[i] = visualParams[i].ToString();
// m_log.DebugFormat(
// "[AVFACTORY]: Setting visual params for {0} to {1}",
// client.Name, string.Join(", ", visualParamsStrings));
// string[] visualParamsStrings = new string[visualParams.Length];
// for (int i = 0; i < visualParams.Length; i++)
// visualParamsStrings[i] = visualParams[i].ToString();
// m_log.DebugFormat(
// "[AVFACTORY]: Setting visual params for {0} to {1}",
// client.Name, string.Join(", ", visualParamsStrings));
float oldHeight = sp.Appearance.AvatarHeight;
changed = sp.Appearance.SetVisualParams(visualParams);
if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0)
((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight);
sp.SetHeight(sp.Appearance.AvatarHeight);
}
// Process the baked texture array
@@ -149,41 +253,39 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
{
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", sp.UUID);
Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(sp, false); });
if (!ValidateBakedTextureCache(sp.ControllingClient))
RequestRebake(sp, true);
// This appears to be set only in the final stage of the appearance
// update transaction. In theory, we should be able to do an immediate
// appearance send and save here.
}
// save only if there were changes, send no matter what (doesn't hurt to send twice)
if (changed)
QueueAppearanceSave(sp.ControllingClient.AgentId);
// save only if there were changes, send no matter what (doesn't hurt to send twice)
if (changed)
QueueAppearanceSave(client.AgentId);
QueueAppearanceSend(sp.ControllingClient.AgentId);
QueueAppearanceSend(client.AgentId);
}
// m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
}
public bool SendAppearance(UUID agentId)
/// <summary>
/// Checks for the existance of a baked texture asset and
/// requests the viewer rebake if the asset is not found
/// </summary>
/// <param name="client"></param>
/// <param name="textureID"></param>
/// <param name="idx"></param>
private bool CheckBakedTextureAsset(IClientAPI client, UUID textureID, int idx)
{
// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId);
ScenePresence sp = m_scene.GetScenePresence(agentId);
if (sp == null)
if (m_scene.AssetService.Get(textureID.ToString()) == null)
{
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",
textureID, idx, client.Name);
return false;
}
// Send the appearance to everyone in the scene
sp.SendAppearanceToAllOtherAgents();
// Send animations back to the avatar as well
sp.Animator.SendAnimPack();
return true;
}
@@ -197,6 +299,35 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
return GetBakedTextureFaces(sp);
}
private Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(ScenePresence sp)
{
if (sp.IsChildAgent)
return new Dictionary<BakeType, Primitive.TextureEntryFace>();
Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures
= new Dictionary<BakeType, Primitive.TextureEntryFace>();
AvatarAppearance appearance = sp.Appearance;
Primitive.TextureEntryFace[] faceTextures = appearance.Texture.FaceTextures;
foreach (int i in Enum.GetValues(typeof(BakeType)))
{
BakeType bakeType = (BakeType)i;
if (bakeType == BakeType.Unknown)
continue;
// m_log.DebugFormat(
// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
bakedTextures[bakeType] = faceTextures[ftIndex];
}
return bakedTextures;
}
public bool SaveBakedTextures(UUID agentId)
{
ScenePresence sp = m_scene.GetScenePresence(agentId);
@@ -241,17 +372,35 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
bakedTextureFace.TextureID, bakeType, sp.Name, m_scene.RegionInfo.RegionName);
}
}
// for (int i = 0; i < faceTextures.Length; i++)
// {
//// m_log.DebugFormat(
//// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
//// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
//
// if (faceTextures[i] == null)
// continue;
//
// AssetBase asset = m_scene.AssetService.Get(faceTextures[i].TextureID.ToString());
//
// if (asset != null)
// {
// asset.Temporary = false;
// m_scene.AssetService.Store(asset);
// }
// else
// {
// m_log.WarnFormat(
// "[AV FACTORY]: Baked texture {0} for {1} in {2} not found when trying to save permanently",
// faceTextures[i].TextureID, sp.Name, m_scene.RegionInfo.RegionName);
// }
// }
return true;
}
/// <summary>
/// Check for the existence of the baked texture assets.
/// </summary>
/// <param name="sp"></param>
public bool ValidateBakedTextureCache(IScenePresence sp)
{
return ValidateBakedTextureCache(sp, true);
}
#region UpdateAppearanceTimer
/// <summary>
/// Queue up a request to send appearance, makes it possible to
@@ -283,105 +432,30 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
}
}
#endregion
#region AvatarFactoryModule private methods
/// <summary>
/// Check for the existence of the baked texture assets. Request a rebake
/// unless checkonly is true.
/// </summary>
/// <param name="client"></param>
/// <param name="checkonly"></param>
private bool ValidateBakedTextureCache(IScenePresence sp, bool checkonly)
private void SaveAppearance(UUID agentid)
{
bool defonly = true; // are we only using default textures
// We must set appearance parameters in the en_US culture in order to avoid issues where values are saved
// in a culture where decimal points are commas and then reloaded in a culture which just treats them as
// number seperators.
Culture.SetCurrentCulture();
// Process the texture entry
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
ScenePresence sp = m_scene.GetScenePresence(agentid);
if (sp == null)
{
int idx = AvatarAppearance.BAKE_INDICES[i];
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
// if there is no texture entry, skip it
if (face == null)
continue;
// m_log.DebugFormat(
// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
// face.TextureID, idx, client.Name, client.AgentId);
// if the texture is one of the "defaults" then skip it
// this should probably be more intelligent (skirt texture doesnt matter
// if the avatar isnt wearing a skirt) but if any of the main baked
// textures is default then the rest should be as well
if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
continue;
defonly = false; // found a non-default texture reference
if (!CheckBakedTextureAsset(sp, face.TextureID, idx))
{
// the asset didn't exist if we are only checking, then we found a bad
// one and we're done otherwise, ask for a rebake
if (checkonly)
return false;
sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
}
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
return;
}
m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0}", sp.UUID);
// m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
// If we only found default textures, then the appearance is not cached
return (defonly ? false : true);
}
// This could take awhile since it needs to pull inventory
// We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
// assets and item asset id changes to complete.
// I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids
// multiple save requests.
SetAppearanceAssets(sp.UUID, sp.Appearance);
/// <summary>
/// Checks for the existance of a baked texture asset and
/// requests the viewer rebake if the asset is not found
/// </summary>
/// <param name="sp"></param>
/// <param name="textureID"></param>
/// <param name="idx"></param>
private bool CheckBakedTextureAsset(IScenePresence sp, UUID textureID, int idx)
{
if (m_scene.AssetService.Get(textureID.ToString()) == null)
{
m_log.InfoFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",
textureID, idx, sp.Name);
return false;
}
return true;
}
private Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(ScenePresence sp)
{
if (sp.IsChildAgent)
return new Dictionary<BakeType, Primitive.TextureEntryFace>();
Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures
= new Dictionary<BakeType, Primitive.TextureEntryFace>();
AvatarAppearance appearance = sp.Appearance;
Primitive.TextureEntryFace[] faceTextures = appearance.Texture.FaceTextures;
foreach (int i in Enum.GetValues(typeof(BakeType)))
{
BakeType bakeType = (BakeType)i;
if (bakeType == BakeType.Unknown)
continue;
// m_log.DebugFormat(
// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
bakedTextures[bakeType] = faceTextures[ftIndex];
}
return bakedTextures;
m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
}
private void HandleAppearanceUpdateTimer(object sender, EventArgs ea)
@@ -424,36 +498,97 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
m_savequeue.Remove(avatarID);
}
}
}
if (m_savequeue.Count == 0 && m_sendqueue.Count == 0)
m_updateTimer.Stop();
// We must lock both queues here so that QueueAppearanceSave() or *Send() don't m_updateTimer.Start() on
// another thread inbetween the first count calls and m_updateTimer.Stop() on this thread.
lock (m_sendqueue)
if (m_savequeue.Count == 0 && m_sendqueue.Count == 0)
m_updateTimer.Stop();
}
}
private void SaveAppearance(UUID agentid)
{
// We must set appearance parameters in the en_US culture in order to avoid issues where values are saved
// in a culture where decimal points are commas and then reloaded in a culture which just treats them as
// number seperators.
Culture.SetCurrentCulture();
#endregion
ScenePresence sp = m_scene.GetScenePresence(agentid);
/// <summary>
/// Tell the client for this scene presence what items it should be wearing now
/// </summary>
public void SendWearables(IClientAPI client)
{
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp == null)
{
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
m_log.WarnFormat("[AVFACTORY]: SendWearables unable to find presence for {0}", client.AgentId);
return;
}
// m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
// m_log.DebugFormat("[AVFACTORY]: Received request for wearables of {0}", client.Name);
// This could take awhile since it needs to pull inventory
// We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
// assets and item asset id changes to complete.
// I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids
// multiple save requests.
SetAppearanceAssets(sp.UUID, sp.Appearance);
client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
}
m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
/// <summary>
/// Update what the avatar is wearing using an item from their inventory.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void AvatarIsWearing(IClientAPI client, AvatarWearingArgs e)
{
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp == null)
{
m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing unable to find presence for {0}", client.AgentId);
return;
}
// m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId);
// we need to clean out the existing textures
sp.Appearance.ResetAppearance();
// operate on a copy of the appearance so we don't have to lock anything yet
AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
{
if (wear.Type < AvatarWearable.MAX_WEARABLES)
avatAppearance.Wearables[wear.Type].Add(wear.ItemID, UUID.Zero);
}
avatAppearance.GetAssetsFrom(sp.Appearance);
lock (m_setAppearanceLock)
{
// Update only those fields that we have changed. This is important because the viewer
// often sends AvatarIsWearing and SetAppearance packets at once, and AvatarIsWearing
// shouldn't overwrite the changes made in SetAppearance.
sp.Appearance.Wearables = avatAppearance.Wearables;
sp.Appearance.Texture = avatAppearance.Texture;
// We don't need to send the appearance here since the "iswearing" will trigger a new set
// of visual param and baked texture changes. When those complete, the new appearance will be sent
QueueAppearanceSave(client.AgentId);
}
}
public bool SendAppearance(UUID agentId)
{
// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId);
ScenePresence sp = m_scene.GetScenePresence(agentId);
if (sp == null)
{
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
return false;
}
// Send the appearance to everyone in the scene
sp.SendAppearanceToAllOtherAgents();
// Send animations back to the avatar as well
sp.Animator.SendAnimPack();
return true;
}
private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
@@ -495,83 +630,5 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
}
}
#endregion
#region Client Event Handlers
/// <summary>
/// Tell the client for this scene presence what items it should be wearing now
/// </summary>
/// <param name="client"></param>
private void Client_OnRequestWearables(IClientAPI client)
{
// m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId);
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp != null)
client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
else
m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId);
}
/// <summary>
/// Set appearance data (texture asset IDs and slider settings) received from a client
/// </summary>
/// <param name="client"></param>
/// <param name="texture"></param>
/// <param name="visualParam"></param>
private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
{
// m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp != null)
SetAppearance(sp, textureEntry, visualParams);
else
m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
}
/// <summary>
/// Update what the avatar is wearing using an item from their inventory.
/// </summary>
/// <param name="client"></param>
/// <param name="e"></param>
private void Client_OnAvatarNowWearing(IClientAPI client, AvatarWearingArgs e)
{
// m_log.WarnFormat("[AVFACTORY]: Client_OnAvatarNowWearing called for {0} ({1})", client.Name, client.AgentId);
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp == null)
{
m_log.WarnFormat("[AVFACTORY]: Client_OnAvatarNowWearing unable to find presence for {0}", client.AgentId);
return;
}
// we need to clean out the existing textures
sp.Appearance.ResetAppearance();
// operate on a copy of the appearance so we don't have to lock anything yet
AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
{
if (wear.Type < AvatarWearable.MAX_WEARABLES)
avatAppearance.Wearables[wear.Type].Add(wear.ItemID, UUID.Zero);
}
avatAppearance.GetAssetsFrom(sp.Appearance);
lock (m_setAppearanceLock)
{
// Update only those fields that we have changed. This is important because the viewer
// often sends AvatarIsWearing and SetAppearance packets at once, and AvatarIsWearing
// shouldn't overwrite the changes made in SetAppearance.
sp.Appearance.Wearables = avatAppearance.Wearables;
sp.Appearance.Texture = avatAppearance.Texture;
// We don't need to send the appearance here since the "iswearing" will trigger a new set
// of visual param and baked texture changes. When those complete, the new appearance will be sent
QueueAppearanceSave(client.AgentId);
}
}
#endregion
}
}

View File

@@ -55,13 +55,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
AvatarFactoryModule afm = new AvatarFactoryModule();
TestScene scene = SceneHelpers.SetupScene();
SceneHelpers.SetupSceneModules(scene, afm);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId);
IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT];
for (byte i = 0; i < visualParams.Length; i++)
visualParams[i] = i;
afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams);
afm.SetAppearanceFromClient(tc, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams);
ScenePresence sp = scene.GetScenePresence(userId);
// TODO: Check baked texture
Assert.AreEqual(visualParams, sp.Appearance.VisualParams);
@@ -83,7 +85,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
AvatarFactoryModule afm = new AvatarFactoryModule();
TestScene scene = SceneHelpers.SetupScene(assetCache);
SceneHelpers.SetupSceneModules(scene, afm);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId);
IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
// TODO: Use the actual BunchOfCaps functionality once we slot in the CapabilitiesModules
AssetBase uploadedAsset;
@@ -102,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
eyesFace.TextureID = eyesTextureId;
afm.SetAppearance(sp, bakedTextureEntry, visualParams);
afm.SetAppearanceFromClient(tc, bakedTextureEntry, visualParams);
afm.SaveBakedTextures(userId);
// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);

View File

@@ -45,12 +45,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
private const int DEBUG_CHANNEL = 2147483647;
private bool m_enabled = true;
private int m_saydistance = 20;
private int m_saydistance = 30;
private int m_shoutdistance = 100;
private int m_whisperdistance = 10;
private List<Scene> m_scenes = new List<Scene>();
private List<string> FreezeCache = new List<string>();
private string m_adminPrefix = "";
internal object m_syncy = new object();
internal IConfig m_config;
@@ -77,7 +76,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
m_adminPrefix = config.Configs["Chat"].GetString("admin_prefix", "");
}
public virtual void AddRegion(Scene scene)
@@ -173,15 +171,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
return;
}
if (FreezeCache.Contains(c.Sender.AgentId.ToString()))
{
if (c.Type != ChatTypeEnum.StartTyping || c.Type != ChatTypeEnum.StopTyping)
c.Sender.SendAgentAlertMessage("You may not talk as you are frozen.", false);
}
else
{
DeliverChatToAvatars(ChatSourceType.Agent, c);
}
DeliverChatToAvatars(ChatSourceType.Agent, c);
}
public virtual void OnChatFromWorld(Object sender, OSChatMessage c)
@@ -195,7 +185,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c)
{
string fromName = c.From;
string fromNamePrefix = "";
UUID fromID = UUID.Zero;
string message = c.Message;
IScene scene = c.Scene;
@@ -218,10 +207,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
fromPos = avatar.AbsolutePosition;
fromName = avatar.Name;
fromID = c.Sender.AgentId;
if (avatar.GodLevel >= 200)
{
fromNamePrefix = m_adminPrefix;
}
break;
case ChatSourceType.Object:
@@ -242,25 +228,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
foreach (Scene s in m_scenes)
{
// This should use ForEachClient, but clients don't have a position.
// If camera is moved into client, then camera position can be used
s.ForEachRootScenePresence(
s.ForEachScenePresence(
delegate(ScenePresence presence)
{
ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
if (Presencecheck != null)
{
// This will pass all chat from objects. Not
// perfect, but it will do. For now. Better
// than the prior behavior of muting all
// objects on a parcel with access restrictions
if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)
{
if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix + fromName, c.Type, message, sourceType))
receiverIDs.Add(presence.UUID);
}
}
if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType))
receiverIDs.Add(presence.UUID);
}
);
}
@@ -304,29 +276,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
}
// m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType);
HashSet<UUID> receiverIDs = new HashSet<UUID>();
if (c.Scene != null)
{
((Scene)c.Scene).ForEachRootClient
(
delegate(IClientAPI client)
{
// don't forward SayOwner chat from objects to
// non-owner agents
if ((c.Type == ChatTypeEnum.Owner) &&
(null != c.SenderObject) &&
(((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
return;
client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID,
(byte)sourceType, (byte)ChatAudibleLevel.Fully);
receiverIDs.Add(client.AgentId);
}
);
(c.Scene as Scene).EventManager.TriggerOnChatToClients(
fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully);
}
((Scene)c.Scene).ForEachRootScenePresence(
delegate(ScenePresence presence)
{
IClientAPI client = presence.ControllingClient;
// don't forward SayOwner chat from objects to
// non-owner agents
if ((c.Type == ChatTypeEnum.Owner) &&
(null != c.SenderObject) &&
(((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
return;
client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID,
(byte)sourceType, (byte)ChatAudibleLevel.Fully);
receiverIDs.Add(presence.UUID);
});
(c.Scene as Scene).EventManager.TriggerOnChatToClients(
fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully);
}
/// <summary>
@@ -369,35 +340,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
return true;
}
Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
public void ParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
{
System.Threading.Timer Timer;
if (flags == 0)
{
FreezeCache.Add(target.ToString());
System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
Timer = new System.Threading.Timer(timeCB, target, 30000, 0);
Timers.Add(target, Timer);
}
else
{
FreezeCache.Remove(target.ToString());
Timers.TryGetValue(target, out Timer);
Timers.Remove(target);
Timer.Dispose();
}
}
private void OnEndParcelFrozen(object avatar)
{
UUID target = (UUID)avatar;
FreezeCache.Remove(target.ToString());
System.Threading.Timer Timer;
Timers.TryGetValue(target, out Timer);
Timers.Remove(target);
Timer.Dispose();
}
}
}

View File

@@ -98,9 +98,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
public void SendGeneralAlert(string message)
{
m_scene.ForEachRootClient(delegate(IClientAPI client)
m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
{
client.SendAlertMessage(message);
presence.ControllingClient.SendAlertMessage(message);
});
}
@@ -162,9 +162,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
public void SendNotificationToUsersInRegion(
UUID fromAvatarID, string fromAvatarName, string message)
{
m_scene.ForEachRootClient(delegate(IClientAPI client)
m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
{
client.SendBlueBoxMessage(fromAvatarID, fromAvatarName, message);
presence.ControllingClient.SendBlueBoxMessage(fromAvatarID, fromAvatarName, message);
});
}
@@ -216,4 +216,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
return result;
}
}
}
}

View File

@@ -29,7 +29,6 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using log4net;
using Nini.Config;
using Nwc.XmlRpc;
@@ -328,7 +327,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
//m_log.DebugFormat("[XXX]: OnClientLogin!");
// Inform the friends that this user is online
StatusChange(agentID, true);
// Register that we need to send the list of online friends to this user
lock (m_NeedsListOfOnlineFriends)
m_NeedsListOfOnlineFriends.Add(agentID);
@@ -378,12 +377,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
continue;
}
im.offline = 0;
PresenceInfo presence = null;
PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
if (presences != null && presences.Length > 0)
presence = presences[0];
if (presence != null)
im.offline = 0;
im.fromAgentID = fromAgentID.Guid;
im.fromAgentName = firstname + " " + lastname;
im.offline = (byte)((presence == null) ? 1 : 0);
im.imSessionID = im.fromAgentID;
im.message = FriendshipMessage(fid);
// Finally
LocalFriendshipOffered(agentID, im);
}
@@ -603,12 +610,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
StoreFriendships(client.AgentId, friendID);
ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>();
if (ccm != null)
{
ccm.CreateCallingCard(client.AgentId, friendID, UUID.Zero);
}
// Update the local cache
RecacheFriends(client);
@@ -785,13 +786,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
(byte)OpenMetaverse.InstantMessageDialog.FriendshipAccepted, userID.ToString(), false, Vector3.Zero);
friendClient.SendInstantMessage(im);
ICallingCardModule ccm = friendClient.Scene.RequestModuleInterface<ICallingCardModule>();
if (ccm != null)
{
ccm.CreateCallingCard(friendID, userID, UUID.Zero);
}
// Update the local cache
RecacheFriends(friendClient);
@@ -814,7 +808,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// we're done
return true;
}
return false;
}
@@ -866,11 +860,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
public bool LocalStatusNotification(UUID userID, UUID friendID, bool online)
{
//m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
// m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
IClientAPI friendClient = LocateClientObject(friendID);
if (friendClient != null)
{
// the friend in this sim as root agent
// the friend in this sim as root agent
if (online)
friendClient.SendAgentOnline(new UUID[] { userID });
else
@@ -927,8 +921,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void RecacheFriends(IClientAPI client)
{
// FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
// is on the critical path for transferring an avatar from one region to another.
UUID agentID = client.AgentId;
lock (m_Friends)
{

View File

@@ -85,8 +85,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
protected override bool CacheFriends(IClientAPI client)
{
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name);
if (base.CacheFriends(client))
{
UUID agentID = client.AgentId;
@@ -111,20 +109,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
}
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting CacheFriends for {0} since detected root agent", client.Name);
return true;
}
}
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting CacheFriends for {0} since detected not root agent", client.Name);
return false;
}
public override bool SendFriendsOnlineIfNeeded(IClientAPI client)
{
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering SendFriendsOnlineIfNeeded for {0}", client.Name);
if (base.SendFriendsOnlineIfNeeded(client))
{
AgentCircuitData aCircuit = ((Scene)client.Scene).AuthenticateHandler.GetAgentCircuitData(client.AgentId);
@@ -141,25 +133,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
}
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting SendFriendsOnlineIfNeeded for {0}", client.Name);
return false;
}
protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
{
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetOnlineFriends for {0}", userID);
List<string> fList = new List<string>();
foreach (string s in friendList)
{
if (s.Length < 36)
m_log.WarnFormat(
"[HGFRIENDS MODULE]: Ignoring friend {0} ({1} chars) for {2} since identifier too short",
s, s.Length, userID);
else
fList.Add(s.Substring(0, 36));
}
fList.Add(s.Substring(0, 36));
PresenceInfo[] presence = PresenceService.GetAgents(fList.ToArray());
foreach (PresenceInfo pi in presence)
@@ -168,8 +149,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (UUID.TryParse(pi.UserID, out presenceID))
online.Add(presenceID);
}
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID);
}
//protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
@@ -259,8 +238,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
{
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID);
// First, let's divide the friends on a per-domain basis
Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>();
foreach (FriendInfo friend in friendList)
@@ -313,8 +290,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
}
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting StatusNotify for {0}", userID);
}
protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
@@ -368,8 +343,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
{
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name);
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
if (account1 != null)
return base.GetFriendsFromService(client);
@@ -384,9 +357,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
finfos = FriendsService.GetFriends(agentUUI);
m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
}
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name);
return finfos;
}
@@ -423,6 +393,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
return false;
}
protected override void StoreBackwards(UUID friendID, UUID agentID)
@@ -648,4 +619,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
}
}
}

View File

@@ -85,7 +85,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
UUID user2Id = TestHelpers.ParseTail(0x2);
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
SceneHelpers.AddScenePresence(m_scene, user2Id);
ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, user2Id);
// This fiendship is two-way but without a connector, only the first user will receive the online
// notification.

View File

@@ -31,40 +31,16 @@ using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces;
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
using System.IO;
using System.Web;
using System.Xml;
using log4net;
using Mono.Addins;
using OpenMetaverse.Messages.Linden;
using OpenMetaverse.StructuredData;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using Caps = OpenSim.Framework.Capabilities.Caps;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
namespace OpenSim.Region.CoreModules.Avatar.Gods
{
public class GodsModule : IRegionModule, IGodsModule
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>Special UUID for actions that apply to all agents</summary>
private static readonly UUID ALL_AGENTS = new UUID("44e87126-e794-4ded-05b3-7c42da3d5cdb");
protected Scene m_scene;
protected IDialogModule m_dialogModule;
protected Dictionary<UUID, string> m_capsDict =
new Dictionary<UUID, string>();
public void Initialise(Scene scene, IConfigSource source)
{
@@ -72,10 +48,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
m_scene.RegisterModuleInterface<IGodsModule>(this);
m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
m_scene.EventManager.OnClientClosed += OnClientClosed;
scene.EventManager.OnIncomingInstantMessage +=
OnIncomingInstantMessage;
}
public void PostInitialise() {}
@@ -95,54 +67,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
client.OnRequestGodlikePowers -= RequestGodlikePowers;
}
private void OnClientClosed(UUID agentID, Scene scene)
{
m_capsDict.Remove(agentID);
}
private void OnRegisterCaps(UUID agentID, Caps caps)
{
string uri = "/CAPS/" + UUID.Random();
m_capsDict[agentID] = uri;
caps.RegisterHandler("UntrustedSimulatorMessage",
new RestStreamHandler("POST", uri,
HandleUntrustedSimulatorMessage));
}
private string HandleUntrustedSimulatorMessage(string request,
string path, string param, OSHttpRequest httpRequest,
OSHttpResponse httpResponse)
{
OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request);
string message = osd["message"].AsString();
if (message == "GodKickUser")
{
OSDMap body = (OSDMap)osd["body"];
OSDArray userInfo = (OSDArray)body["UserInfo"];
OSDMap userData = (OSDMap)userInfo[0];
UUID agentID = userData["AgentID"].AsUUID();
UUID godID = userData["GodID"].AsUUID();
UUID godSessionID = userData["GodSessionID"].AsUUID();
uint kickFlags = userData["KickFlags"].AsUInteger();
string reason = userData["Reason"].AsString();
ScenePresence god = m_scene.GetScenePresence(godID);
if (god == null || god.ControllingClient.SessionId != godSessionID)
return String.Empty;
KickUser(godID, godSessionID, agentID, kickFlags, Util.StringToBytes1024(reason));
}
else
{
m_log.ErrorFormat("[GOD]: Unhandled UntrustedSimulatorMessage: {0}", message);
}
return String.Empty;
}
public void RequestGodlikePowers(
UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient)
{
@@ -191,85 +115,71 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
/// <param name="reason">The message to send to the user after it's been turned into a field</param>
public void KickUser(UUID godID, UUID sessionID, UUID agentID, uint kickflags, byte[] reason)
{
if (!m_scene.Permissions.IsGod(godID))
return;
UUID kickUserID = ALL_AGENTS;
ScenePresence sp = m_scene.GetScenePresence(agentID);
if (sp == null && agentID != ALL_AGENTS)
if (sp != null || agentID == kickUserID)
{
IMessageTransferModule transferModule =
m_scene.RequestModuleInterface<IMessageTransferModule>();
if (transferModule != null)
if (m_scene.Permissions.IsGod(godID))
{
m_log.DebugFormat("[GODS]: Sending nonlocal kill for agent {0}", agentID);
transferModule.SendInstantMessage(new GridInstantMessage(
m_scene, godID, "God", agentID, (byte)250, false,
Utils.BytesToString(reason), UUID.Zero, true,
new Vector3(), new byte[] {(byte)kickflags}),
delegate(bool success) {} );
}
return;
}
if (kickflags == 0)
{
if (agentID == kickUserID)
{
string reasonStr = Utils.BytesToString(reason);
switch (kickflags)
{
case 0:
if (sp != null)
{
KickPresence(sp, Utils.BytesToString(reason));
}
else if (agentID == ALL_AGENTS)
{
m_scene.ForEachRootScenePresence(
delegate(ScenePresence p)
{
if (p.UUID != godID && (!m_scene.Permissions.IsGod(p.UUID)))
KickPresence(p, Utils.BytesToString(reason));
}
);
}
break;
case 1:
if (sp != null)
{
sp.AllowMovement = false;
m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
m_dialogModule.SendAlertToUser(godID, "User Frozen");
}
break;
case 2:
if (sp != null)
{
sp.AllowMovement = true;
m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
m_dialogModule.SendAlertToUser(godID, "User Unfrozen");
}
break;
default:
break;
}
}
m_scene.ForEachClient(
delegate(IClientAPI controller)
{
if (controller.AgentId != godID)
controller.Kick(reasonStr);
}
);
private void KickPresence(ScenePresence sp, string reason)
{
if (sp.IsChildAgent)
return;
sp.ControllingClient.Kick(reason);
sp.Scene.IncomingCloseAgent(sp.UUID);
}
// This is a bit crude. It seems the client will be null before it actually stops the thread
// The thread will kill itself eventually :/
// Is there another way to make sure *all* clients get this 'inter region' message?
m_scene.ForEachRootScenePresence(
delegate(ScenePresence p)
{
if (p.UUID != godID)
{
// Possibly this should really be p.Close() though that method doesn't send a close
// to the client
p.ControllingClient.Close();
}
}
);
}
else
{
m_scene.SceneGraph.removeUserCount(!sp.IsChildAgent);
private void OnIncomingInstantMessage(GridInstantMessage msg)
{
if (msg.dialog == (uint)250) // Nonlocal kick
{
UUID agentID = new UUID(msg.toAgentID);
string reason = msg.message;
UUID godID = new UUID(msg.fromAgentID);
uint kickMode = (uint)msg.binaryBucket[0];
KickUser(godID, UUID.Zero, agentID, kickMode, Util.StringToBytes1024(reason));
sp.ControllingClient.Kick(Utils.BytesToString(reason));
sp.ControllingClient.Close();
}
}
if (kickflags == 1)
{
sp.AllowMovement = false;
m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
m_dialogModule.SendAlertToUser(godID, "User Frozen");
}
if (kickflags == 2)
{
sp.AllowMovement = true;
m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
m_dialogModule.SendAlertToUser(godID, "User Unfrozen");
}
}
else
{
m_dialogModule.SendAlertToUser(godID, "Kick request denied");
}
}
}
}
}
}

View File

@@ -143,19 +143,24 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
// Try root avatar only first
foreach (Scene scene in m_Scenes)
{
// m_log.DebugFormat(
// "[HG INSTANT MESSAGE]: Looking for root agent {0} in {1}",
// toAgentID.ToString(), scene.RegionInfo.RegionName);
ScenePresence sp = scene.GetScenePresence(toAgentID);
if (sp != null && !sp.IsChildAgent)
{
// Local message
// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
sp.ControllingClient.SendInstantMessage(im);
if (scene.Entities.ContainsKey(toAgentID) &&
scene.Entities[toAgentID] is ScenePresence)
{
// m_log.DebugFormat(
// "[HG INSTANT MESSAGE]: Looking for root agent {0} in {1}",
// toAgentID.ToString(), scene.RegionInfo.RegionName);
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
if (!user.IsChildAgent)
{
// Local message
// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
user.ControllingClient.SendInstantMessage(im);
// Message sent
result(true);
return;
// Message sent
result(true);
return;
}
}
}
@@ -163,14 +168,16 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
foreach (Scene scene in m_Scenes)
{
// m_log.DebugFormat(
// "[HG INSTANT MESSAGE]: Looking for child of {0} in {1}",
// toAgentID, scene.RegionInfo.RegionName);
ScenePresence sp = scene.GetScenePresence(toAgentID);
if (sp != null)
{
// "[HG INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
if (scene.Entities.ContainsKey(toAgentID) &&
scene.Entities[toAgentID] is ScenePresence)
{
// Local message
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
sp.ControllingClient.SendInstantMessage(im);
user.ControllingClient.SendInstantMessage(im);
// Message sent
result(true);
@@ -224,14 +231,19 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
bool successful = false;
foreach (Scene scene in m_Scenes)
{
ScenePresence sp = scene.GetScenePresence(toAgentID);
if(sp != null && !sp.IsChildAgent)
if (scene.Entities.ContainsKey(toAgentID) &&
scene.Entities[toAgentID] is ScenePresence)
{
scene.EventManager.TriggerIncomingInstantMessage(gim);
successful = true;
ScenePresence user =
(ScenePresence)scene.Entities[toAgentID];
if (!user.IsChildAgent)
{
scene.EventManager.TriggerIncomingInstantMessage(gim);
successful = true;
}
}
}
if (!successful)
{
// If the message can't be delivered to an agent, it
@@ -291,24 +303,41 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
return string.Empty;
}
/// <summary>
/// Find the root client for a ID
/// Find the scene for an agent
/// </summary>
public IClientAPI LocateClientObject(UUID agentID)
private Scene GetClientScene(UUID agentId)
{
lock (m_Scenes)
{
foreach (Scene scene in m_Scenes)
{
ScenePresence presence = scene.GetScenePresence(agentID);
ScenePresence presence = scene.GetScenePresence(agentId);
if (presence != null && !presence.IsChildAgent)
return presence.ControllingClient;
return scene;
}
}
return null;
}
/// <summary>
/// Find the client for a ID
/// </summary>
public IClientAPI LocateClientObject(UUID agentID)
{
Scene scene = GetClientScene(agentID);
if (scene != null)
{
ScenePresence presence = scene.GetScenePresence(agentID);
if (presence != null)
return presence.ControllingClient;
}
return null;
}
#region IInstantMessageSimConnector
public bool SendInstantMessage(GridInstantMessage im)
{

View File

@@ -151,38 +151,11 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
if (dialog != (byte)InstantMessageDialog.MessageFromAgent
&& dialog != (byte)InstantMessageDialog.StartTyping
&& dialog != (byte)InstantMessageDialog.StopTyping
&& dialog != (byte)InstantMessageDialog.BusyAutoResponse
&& dialog != (byte)InstantMessageDialog.MessageFromObject)
{
return;
}
//DateTime dt = DateTime.UtcNow;
// Ticks from UtcNow, but make it look like local. Evil, huh?
//dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
//try
//{
// // Convert that to the PST timezone
// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
//}
//catch
//{
// //m_log.Info("[OFFLINE MESSAGING]: No PST timezone found on this machine. Saving with local timestamp.");
//}
//// And make it look local again to fool the unix time util
//dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
// If client is null, this message comes from storage and IS offline
if (client != null)
im.offline = 0;
if (im.offline == 0)
im.timestamp = (uint)Util.UnixTimeSinceEpoch();
if (m_TransferModule != null)
{
if (client != null)

View File

@@ -48,7 +48,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private bool m_Enabled = false;
protected string m_MessageKey = String.Empty;
protected List<Scene> m_Scenes = new List<Scene>();
protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>();
@@ -68,17 +67,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
public virtual void Initialise(IConfigSource config)
{
IConfig cnf = config.Configs["Messaging"];
if (cnf != null)
if (cnf != null && cnf.GetString(
"MessageTransferModule", "MessageTransferModule") !=
"MessageTransferModule")
{
if (cnf.GetString("MessageTransferModule",
"MessageTransferModule") != "MessageTransferModule")
{
return;
}
m_MessageKey = cnf.GetString("MessageKey", String.Empty);
m_log.Debug("[MESSAGE TRANSFER]: Disabled by configuration");
return;
}
m_log.Debug("[MESSAGE TRANSFER]: Module enabled");
m_Enabled = true;
}
@@ -140,11 +136,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
// Try root avatar only first
foreach (Scene scene in m_Scenes)
{
// m_log.DebugFormat(
// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
// toAgentID.ToString(), scene.RegionInfo.RegionName);
ScenePresence sp = scene.GetScenePresence(toAgentID);
if (sp != null && !sp.IsChildAgent)
if (scene.Entities.ContainsKey(toAgentID) &&
scene.Entities[toAgentID] is ScenePresence)
{
// m_log.DebugFormat(
// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
@@ -153,7 +146,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
if (!user.IsChildAgent)
{
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client");
// Local message
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
user.ControllingClient.SendInstantMessage(im);
// Message sent
@@ -168,13 +162,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
{
// m_log.DebugFormat(
// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
ScenePresence sp = scene.GetScenePresence(toAgentID);
if (sp != null)
if (scene.Entities.ContainsKey(toAgentID) &&
scene.Entities[toAgentID] is ScenePresence)
{
// Local message
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client");
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
user.ControllingClient.SendInstantMessage(im);
// Message sent
@@ -257,19 +252,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
&& requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id")
&& requestData.ContainsKey("binary_bucket"))
{
if (m_MessageKey != String.Empty)
{
XmlRpcResponse error_resp = new XmlRpcResponse();
Hashtable error_respdata = new Hashtable();
error_respdata["success"] = "FALSE";
error_resp.Value = error_respdata;
if (!requestData.Contains("message_key"))
return error_resp;
if (m_MessageKey != (string)requestData["message_key"])
return error_resp;
}
// Do the easy way of validating the UUIDs
UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID);
UUID.TryParse((string)requestData["to_agent_id"], out toAgentID);
@@ -407,11 +389,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
// Trigger the Instant message in the scene.
foreach (Scene scene in m_Scenes)
{
ScenePresence sp = scene.GetScenePresence(toAgentID);
if (sp != null && !sp.IsChildAgent)
if (scene.Entities.ContainsKey(toAgentID) &&
scene.Entities[toAgentID] is ScenePresence)
{
scene.EventManager.TriggerIncomingInstantMessage(gim);
successful = true;
ScenePresence user =
(ScenePresence)scene.Entities[toAgentID];
if (!user.IsChildAgent)
{
scene.EventManager.TriggerIncomingInstantMessage(gim);
successful = true;
}
}
}
if (!successful)
@@ -446,37 +434,24 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
return resp;
}
private delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
/// <summary>
/// delegate for sending a grid instant message asynchronously
/// </summary>
public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID);
private class GIM {
public GridInstantMessage im;
public MessageResultNotification result;
};
private Queue<GIM> pendingInstantMessages = new Queue<GIM>();
private int numInstantMessageThreads = 0;
private void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
protected virtual void GridInstantMessageCompleted(IAsyncResult iar)
{
lock (pendingInstantMessages) {
if (numInstantMessageThreads >= 4) {
GIM gim = new GIM();
gim.im = im;
gim.result = result;
pendingInstantMessages.Enqueue(gim);
} else {
++ numInstantMessageThreads;
//m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: ++numInstantMessageThreads={0}", numInstantMessageThreads);
GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsyncMain;
d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
}
}
GridInstantMessageDelegate icon =
(GridInstantMessageDelegate)iar.AsyncState;
icon.EndInvoke(iar);
}
private void GridInstantMessageCompleted(IAsyncResult iar)
protected virtual void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
{
GridInstantMessageDelegate d = (GridInstantMessageDelegate)iar.AsyncState;
d.EndInvoke(iar);
GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync;
d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d);
}
/// <summary>
@@ -491,31 +466,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
/// Pass in 0 the first time this method is called. It will be called recursively with the last
/// regionhandle tried
/// </param>
private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result)
protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
{
GIM gim;
do {
try {
SendGridInstantMessageViaXMLRPCAsync(im, result, UUID.Zero);
} catch (Exception e) {
m_log.Error("[SendGridInstantMessageViaXMLRPC]: exception " + e.Message);
}
lock (pendingInstantMessages) {
if (pendingInstantMessages.Count > 0) {
gim = pendingInstantMessages.Dequeue();
im = gim.im;
result = gim.result;
} else {
gim = null;
-- numInstantMessageThreads;
//m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: --numInstantMessageThreads={0}", numInstantMessageThreads);
}
}
} while (gim != null);
}
private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
{
UUID toAgentID = new UUID(im.toAgentID);
PresenceInfo upd = null;
@@ -582,7 +534,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
if (upd != null)
{
GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(UUID.Zero,
GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID,
upd.RegionID);
if (reginfo != null)
{
@@ -731,8 +683,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
gim["position_z"] = msg.Position.Z.ToString();
gim["region_id"] = msg.RegionID.ToString();
gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None);
if (m_MessageKey != String.Empty)
gim["message_key"] = m_MessageKey;
return gim;
}

View File

@@ -171,11 +171,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
private void RetrieveInstantMessages(IClientAPI client)
{
if (m_RestURL == String.Empty)
{
return;
}
else
if (m_RestURL != "")
{
m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId);
@@ -183,61 +179,48 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
= SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>(
"POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
if (msglist != null)
if (msglist == null)
m_log.WarnFormat("[OFFLINE MESSAGING]: WARNING null message list.");
foreach (GridInstantMessage im in msglist)
{
foreach (GridInstantMessage im in msglist)
{
// client.SendInstantMessage(im);
// client.SendInstantMessage(im);
// Send through scene event manager so all modules get a chance
// to look at this message before it gets delivered.
//
// Needed for proper state management for stored group
// invitations
//
im.offline = 1;
Scene s = FindScene(client.AgentId);
if (s != null)
s.EventManager.TriggerIncomingInstantMessage(im);
}
// Send through scene event manager so all modules get a chance
// to look at this message before it gets delivered.
//
// Needed for proper state management for stored group
// invitations
//
Scene s = FindScene(client.AgentId);
if (s != null)
s.EventManager.TriggerIncomingInstantMessage(im);
}
}
}
private void UndeliveredMessage(GridInstantMessage im)
{
if (im.dialog != (byte)InstantMessageDialog.MessageFromObject &&
im.dialog != (byte)InstantMessageDialog.MessageFromAgent &&
im.dialog != (byte)InstantMessageDialog.GroupNotice &&
im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
im.dialog != (byte)InstantMessageDialog.InventoryOffered)
if ((im.offline != 0)
&& (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages)))
{
return;
}
bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
"POST", m_RestURL+"/SaveMessage/", im);
Scene scene = FindScene(new UUID(im.fromAgentID));
if (scene == null)
scene = m_SceneList[0];
if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
{
IClientAPI client = FindClient(new UUID(im.fromAgentID));
if (client == null)
return;
bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
"POST", m_RestURL+"/SaveMessage/?scope=" +
scene.RegionInfo.ScopeID.ToString(), im);
if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
{
IClientAPI client = FindClient(new UUID(im.fromAgentID));
if (client == null)
return;
client.SendInstantMessage(new GridInstantMessage(
null, new UUID(im.toAgentID),
"System", new UUID(im.fromAgentID),
(byte)InstantMessageDialog.MessageFromAgent,
"User is not logged in. "+
(success ? "Message saved." : "Message not saved"),
false, new Vector3()));
client.SendInstantMessage(new GridInstantMessage(
null, new UUID(im.toAgentID),
"System", new UUID(im.fromAgentID),
(byte)InstantMessageDialog.MessageFromAgent,
"User is not logged in. "+
(success ? "Message saved." : "Message not saved"),
false, new Vector3()));
}
}
}
}

View File

@@ -632,4 +632,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_assetsLoaded = true;
}
}
}
}

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