diff options
author | Melanie | 2009-10-22 07:12:10 +0100 |
---|---|---|
committer | Melanie | 2009-10-22 07:12:10 +0100 |
commit | c4969d47d9bbc22b37054451cd31451ca8d8c78a (patch) | |
tree | 788e3b034254bcf068ca950ee97a78b6aa07b386 /OpenSim/Region | |
parent | Merge branch 'master' into vehicles (diff) | |
parent | Remove the "mel_t" from version string (diff) | |
download | opensim-SC-c4969d47d9bbc22b37054451cd31451ca8d8c78a.zip opensim-SC-c4969d47d9bbc22b37054451cd31451ca8d8c78a.tar.gz opensim-SC-c4969d47d9bbc22b37054451cd31451ca8d8c78a.tar.bz2 opensim-SC-c4969d47d9bbc22b37054451cd31451ca8d8c78a.tar.xz |
Merge branch 'master' into vehicles
Diffstat (limited to 'OpenSim/Region')
45 files changed, 2271 insertions, 2052 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index ca6a2a3..c04b8c2 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -67,6 +67,8 @@ namespace OpenSim | |||
67 | 67 | ||
68 | IConfig startupConfig = m_config.Source.Configs["Startup"]; | 68 | IConfig startupConfig = m_config.Source.Configs["Startup"]; |
69 | 69 | ||
70 | Util.SetMaxThreads(startupConfig.GetInt("MaxPoolThreads", 15)); | ||
71 | |||
70 | if (startupConfig != null) | 72 | if (startupConfig != null) |
71 | { | 73 | { |
72 | m_startupCommandsFile = startupConfig.GetString("startup_console_commands_file", "startup_commands.txt"); | 74 | m_startupCommandsFile = startupConfig.GetString("startup_console_commands_file", "startup_commands.txt"); |
@@ -90,10 +92,17 @@ namespace OpenSim | |||
90 | appender.File = fileName; | 92 | appender.File = fileName; |
91 | appender.ActivateOptions(); | 93 | appender.ActivateOptions(); |
92 | } | 94 | } |
93 | m_log.InfoFormat("[LOGGING] Logging started to file {0}", appender.File); | 95 | m_log.InfoFormat("[LOGGING]: Logging started to file {0}", appender.File); |
94 | } | 96 | } |
95 | } | 97 | } |
98 | |||
99 | string asyncCallMethodStr = startupConfig.GetString("async_call_method", String.Empty); | ||
100 | FireAndForgetMethod asyncCallMethod; | ||
101 | if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod)) | ||
102 | Util.FireAndForgetMethod = asyncCallMethod; | ||
96 | } | 103 | } |
104 | |||
105 | m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod); | ||
97 | } | 106 | } |
98 | 107 | ||
99 | /// <summary> | 108 | /// <summary> |
@@ -628,8 +637,20 @@ namespace OpenSim | |||
628 | break; | 637 | break; |
629 | 638 | ||
630 | case "save": | 639 | case "save": |
631 | m_log.Info("Saving configuration file: " + Application.iniFilePath); | 640 | if (cmdparams.Length < 2) |
632 | m_config.Save(Application.iniFilePath); | 641 | { |
642 | m_log.Error("SYNTAX: " + n + " SAVE FILE"); | ||
643 | return; | ||
644 | } | ||
645 | |||
646 | if (Application.iniFilePath == cmdparams[1]) | ||
647 | { | ||
648 | m_log.Error("FILE can not be "+Application.iniFilePath); | ||
649 | return; | ||
650 | } | ||
651 | |||
652 | m_log.Info("Saving configuration file: " + cmdparams[1]); | ||
653 | m_config.Save(cmdparams[1]); | ||
633 | break; | 654 | break; |
634 | } | 655 | } |
635 | } | 656 | } |
diff --git a/OpenSim/Region/ClientStack/ClientStackUserSettings.cs b/OpenSim/Region/ClientStack/ClientStackUserSettings.cs deleted file mode 100644 index 231b3aa..0000000 --- a/OpenSim/Region/ClientStack/ClientStackUserSettings.cs +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | namespace OpenSim.Region.ClientStack | ||
29 | { | ||
30 | /// <summary> | ||
31 | /// Allow users to tweak parameters for the client stack. | ||
32 | /// | ||
33 | /// At the moment this is very incomplete - other tweakable settings could be added. This is also somewhat LL client | ||
34 | /// oriented right now. | ||
35 | /// </summary> | ||
36 | public class ClientStackUserSettings | ||
37 | { | ||
38 | /// <summary> | ||
39 | /// The settings for the throttle that governs how many packets in total are sent to the client. | ||
40 | /// </summary> | ||
41 | public ThrottleSettings TotalThrottleSettings; | ||
42 | |||
43 | /// <summary> | ||
44 | /// A multiplier applied to all client throttle settings. Default value is x2 (temporarily) | ||
45 | /// </summary> | ||
46 | public float ClientThrottleMultipler = 2; | ||
47 | } | ||
48 | } | ||
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 05a2a63..0ba76ec 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -45,12 +45,50 @@ using OpenSim.Region.Framework.Interfaces; | |||
45 | using OpenSim.Region.Framework.Scenes; | 45 | using OpenSim.Region.Framework.Scenes; |
46 | using OpenSim.Region.Framework.Scenes.Hypergrid; | 46 | using OpenSim.Region.Framework.Scenes.Hypergrid; |
47 | using OpenSim.Services.Interfaces; | 47 | using OpenSim.Services.Interfaces; |
48 | using Timer=System.Timers.Timer; | 48 | using Timer = System.Timers.Timer; |
49 | using AssetLandmark = OpenSim.Framework.AssetLandmark; | 49 | using AssetLandmark = OpenSim.Framework.AssetLandmark; |
50 | using Nini.Config; | 50 | using Nini.Config; |
51 | 51 | ||
52 | namespace OpenSim.Region.ClientStack.LindenUDP | 52 | namespace OpenSim.Region.ClientStack.LindenUDP |
53 | { | 53 | { |
54 | #region Enums | ||
55 | |||
56 | /// <summary> | ||
57 | /// Specifies the fields that have been changed when sending a prim or | ||
58 | /// avatar update | ||
59 | /// </summary> | ||
60 | [Flags] | ||
61 | public enum PrimUpdateFlags : uint | ||
62 | { | ||
63 | None = 0, | ||
64 | AttachmentPoint = 1 << 0, | ||
65 | Material = 1 << 1, | ||
66 | ClickAction = 1 << 2, | ||
67 | Scale = 1 << 3, | ||
68 | ParentID = 1 << 4, | ||
69 | PrimFlags = 1 << 5, | ||
70 | PrimData = 1 << 6, | ||
71 | MediaURL = 1 << 7, | ||
72 | ScratchPad = 1 << 8, | ||
73 | Textures = 1 << 9, | ||
74 | TextureAnim = 1 << 10, | ||
75 | NameValue = 1 << 11, | ||
76 | Position = 1 << 12, | ||
77 | Rotation = 1 << 13, | ||
78 | Velocity = 1 << 14, | ||
79 | Acceleration = 1 << 15, | ||
80 | AngularVelocity = 1 << 16, | ||
81 | CollisionPlane = 1 << 17, | ||
82 | Text = 1 << 18, | ||
83 | Particles = 1 << 19, | ||
84 | ExtraData = 1 << 20, | ||
85 | Sound = 1 << 21, | ||
86 | Joint = 1 << 22, | ||
87 | FullUpdate = UInt32.MaxValue | ||
88 | } | ||
89 | |||
90 | #endregion Enums | ||
91 | |||
54 | public delegate bool PacketMethod(IClientAPI simClient, Packet packet); | 92 | public delegate bool PacketMethod(IClientAPI simClient, Packet packet); |
55 | 93 | ||
56 | /// <summary> | 94 | /// <summary> |
@@ -257,6 +295,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
257 | public event MuteListRequest OnMuteListRequest; | 295 | public event MuteListRequest OnMuteListRequest; |
258 | public event AvatarInterestUpdate OnAvatarInterestUpdate; | 296 | public event AvatarInterestUpdate OnAvatarInterestUpdate; |
259 | public event PlacesQuery OnPlacesQuery; | 297 | public event PlacesQuery OnPlacesQuery; |
298 | public event AgentFOV OnAgentFOV; | ||
260 | 299 | ||
261 | #endregion Events | 300 | #endregion Events |
262 | 301 | ||
@@ -282,12 +321,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
282 | private readonly IGroupsModule m_GroupsModule; | 321 | private readonly IGroupsModule m_GroupsModule; |
283 | 322 | ||
284 | private int m_cachedTextureSerial; | 323 | private int m_cachedTextureSerial; |
285 | private Timer m_avatarTerseUpdateTimer; | 324 | private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates; |
286 | private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | 325 | private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates; |
287 | private Timer m_primTerseUpdateTimer; | 326 | private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates; |
288 | private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||
289 | private Timer m_primFullUpdateTimer; | ||
290 | private List<ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates = new List<ObjectUpdatePacket.ObjectDataBlock>(); | ||
291 | private int m_moneyBalance; | 327 | private int m_moneyBalance; |
292 | private int m_animationSequenceNumber = 1; | 328 | private int m_animationSequenceNumber = 1; |
293 | private bool m_SendLogoutPacketWhenClosing = true; | 329 | private bool m_SendLogoutPacketWhenClosing = true; |
@@ -296,26 +332,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
296 | 332 | ||
297 | protected Dictionary<PacketType, PacketMethod> m_packetHandlers = new Dictionary<PacketType, PacketMethod>(); | 333 | protected Dictionary<PacketType, PacketMethod> m_packetHandlers = new Dictionary<PacketType, PacketMethod>(); |
298 | protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers | 334 | protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers |
299 | protected IScene m_scene; | 335 | protected Scene m_scene; |
300 | protected LLImageManager m_imageManager; | 336 | protected LLImageManager m_imageManager; |
301 | protected string m_firstName; | 337 | protected string m_firstName; |
302 | protected string m_lastName; | 338 | protected string m_lastName; |
303 | protected Thread m_clientThread; | 339 | protected Thread m_clientThread; |
304 | protected Vector3 m_startpos; | 340 | protected Vector3 m_startpos; |
305 | protected EndPoint m_userEndPoint; | 341 | protected EndPoint m_userEndPoint; |
306 | protected UUID m_activeGroupID = UUID.Zero; | 342 | protected UUID m_activeGroupID; |
307 | protected string m_activeGroupName = String.Empty; | 343 | protected string m_activeGroupName = String.Empty; |
308 | protected ulong m_activeGroupPowers; | 344 | protected ulong m_activeGroupPowers; |
309 | protected Dictionary<UUID,ulong> m_groupPowers = new Dictionary<UUID, ulong>(); | 345 | protected Dictionary<UUID, ulong> m_groupPowers = new Dictionary<UUID, ulong>(); |
310 | protected int m_terrainCheckerCount; | 346 | protected int m_terrainCheckerCount; |
311 | 347 | protected uint m_agentFOVCounter; | |
312 | // LL uses these limits, apparently. Compressed terse would be 23, but we don't have that yet | 348 | |
313 | protected int m_primTerseUpdatesPerPacket = 10; | 349 | // These numbers are guesses at a decent tradeoff between responsiveness |
314 | protected int m_primFullUpdatesPerPacket = 14; | 350 | // of the interest list and throughput. Lower is more responsive, higher |
315 | protected int m_primTerseUpdateRate = 10; | 351 | // is better throughput |
316 | protected int m_primFullUpdateRate = 14; | 352 | protected int m_primTerseUpdatesPerPacket = 25; |
317 | protected int m_avatarTerseUpdateRate = 50; | 353 | protected int m_primFullUpdatesPerPacket = 100; |
318 | protected int m_avatarTerseUpdatesPerPacket = 5; | 354 | protected int m_avatarTerseUpdatesPerPacket = 10; |
319 | /// <summary>Number of texture packets to put on the queue each time the | 355 | /// <summary>Number of texture packets to put on the queue each time the |
320 | /// OnQueueEmpty event is triggered for the texture category</summary> | 356 | /// OnQueueEmpty event is triggered for the texture category</summary> |
321 | protected int m_textureSendLimit = 20; | 357 | protected int m_textureSendLimit = 20; |
@@ -369,21 +405,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
369 | /// <summary> | 405 | /// <summary> |
370 | /// Constructor | 406 | /// Constructor |
371 | /// </summary> | 407 | /// </summary> |
372 | public LLClientView(EndPoint remoteEP, IScene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo, | 408 | public LLClientView(EndPoint remoteEP, Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo, |
373 | UUID agentId, UUID sessionId, uint circuitCode) | 409 | UUID agentId, UUID sessionId, uint circuitCode) |
374 | { | 410 | { |
375 | RegisterInterface<IClientIM>(this); | 411 | RegisterInterface<IClientIM>(this); |
376 | RegisterInterface<IClientChat>(this); | 412 | RegisterInterface<IClientChat>(this); |
377 | RegisterInterface<IClientIPEndpoint>(this); | 413 | RegisterInterface<IClientIPEndpoint>(this); |
378 | 414 | ||
379 | InitDefaultAnimations(); | 415 | InitDefaultAnimations(); |
380 | 416 | ||
381 | m_scene = scene; | 417 | m_scene = scene; |
418 | |||
419 | m_avatarTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||
420 | m_primTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||
421 | m_primFullUpdates = new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>(m_scene.Entities.Count); | ||
422 | |||
382 | m_assetService = m_scene.RequestModuleInterface<IAssetService>(); | 423 | m_assetService = m_scene.RequestModuleInterface<IAssetService>(); |
383 | m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>(); | 424 | m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>(); |
384 | m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>(); | 425 | m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>(); |
385 | m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>()); | 426 | m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>()); |
386 | m_channelVersion = Utils.StringToBytes(scene.GetSimulatorVersion()); | 427 | m_channelVersion = Util.StringToBytes256(scene.GetSimulatorVersion()); |
387 | m_agentId = agentId; | 428 | m_agentId = agentId; |
388 | m_sessionId = sessionId; | 429 | m_sessionId = sessionId; |
389 | m_secureSessionId = sessionInfo.LoginInfo.SecureSession; | 430 | m_secureSessionId = sessionInfo.LoginInfo.SecureSession; |
@@ -438,25 +479,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
438 | // Remove ourselves from the scene | 479 | // Remove ourselves from the scene |
439 | m_scene.RemoveClient(AgentId); | 480 | m_scene.RemoveClient(AgentId); |
440 | 481 | ||
441 | // Shut down timers. Thread Context of this method is murky. Lock all timers | ||
442 | if (m_avatarTerseUpdateTimer.Enabled) | ||
443 | lock (m_avatarTerseUpdateTimer) | ||
444 | m_avatarTerseUpdateTimer.Stop(); | ||
445 | if (m_primTerseUpdateTimer.Enabled) | ||
446 | lock (m_primTerseUpdateTimer) | ||
447 | m_primTerseUpdateTimer.Stop(); | ||
448 | if (m_primFullUpdateTimer.Enabled) | ||
449 | lock (m_primFullUpdateTimer) | ||
450 | m_primFullUpdateTimer.Stop(); | ||
451 | |||
452 | // We can't reach into other scenes and close the connection | 482 | // We can't reach into other scenes and close the connection |
453 | // We need to do this over grid communications | 483 | // We need to do this over grid communications |
454 | //m_scene.CloseAllAgents(CircuitCode); | 484 | //m_scene.CloseAllAgents(CircuitCode); |
455 | 485 | ||
456 | m_avatarTerseUpdateTimer.Dispose(); | ||
457 | m_primTerseUpdateTimer.Dispose(); | ||
458 | m_primFullUpdateTimer.Dispose(); | ||
459 | |||
460 | // Disable UDP handling for this client | 486 | // Disable UDP handling for this client |
461 | m_udpClient.Shutdown(); | 487 | m_udpClient.Shutdown(); |
462 | 488 | ||
@@ -474,7 +500,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
474 | kupack.UserInfo.SessionID = SessionId; | 500 | kupack.UserInfo.SessionID = SessionId; |
475 | kupack.TargetBlock.TargetIP = 0; | 501 | kupack.TargetBlock.TargetIP = 0; |
476 | kupack.TargetBlock.TargetPort = 0; | 502 | kupack.TargetBlock.TargetPort = 0; |
477 | kupack.UserInfo.Reason = Utils.StringToBytes(message); | 503 | kupack.UserInfo.Reason = Util.StringToBytes256(message); |
478 | OutPacket(kupack, ThrottleOutPacketType.Task); | 504 | OutPacket(kupack, ThrottleOutPacketType.Task); |
479 | // You must sleep here or users get no message! | 505 | // You must sleep here or users get no message! |
480 | Thread.Sleep(500); | 506 | Thread.Sleep(500); |
@@ -483,18 +509,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
483 | 509 | ||
484 | public void Stop() | 510 | public void Stop() |
485 | { | 511 | { |
486 | // Shut down timers. Thread Context is Murky, lock all timers! | ||
487 | if (m_avatarTerseUpdateTimer.Enabled) | ||
488 | lock (m_avatarTerseUpdateTimer) | ||
489 | m_avatarTerseUpdateTimer.Stop(); | ||
490 | |||
491 | if (m_primTerseUpdateTimer.Enabled) | ||
492 | lock (m_primTerseUpdateTimer) | ||
493 | m_primTerseUpdateTimer.Stop(); | ||
494 | 512 | ||
495 | if (m_primFullUpdateTimer.Enabled) | ||
496 | lock (m_primFullUpdateTimer) | ||
497 | m_primFullUpdateTimer.Stop(); | ||
498 | } | 513 | } |
499 | 514 | ||
500 | #endregion Client Methods | 515 | #endregion Client Methods |
@@ -590,18 +605,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
590 | 605 | ||
591 | public virtual void Start() | 606 | public virtual void Start() |
592 | { | 607 | { |
593 | m_avatarTerseUpdateTimer = new Timer(m_avatarTerseUpdateRate); | ||
594 | m_avatarTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates); | ||
595 | m_avatarTerseUpdateTimer.AutoReset = false; | ||
596 | |||
597 | m_primTerseUpdateTimer = new Timer(m_primTerseUpdateRate); | ||
598 | m_primTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimTerseUpdates); | ||
599 | m_primTerseUpdateTimer.AutoReset = false; | ||
600 | |||
601 | m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); | ||
602 | m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); | ||
603 | m_primFullUpdateTimer.AutoReset = false; | ||
604 | |||
605 | m_scene.AddNewClient(this); | 608 | m_scene.AddNewClient(this); |
606 | 609 | ||
607 | RefreshGroupMembership(); | 610 | RefreshGroupMembership(); |
@@ -618,7 +621,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
618 | } | 621 | } |
619 | 622 | ||
620 | // Sound | 623 | // Sound |
621 | public void SoundTrigger(UUID soundId, UUID owerid, UUID Objectid,UUID ParentId,float Gain, Vector3 Position,UInt64 Handle) | 624 | public void SoundTrigger(UUID soundId, UUID owerid, UUID Objectid, UUID ParentId, float Gain, Vector3 Position, UInt64 Handle) |
622 | { | 625 | { |
623 | } | 626 | } |
624 | 627 | ||
@@ -642,7 +645,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
642 | handshake.RegionInfo.WaterHeight = args.waterHeight; | 645 | handshake.RegionInfo.WaterHeight = args.waterHeight; |
643 | 646 | ||
644 | handshake.RegionInfo.RegionFlags = args.regionFlags; | 647 | handshake.RegionInfo.RegionFlags = args.regionFlags; |
645 | handshake.RegionInfo.SimName = Utils.StringToBytes(args.regionName); | 648 | handshake.RegionInfo.SimName = Util.StringToBytes256(args.regionName); |
646 | handshake.RegionInfo.SimOwner = args.SimOwner; | 649 | handshake.RegionInfo.SimOwner = args.SimOwner; |
647 | handshake.RegionInfo.TerrainBase0 = args.terrainBase0; | 650 | handshake.RegionInfo.TerrainBase0 = args.terrainBase0; |
648 | handshake.RegionInfo.TerrainBase1 = args.terrainBase1; | 651 | handshake.RegionInfo.TerrainBase1 = args.terrainBase1; |
@@ -655,7 +658,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
655 | handshake.RegionInfo.CacheID = UUID.Random(); //I guess this is for the client to remember an old setting? | 658 | handshake.RegionInfo.CacheID = UUID.Random(); //I guess this is for the client to remember an old setting? |
656 | handshake.RegionInfo2 = new RegionHandshakePacket.RegionInfo2Block(); | 659 | handshake.RegionInfo2 = new RegionHandshakePacket.RegionInfo2Block(); |
657 | handshake.RegionInfo2.RegionID = regionInfo.RegionID; | 660 | handshake.RegionInfo2.RegionID = regionInfo.RegionID; |
658 | 661 | ||
659 | handshake.RegionInfo3 = new RegionHandshakePacket.RegionInfo3Block(); | 662 | handshake.RegionInfo3 = new RegionHandshakePacket.RegionInfo3Block(); |
660 | handshake.RegionInfo3.CPUClassID = 9; | 663 | handshake.RegionInfo3.CPUClassID = 9; |
661 | handshake.RegionInfo3.CPURatio = 1; | 664 | handshake.RegionInfo3.CPURatio = 1; |
@@ -698,11 +701,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
698 | { | 701 | { |
699 | ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator); | 702 | ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator); |
700 | reply.ChatData.Audible = audible; | 703 | reply.ChatData.Audible = audible; |
701 | reply.ChatData.Message = Utils.StringToBytes(message); | 704 | reply.ChatData.Message = Util.StringToBytes1024(message); |
702 | reply.ChatData.ChatType = type; | 705 | reply.ChatData.ChatType = type; |
703 | reply.ChatData.SourceType = source; | 706 | reply.ChatData.SourceType = source; |
704 | reply.ChatData.Position = fromPos; | 707 | reply.ChatData.Position = fromPos; |
705 | reply.ChatData.FromName = Utils.StringToBytes(fromName); | 708 | reply.ChatData.FromName = Util.StringToBytes256(fromName); |
706 | reply.ChatData.OwnerID = fromAgentID; | 709 | reply.ChatData.OwnerID = fromAgentID; |
707 | reply.ChatData.SourceID = fromAgentID; | 710 | reply.ChatData.SourceID = fromAgentID; |
708 | 711 | ||
@@ -723,7 +726,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
723 | 726 | ||
724 | msg.AgentData.AgentID = new UUID(im.fromAgentID); | 727 | msg.AgentData.AgentID = new UUID(im.fromAgentID); |
725 | msg.AgentData.SessionID = UUID.Zero; | 728 | msg.AgentData.SessionID = UUID.Zero; |
726 | msg.MessageBlock.FromAgentName = Utils.StringToBytes(im.fromAgentName); | 729 | msg.MessageBlock.FromAgentName = Util.StringToBytes256(im.fromAgentName); |
727 | msg.MessageBlock.Dialog = im.dialog; | 730 | msg.MessageBlock.Dialog = im.dialog; |
728 | msg.MessageBlock.FromGroup = im.fromGroup; | 731 | msg.MessageBlock.FromGroup = im.fromGroup; |
729 | if (im.imSessionID == UUID.Zero.Guid) | 732 | if (im.imSessionID == UUID.Zero.Guid) |
@@ -736,12 +739,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
736 | msg.MessageBlock.RegionID = new UUID(im.RegionID); | 739 | msg.MessageBlock.RegionID = new UUID(im.RegionID); |
737 | msg.MessageBlock.Timestamp = im.timestamp; | 740 | msg.MessageBlock.Timestamp = im.timestamp; |
738 | msg.MessageBlock.ToAgentID = new UUID(im.toAgentID); | 741 | msg.MessageBlock.ToAgentID = new UUID(im.toAgentID); |
739 | // Cap the message length at 1099. There is a limit in ImprovedInstantMessagePacket | 742 | msg.MessageBlock.Message = Util.StringToBytes1024(im.message); |
740 | // the limit is 1100 but a 0 byte gets added to mark the end of the string | ||
741 | if (im.message != null && im.message.Length > 1099) | ||
742 | msg.MessageBlock.Message = Utils.StringToBytes(im.message.Substring(0, 1099)); | ||
743 | else | ||
744 | msg.MessageBlock.Message = Utils.StringToBytes(im.message); | ||
745 | msg.MessageBlock.BinaryBucket = im.binaryBucket; | 743 | msg.MessageBlock.BinaryBucket = im.binaryBucket; |
746 | 744 | ||
747 | if (im.message.StartsWith("[grouptest]")) | 745 | if (im.message.StartsWith("[grouptest]")) |
@@ -759,7 +757,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
759 | eq.ChatterboxInvitation( | 757 | eq.ChatterboxInvitation( |
760 | new UUID("00000000-68f9-1111-024e-222222111123"), | 758 | new UUID("00000000-68f9-1111-024e-222222111123"), |
761 | "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0, | 759 | "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0, |
762 | false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Utils.StringToBytes("OpenSimulator Testing")); | 760 | false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing")); |
763 | 761 | ||
764 | eq.ChatterBoxSessionAgentListUpdates( | 762 | eq.ChatterBoxSessionAgentListUpdates( |
765 | new UUID("00000000-68f9-1111-024e-222222111123"), | 763 | new UUID("00000000-68f9-1111-024e-222222111123"), |
@@ -776,13 +774,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
776 | public void SendGenericMessage(string method, List<string> message) | 774 | public void SendGenericMessage(string method, List<string> message) |
777 | { | 775 | { |
778 | GenericMessagePacket gmp = new GenericMessagePacket(); | 776 | GenericMessagePacket gmp = new GenericMessagePacket(); |
779 | gmp.MethodData.Method = Utils.StringToBytes(method); | 777 | gmp.MethodData.Method = Util.StringToBytes256(method); |
780 | gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; | 778 | gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; |
781 | int i = 0; | 779 | int i = 0; |
782 | foreach (string val in message) | 780 | foreach (string val in message) |
783 | { | 781 | { |
784 | gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock(); | 782 | gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock(); |
785 | gmp.ParamList[i++].Parameter = Utils.StringToBytes(val); | 783 | gmp.ParamList[i++].Parameter = Util.StringToBytes256(val); |
786 | } | 784 | } |
787 | OutPacket(gmp, ThrottleOutPacketType.Task); | 785 | OutPacket(gmp, ThrottleOutPacketType.Task); |
788 | } | 786 | } |
@@ -793,7 +791,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
793 | /// <param name="map">heightmap</param> | 791 | /// <param name="map">heightmap</param> |
794 | public virtual void SendLayerData(float[] map) | 792 | public virtual void SendLayerData(float[] map) |
795 | { | 793 | { |
796 | ThreadPool.QueueUserWorkItem(DoSendLayerData, map); | 794 | Util.FireAndForget(DoSendLayerData, map); |
797 | } | 795 | } |
798 | 796 | ||
799 | /// <summary> | 797 | /// <summary> |
@@ -802,32 +800,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
802 | /// <param name="o"></param> | 800 | /// <param name="o"></param> |
803 | private void DoSendLayerData(object o) | 801 | private void DoSendLayerData(object o) |
804 | { | 802 | { |
805 | float[] map = (float[])o; | 803 | float[] map = LLHeightFieldMoronize((float[])o); |
806 | 804 | ||
807 | try | 805 | try |
808 | { | 806 | { |
809 | for (int y = 0; y < 16; y++) | 807 | //for (int y = 0; y < 16; y++) |
810 | { | 808 | //{ |
811 | // For some terrains, sending more than one terrain patch at once results in a libsecondlife exception | 809 | // for (int x = 0; x < 16; x++) |
812 | // see http://opensimulator.org/mantis/view.php?id=1662 | 810 | // { |
813 | //for (int x = 0; x < 16; x += 4) | 811 | // SendLayerData(x, y, map); |
814 | //{ | 812 | // } |
815 | // SendLayerPacket(map, y, x); | 813 | //} |
816 | // Thread.Sleep(150); | 814 | |
817 | //} | 815 | // Send LayerData in a spiral pattern. Fun! |
818 | for (int x = 0; x < 16; x++) | 816 | SendLayerTopRight(map, 0, 0, 15, 15); |
819 | { | ||
820 | SendLayerData(x, y, LLHeightFieldMoronize(map)); | ||
821 | Thread.Sleep(35); | ||
822 | } | ||
823 | } | ||
824 | } | 817 | } |
825 | catch (Exception e) | 818 | catch (Exception e) |
826 | { | 819 | { |
827 | m_log.Warn("[CLIENT]: ClientView.API.cs: SendLayerData() - Failed with exception " + e); | 820 | m_log.Error("[CLIENT]: SendLayerData() Failed with exception: " + e.Message, e); |
828 | } | 821 | } |
829 | } | 822 | } |
830 | 823 | ||
824 | private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2) | ||
825 | { | ||
826 | // Row | ||
827 | for (int i = x1; i <= x2; i++) | ||
828 | SendLayerData(i, y1, map); | ||
829 | |||
830 | // Column | ||
831 | for (int j = y1 + 1; j <= y2; j++) | ||
832 | SendLayerData(x2, j, map); | ||
833 | |||
834 | if (x2 - x1 > 0) | ||
835 | SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2); | ||
836 | } | ||
837 | |||
838 | void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2) | ||
839 | { | ||
840 | // Row in reverse | ||
841 | for (int i = x2; i >= x1; i--) | ||
842 | SendLayerData(i, y2, map); | ||
843 | |||
844 | // Column in reverse | ||
845 | for (int j = y2 - 1; j >= y1; j--) | ||
846 | SendLayerData(x1, j, map); | ||
847 | |||
848 | if (x2 - x1 > 0) | ||
849 | SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1); | ||
850 | } | ||
851 | |||
831 | /// <summary> | 852 | /// <summary> |
832 | /// Sends a set of four patches (x, x+1, ..., x+3) to the client | 853 | /// Sends a set of four patches (x, x+1, ..., x+3) to the client |
833 | /// </summary> | 854 | /// </summary> |
@@ -856,22 +877,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
856 | { | 877 | { |
857 | try | 878 | try |
858 | { | 879 | { |
859 | int[] patches = new int[1]; | 880 | int[] patches = new int[] { py * 16 + px }; |
860 | int patchx, patchy; | 881 | float[] heightmap = (map.Length == 65536) ? |
861 | patchx = px; | 882 | map : |
862 | patchy = py; | 883 | LLHeightFieldMoronize(map); |
863 | 884 | ||
864 | patches[0] = patchx + 0 + patchy * 16; | 885 | LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); |
865 | 886 | layerpack.Header.Reliable = true; | |
866 | LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(((map.Length==65536)? map : LLHeightFieldMoronize(map)), patches); | ||
867 | layerpack.Header.Zerocoded = true; | ||
868 | 887 | ||
869 | OutPacket(layerpack, ThrottleOutPacketType.Land); | 888 | OutPacket(layerpack, ThrottleOutPacketType.Land); |
870 | |||
871 | } | 889 | } |
872 | catch (Exception e) | 890 | catch (Exception e) |
873 | { | 891 | { |
874 | m_log.Warn("[client]: ClientView.API.cs: SendLayerData() - Failed with exception " + e.ToString()); | 892 | m_log.Error("[CLIENT]: SendLayerData() Failed with exception: " + e.Message, e); |
875 | } | 893 | } |
876 | } | 894 | } |
877 | 895 | ||
@@ -900,7 +918,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
900 | Array.Copy(map, i * (int)Constants.RegionSize, returnmap, i * 256, 256); | 918 | Array.Copy(map, i * (int)Constants.RegionSize, returnmap, i * 256, 256); |
901 | } | 919 | } |
902 | 920 | ||
903 | |||
904 | //Array.Copy(map,0,returnmap,0,(map.Length < 65536)? map.Length : 65536); | 921 | //Array.Copy(map,0,returnmap,0,(map.Length < 65536)? map.Length : 65536); |
905 | 922 | ||
906 | return returnmap; | 923 | return returnmap; |
@@ -914,7 +931,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
914 | /// <param name="windSpeeds">16x16 array of wind speeds</param> | 931 | /// <param name="windSpeeds">16x16 array of wind speeds</param> |
915 | public virtual void SendWindData(Vector2[] windSpeeds) | 932 | public virtual void SendWindData(Vector2[] windSpeeds) |
916 | { | 933 | { |
917 | ThreadPool.QueueUserWorkItem(new WaitCallback(DoSendWindData), (object)windSpeeds); | 934 | Util.FireAndForget(DoSendWindData, windSpeeds); |
918 | } | 935 | } |
919 | 936 | ||
920 | /// <summary> | 937 | /// <summary> |
@@ -923,7 +940,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
923 | /// <param name="windSpeeds">16x16 array of cloud densities</param> | 940 | /// <param name="windSpeeds">16x16 array of cloud densities</param> |
924 | public virtual void SendCloudData(float[] cloudDensity) | 941 | public virtual void SendCloudData(float[] cloudDensity) |
925 | { | 942 | { |
926 | ThreadPool.QueueUserWorkItem(new WaitCallback(DoSendCloudData), (object)cloudDensity); | 943 | Util.FireAndForget(DoSendCloudData, cloudDensity); |
927 | } | 944 | } |
928 | 945 | ||
929 | /// <summary> | 946 | /// <summary> |
@@ -1012,14 +1029,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1012 | agentData.child = false; | 1029 | agentData.child = false; |
1013 | agentData.firstname = m_firstName; | 1030 | agentData.firstname = m_firstName; |
1014 | agentData.lastname = m_lastName; | 1031 | agentData.lastname = m_lastName; |
1015 | 1032 | ||
1016 | ICapabilitiesModule capsModule = m_scene.RequestModuleInterface<ICapabilitiesModule>(); | 1033 | ICapabilitiesModule capsModule = m_scene.RequestModuleInterface<ICapabilitiesModule>(); |
1017 | 1034 | ||
1018 | if (capsModule == null) // can happen when shutting down. | 1035 | if (capsModule == null) // can happen when shutting down. |
1019 | return agentData; | 1036 | return agentData; |
1020 | 1037 | ||
1021 | agentData.CapsPath = capsModule.GetCapsPath(m_agentId); | 1038 | agentData.CapsPath = capsModule.GetCapsPath(m_agentId); |
1022 | agentData.ChildrenCapSeeds = new Dictionary<ulong,string>(capsModule.GetChildrenSeeds(m_agentId)); | 1039 | agentData.ChildrenCapSeeds = new Dictionary<ulong, string>(capsModule.GetChildrenSeeds(m_agentId)); |
1023 | 1040 | ||
1024 | return agentData; | 1041 | return agentData; |
1025 | } | 1042 | } |
@@ -1046,7 +1063,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1046 | newSimPack.RegionData.SimIP += (uint)byteIP[1] << 8; | 1063 | newSimPack.RegionData.SimIP += (uint)byteIP[1] << 8; |
1047 | newSimPack.RegionData.SimIP += (uint)byteIP[0]; | 1064 | newSimPack.RegionData.SimIP += (uint)byteIP[0]; |
1048 | newSimPack.RegionData.SimPort = (ushort)externalIPEndPoint.Port; | 1065 | newSimPack.RegionData.SimPort = (ushort)externalIPEndPoint.Port; |
1049 | newSimPack.RegionData.SeedCapability = Utils.StringToBytes(capsURL); | 1066 | newSimPack.RegionData.SeedCapability = Util.StringToBytes256(capsURL); |
1050 | 1067 | ||
1051 | // Hack to get this out immediately and skip throttles | 1068 | // Hack to get this out immediately and skip throttles |
1052 | OutPacket(newSimPack, ThrottleOutPacketType.Unknown); | 1069 | OutPacket(newSimPack, ThrottleOutPacketType.Unknown); |
@@ -1124,7 +1141,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1124 | teleport.Info.RegionHandle = regionHandle; | 1141 | teleport.Info.RegionHandle = regionHandle; |
1125 | teleport.Info.SimAccess = simAccess; | 1142 | teleport.Info.SimAccess = simAccess; |
1126 | 1143 | ||
1127 | teleport.Info.SeedCapability = Utils.StringToBytes(capsURL); | 1144 | teleport.Info.SeedCapability = Util.StringToBytes256(capsURL); |
1128 | 1145 | ||
1129 | IPAddress oIP = newRegionEndPoint.Address; | 1146 | IPAddress oIP = newRegionEndPoint.Address; |
1130 | byte[] byteIP = oIP.GetAddressBytes(); | 1147 | byte[] byteIP = oIP.GetAddressBytes(); |
@@ -1149,7 +1166,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1149 | { | 1166 | { |
1150 | TeleportFailedPacket tpFailed = (TeleportFailedPacket)PacketPool.Instance.GetPacket(PacketType.TeleportFailed); | 1167 | TeleportFailedPacket tpFailed = (TeleportFailedPacket)PacketPool.Instance.GetPacket(PacketType.TeleportFailed); |
1151 | tpFailed.Info.AgentID = AgentId; | 1168 | tpFailed.Info.AgentID = AgentId; |
1152 | tpFailed.Info.Reason = Utils.StringToBytes(reason); | 1169 | tpFailed.Info.Reason = Util.StringToBytes256(reason); |
1153 | tpFailed.AlertInfo = new TeleportFailedPacket.AlertInfoBlock[0]; | 1170 | tpFailed.AlertInfo = new TeleportFailedPacket.AlertInfoBlock[0]; |
1154 | 1171 | ||
1155 | // Hack to get this out immediately and skip throttles | 1172 | // Hack to get this out immediately and skip throttles |
@@ -1211,11 +1228,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1211 | StartPingCheckPacket pc = (StartPingCheckPacket)PacketPool.Instance.GetPacket(PacketType.StartPingCheck); | 1228 | StartPingCheckPacket pc = (StartPingCheckPacket)PacketPool.Instance.GetPacket(PacketType.StartPingCheck); |
1212 | pc.Header.Reliable = false; | 1229 | pc.Header.Reliable = false; |
1213 | 1230 | ||
1214 | OutgoingPacket oldestPacket = m_udpClient.NeedAcks.GetOldest(); | ||
1215 | |||
1216 | pc.PingID.PingID = seq; | 1231 | pc.PingID.PingID = seq; |
1217 | pc.PingID.OldestUnacked = (oldestPacket != null) ? oldestPacket.SequenceNumber : 0; | 1232 | // We *could* get OldestUnacked, but it would hurt performance and not provide any benefit |
1218 | 1233 | pc.PingID.OldestUnacked = 0; | |
1234 | |||
1219 | OutPacket(pc, ThrottleOutPacketType.Unknown); | 1235 | OutPacket(pc, ThrottleOutPacketType.Unknown); |
1220 | } | 1236 | } |
1221 | 1237 | ||
@@ -1521,7 +1537,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1521 | inventoryReply.Header.Zerocoded = true; | 1537 | inventoryReply.Header.Zerocoded = true; |
1522 | OutPacket(inventoryReply, ThrottleOutPacketType.Asset); | 1538 | OutPacket(inventoryReply, ThrottleOutPacketType.Asset); |
1523 | } | 1539 | } |
1524 | 1540 | ||
1525 | protected void SendBulkUpdateInventoryFolder(InventoryFolderBase folderBase) | 1541 | protected void SendBulkUpdateInventoryFolder(InventoryFolderBase folderBase) |
1526 | { | 1542 | { |
1527 | // We will use the same transaction id for all the separate packets to be sent out in this update. | 1543 | // We will use the same transaction id for all the separate packets to be sent out in this update. |
@@ -1545,7 +1561,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1545 | bulkUpdate.FolderData = folderDataBlocks.ToArray(); | 1561 | bulkUpdate.FolderData = folderDataBlocks.ToArray(); |
1546 | List<BulkUpdateInventoryPacket.ItemDataBlock> foo = new List<BulkUpdateInventoryPacket.ItemDataBlock>(); | 1562 | List<BulkUpdateInventoryPacket.ItemDataBlock> foo = new List<BulkUpdateInventoryPacket.ItemDataBlock>(); |
1547 | bulkUpdate.ItemData = foo.ToArray(); | 1563 | bulkUpdate.ItemData = foo.ToArray(); |
1548 | 1564 | ||
1549 | //m_log.Debug("SendBulkUpdateInventory :" + bulkUpdate); | 1565 | //m_log.Debug("SendBulkUpdateInventory :" + bulkUpdate); |
1550 | OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); | 1566 | OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); |
1551 | } | 1567 | } |
@@ -1668,7 +1684,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1668 | 1684 | ||
1669 | return itemBlock; | 1685 | return itemBlock; |
1670 | } | 1686 | } |
1671 | 1687 | ||
1672 | public void SendBulkUpdateInventory(InventoryNodeBase node) | 1688 | public void SendBulkUpdateInventory(InventoryNodeBase node) |
1673 | { | 1689 | { |
1674 | if (node is InventoryItemBase) | 1690 | if (node is InventoryItemBase) |
@@ -1678,7 +1694,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1678 | else | 1694 | else |
1679 | m_log.ErrorFormat("[CLIENT]: Client for {0} sent unknown inventory node named {1}", Name, node.Name); | 1695 | m_log.ErrorFormat("[CLIENT]: Client for {0} sent unknown inventory node named {1}", Name, node.Name); |
1680 | } | 1696 | } |
1681 | 1697 | ||
1682 | protected void SendBulkUpdateInventoryItem(InventoryItemBase item) | 1698 | protected void SendBulkUpdateInventoryItem(InventoryItemBase item) |
1683 | { | 1699 | { |
1684 | const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; | 1700 | const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; |
@@ -1881,11 +1897,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1881 | AgentDataUpdatePacket sendAgentDataUpdate = (AgentDataUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentDataUpdate); | 1897 | AgentDataUpdatePacket sendAgentDataUpdate = (AgentDataUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentDataUpdate); |
1882 | sendAgentDataUpdate.AgentData.ActiveGroupID = activegroupid; | 1898 | sendAgentDataUpdate.AgentData.ActiveGroupID = activegroupid; |
1883 | sendAgentDataUpdate.AgentData.AgentID = agentid; | 1899 | sendAgentDataUpdate.AgentData.AgentID = agentid; |
1884 | sendAgentDataUpdate.AgentData.FirstName = Utils.StringToBytes(firstname); | 1900 | sendAgentDataUpdate.AgentData.FirstName = Util.StringToBytes256(firstname); |
1885 | sendAgentDataUpdate.AgentData.GroupName = Utils.StringToBytes(groupname); | 1901 | sendAgentDataUpdate.AgentData.GroupName = Util.StringToBytes256(groupname); |
1886 | sendAgentDataUpdate.AgentData.GroupPowers = grouppowers; | 1902 | sendAgentDataUpdate.AgentData.GroupPowers = grouppowers; |
1887 | sendAgentDataUpdate.AgentData.GroupTitle = Utils.StringToBytes(grouptitle); | 1903 | sendAgentDataUpdate.AgentData.GroupTitle = Util.StringToBytes256(grouptitle); |
1888 | sendAgentDataUpdate.AgentData.LastName = Utils.StringToBytes(lastname); | 1904 | sendAgentDataUpdate.AgentData.LastName = Util.StringToBytes256(lastname); |
1889 | OutPacket(sendAgentDataUpdate, ThrottleOutPacketType.Task); | 1905 | OutPacket(sendAgentDataUpdate, ThrottleOutPacketType.Task); |
1890 | } | 1906 | } |
1891 | 1907 | ||
@@ -1898,7 +1914,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1898 | { | 1914 | { |
1899 | AlertMessagePacket alertPack = (AlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AlertMessage); | 1915 | AlertMessagePacket alertPack = (AlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AlertMessage); |
1900 | alertPack.AlertData = new AlertMessagePacket.AlertDataBlock(); | 1916 | alertPack.AlertData = new AlertMessagePacket.AlertDataBlock(); |
1901 | alertPack.AlertData.Message = Utils.StringToBytes(message); | 1917 | alertPack.AlertData.Message = Util.StringToBytes256(message); |
1902 | alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[0]; | 1918 | alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[0]; |
1903 | OutPacket(alertPack, ThrottleOutPacketType.Task); | 1919 | OutPacket(alertPack, ThrottleOutPacketType.Task); |
1904 | } | 1920 | } |
@@ -1925,7 +1941,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1925 | { | 1941 | { |
1926 | AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); | 1942 | AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); |
1927 | alertPack.AgentData.AgentID = AgentId; | 1943 | alertPack.AgentData.AgentID = AgentId; |
1928 | alertPack.AlertData.Message = Utils.StringToBytes(message); | 1944 | alertPack.AlertData.Message = Util.StringToBytes256(message); |
1929 | alertPack.AlertData.Modal = modal; | 1945 | alertPack.AlertData.Modal = modal; |
1930 | 1946 | ||
1931 | return alertPack; | 1947 | return alertPack; |
@@ -1935,12 +1951,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1935 | string url) | 1951 | string url) |
1936 | { | 1952 | { |
1937 | LoadURLPacket loadURL = (LoadURLPacket)PacketPool.Instance.GetPacket(PacketType.LoadURL); | 1953 | LoadURLPacket loadURL = (LoadURLPacket)PacketPool.Instance.GetPacket(PacketType.LoadURL); |
1938 | loadURL.Data.ObjectName = Utils.StringToBytes(objectname); | 1954 | loadURL.Data.ObjectName = Util.StringToBytes256(objectname); |
1939 | loadURL.Data.ObjectID = objectID; | 1955 | loadURL.Data.ObjectID = objectID; |
1940 | loadURL.Data.OwnerID = ownerID; | 1956 | loadURL.Data.OwnerID = ownerID; |
1941 | loadURL.Data.OwnerIsGroup = groupOwned; | 1957 | loadURL.Data.OwnerIsGroup = groupOwned; |
1942 | loadURL.Data.Message = Utils.StringToBytes(message); | 1958 | loadURL.Data.Message = Util.StringToBytes256(message); |
1943 | loadURL.Data.URL = Utils.StringToBytes(url); | 1959 | loadURL.Data.URL = Util.StringToBytes256(url); |
1944 | OutPacket(loadURL, ThrottleOutPacketType.Task); | 1960 | OutPacket(loadURL, ThrottleOutPacketType.Task); |
1945 | } | 1961 | } |
1946 | 1962 | ||
@@ -1948,18 +1964,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1948 | { | 1964 | { |
1949 | ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog); | 1965 | ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog); |
1950 | dialog.Data.ObjectID = objectID; | 1966 | dialog.Data.ObjectID = objectID; |
1951 | dialog.Data.ObjectName = Utils.StringToBytes(objectname); | 1967 | dialog.Data.ObjectName = Util.StringToBytes256(objectname); |
1952 | // this is the username of the *owner* | 1968 | // this is the username of the *owner* |
1953 | dialog.Data.FirstName = Utils.StringToBytes(ownerFirstName); | 1969 | dialog.Data.FirstName = Util.StringToBytes256(ownerFirstName); |
1954 | dialog.Data.LastName = Utils.StringToBytes(ownerLastName); | 1970 | dialog.Data.LastName = Util.StringToBytes256(ownerLastName); |
1955 | dialog.Data.Message = Utils.StringToBytes(msg); | 1971 | dialog.Data.Message = Util.StringToBytes1024(msg); |
1956 | dialog.Data.ImageID = textureID; | 1972 | dialog.Data.ImageID = textureID; |
1957 | dialog.Data.ChatChannel = ch; | 1973 | dialog.Data.ChatChannel = ch; |
1958 | ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[buttonlabels.Length]; | 1974 | ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[buttonlabels.Length]; |
1959 | for (int i = 0; i < buttonlabels.Length; i++) | 1975 | for (int i = 0; i < buttonlabels.Length; i++) |
1960 | { | 1976 | { |
1961 | buttons[i] = new ScriptDialogPacket.ButtonsBlock(); | 1977 | buttons[i] = new ScriptDialogPacket.ButtonsBlock(); |
1962 | buttons[i].ButtonLabel = Utils.StringToBytes(buttonlabels[i]); | 1978 | buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]); |
1963 | } | 1979 | } |
1964 | dialog.Buttons = buttons; | 1980 | dialog.Buttons = buttons; |
1965 | OutPacket(dialog, ThrottleOutPacketType.Task); | 1981 | OutPacket(dialog, ThrottleOutPacketType.Task); |
@@ -2115,19 +2131,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2115 | avatarReply.AgentData.AgentID = AgentId; | 2131 | avatarReply.AgentData.AgentID = AgentId; |
2116 | avatarReply.AgentData.AvatarID = avatarID; | 2132 | avatarReply.AgentData.AvatarID = avatarID; |
2117 | if (aboutText != null) | 2133 | if (aboutText != null) |
2118 | avatarReply.PropertiesData.AboutText = Utils.StringToBytes(aboutText); | 2134 | avatarReply.PropertiesData.AboutText = Util.StringToBytes1024(aboutText); |
2119 | else | 2135 | else |
2120 | avatarReply.PropertiesData.AboutText = Utils.StringToBytes(""); | 2136 | avatarReply.PropertiesData.AboutText = Utils.EmptyBytes; |
2121 | avatarReply.PropertiesData.BornOn = Utils.StringToBytes(bornOn); | 2137 | avatarReply.PropertiesData.BornOn = Util.StringToBytes256(bornOn); |
2122 | avatarReply.PropertiesData.CharterMember = charterMember; | 2138 | avatarReply.PropertiesData.CharterMember = charterMember; |
2123 | if (flAbout != null) | 2139 | if (flAbout != null) |
2124 | avatarReply.PropertiesData.FLAboutText = Utils.StringToBytes(flAbout); | 2140 | avatarReply.PropertiesData.FLAboutText = Util.StringToBytes256(flAbout); |
2125 | else | 2141 | else |
2126 | avatarReply.PropertiesData.FLAboutText = Utils.StringToBytes(""); | 2142 | avatarReply.PropertiesData.FLAboutText = Utils.EmptyBytes; |
2127 | avatarReply.PropertiesData.Flags = flags; | 2143 | avatarReply.PropertiesData.Flags = flags; |
2128 | avatarReply.PropertiesData.FLImageID = flImageID; | 2144 | avatarReply.PropertiesData.FLImageID = flImageID; |
2129 | avatarReply.PropertiesData.ImageID = imageID; | 2145 | avatarReply.PropertiesData.ImageID = imageID; |
2130 | avatarReply.PropertiesData.ProfileURL = Utils.StringToBytes(profileURL); | 2146 | avatarReply.PropertiesData.ProfileURL = Util.StringToBytes256(profileURL); |
2131 | avatarReply.PropertiesData.PartnerID = partnerID; | 2147 | avatarReply.PropertiesData.PartnerID = partnerID; |
2132 | OutPacket(avatarReply, ThrottleOutPacketType.Task); | 2148 | OutPacket(avatarReply, ThrottleOutPacketType.Task); |
2133 | } | 2149 | } |
@@ -2254,7 +2270,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2254 | Group.Contribution = GroupMembership[i].Contribution; | 2270 | Group.Contribution = GroupMembership[i].Contribution; |
2255 | Group.GroupID = GroupMembership[i].GroupID; | 2271 | Group.GroupID = GroupMembership[i].GroupID; |
2256 | Group.GroupInsigniaID = GroupMembership[i].GroupPicture; | 2272 | Group.GroupInsigniaID = GroupMembership[i].GroupPicture; |
2257 | Group.GroupName = Utils.StringToBytes(GroupMembership[i].GroupName); | 2273 | Group.GroupName = Util.StringToBytes256(GroupMembership[i].GroupName); |
2258 | Group.GroupPowers = GroupMembership[i].GroupPowers; | 2274 | Group.GroupPowers = GroupMembership[i].GroupPowers; |
2259 | Groups[i] = Group; | 2275 | Groups[i] = Group; |
2260 | 2276 | ||
@@ -2288,7 +2304,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2288 | UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1]; | 2304 | UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1]; |
2289 | UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock(); | 2305 | UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock(); |
2290 | uidnamebloc.ID = groupLLUID; | 2306 | uidnamebloc.ID = groupLLUID; |
2291 | uidnamebloc.GroupName = Utils.StringToBytes(GroupName); | 2307 | uidnamebloc.GroupName = Util.StringToBytes256(GroupName); |
2292 | uidnameblock[0] = uidnamebloc; | 2308 | uidnameblock[0] = uidnamebloc; |
2293 | pack.UUIDNameBlock = uidnameblock; | 2309 | pack.UUIDNameBlock = uidnameblock; |
2294 | OutPacket(pack, ThrottleOutPacketType.Task); | 2310 | OutPacket(pack, ThrottleOutPacketType.Task); |
@@ -2313,8 +2329,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2313 | lsrepdb.Score = lsrpia[i].Score; | 2329 | lsrepdb.Score = lsrpia[i].Score; |
2314 | lsrepdb.TaskID = lsrpia[i].TaskID; | 2330 | lsrepdb.TaskID = lsrpia[i].TaskID; |
2315 | lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID; | 2331 | lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID; |
2316 | lsrepdb.TaskName = Utils.StringToBytes(lsrpia[i].TaskName); | 2332 | lsrepdb.TaskName = Util.StringToBytes256(lsrpia[i].TaskName); |
2317 | lsrepdb.OwnerName = Utils.StringToBytes(lsrpia[i].OwnerName); | 2333 | lsrepdb.OwnerName = Util.StringToBytes256(lsrpia[i].OwnerName); |
2318 | lsrepdba[i] = lsrepdb; | 2334 | lsrepdba[i] = lsrepdb; |
2319 | } | 2335 | } |
2320 | lsrp.ReportData = lsrepdba; | 2336 | lsrp.ReportData = lsrepdba; |
@@ -3102,9 +3118,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3102 | awb.ItemID = wearables[i].ItemID; | 3118 | awb.ItemID = wearables[i].ItemID; |
3103 | aw.WearableData[i] = awb; | 3119 | aw.WearableData[i] = awb; |
3104 | 3120 | ||
3105 | // m_log.DebugFormat( | 3121 | // m_log.DebugFormat( |
3106 | // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", | 3122 | // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", |
3107 | // awb.ItemID, awb.AssetID, i, Name); | 3123 | // awb.ItemID, awb.AssetID, i, Name); |
3108 | } | 3124 | } |
3109 | 3125 | ||
3110 | OutPacket(aw, ThrottleOutPacketType.Task); | 3126 | OutPacket(aw, ThrottleOutPacketType.Task); |
@@ -3127,7 +3143,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3127 | 3143 | ||
3128 | avp.Sender.IsTrial = false; | 3144 | avp.Sender.IsTrial = false; |
3129 | avp.Sender.ID = agentID; | 3145 | avp.Sender.ID = agentID; |
3130 | OutPacket(avp, ThrottleOutPacketType.State); | 3146 | OutPacket(avp, ThrottleOutPacketType.Task); |
3131 | } | 3147 | } |
3132 | 3148 | ||
3133 | public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) | 3149 | public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) |
@@ -3159,123 +3175,174 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3159 | 3175 | ||
3160 | #endregion | 3176 | #endregion |
3161 | 3177 | ||
3162 | #region Avatar Packet/data sending Methods | 3178 | #region Prim/Avatar Updates |
3163 | 3179 | ||
3164 | /// <summary> | 3180 | /*void SendObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) |
3165 | /// send a objectupdate packet with information about the clients avatar | ||
3166 | /// </summary> | ||
3167 | public void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, | ||
3168 | uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation) | ||
3169 | { | 3181 | { |
3170 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | 3182 | bool canUseCompressed, canUseImproved; |
3171 | // TODO: don't create new blocks if recycling an old packet | 3183 | UpdateFlagsToPacketType(creatorFlags, updateFlags, out canUseCompressed, out canUseImproved); |
3172 | objupdate.RegionData.RegionHandle = regionHandle; | 3184 | |
3173 | objupdate.RegionData.TimeDilation = ushort.MaxValue; | 3185 | if (!canUseImproved && !canUseCompressed) |
3174 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | 3186 | SendFullObjectUpdate(obj, creatorFlags, updateFlags); |
3175 | objupdate.ObjectData[0] = CreateDefaultAvatarPacket(textureEntry); | 3187 | else if (!canUseImproved) |
3188 | SendObjectUpdateCompressed(obj, creatorFlags, updateFlags); | ||
3189 | else | ||
3190 | SendImprovedTerseObjectUpdate(obj, creatorFlags, updateFlags); | ||
3191 | } | ||
3176 | 3192 | ||
3177 | //give this avatar object a local id and assign the user a name | 3193 | void SendFullObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) |
3178 | objupdate.ObjectData[0].ID = avatarLocalID; | 3194 | { |
3179 | objupdate.ObjectData[0].FullID = avatarID; | 3195 | IClientAPI owner; |
3180 | objupdate.ObjectData[0].ParentID = parentID; | 3196 | if (m_scene.ClientManager.TryGetValue(obj.OwnerID, out owner) && owner is LLClientView) |
3181 | objupdate.ObjectData[0].NameValue = | 3197 | { |
3182 | Utils.StringToBytes("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName + "\nTitle STRING RW SV " + grouptitle); | 3198 | LLClientView llOwner = (LLClientView)owner; |
3183 | 3199 | ||
3184 | Vector3 pos2 = new Vector3(Pos.X, Pos.Y, Pos.Z); | 3200 | // Send an update out to the owner |
3185 | byte[] pb = pos2.GetBytes(); | 3201 | ObjectUpdatePacket updateToOwner = new ObjectUpdatePacket(); |
3186 | Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); | 3202 | updateToOwner.RegionData.RegionHandle = obj.RegionHandle; |
3203 | //updateToOwner.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); | ||
3204 | updateToOwner.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
3205 | updateToOwner.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags | creatorFlags | PrimFlags.ObjectYouOwner, 0); | ||
3187 | 3206 | ||
3188 | byte[] rot = rotation.GetBytes(); | 3207 | m_udpServer.SendPacket(llOwner.UDPClient, updateToOwner, ThrottleOutPacketType.State, true); |
3189 | Array.Copy(rot, 0, objupdate.ObjectData[0].ObjectData, 52, rot.Length); | 3208 | } |
3190 | 3209 | ||
3191 | objupdate.Header.Zerocoded = true; | 3210 | // Send an update out to everyone else |
3192 | OutPacket(objupdate, ThrottleOutPacketType.Task); | 3211 | ObjectUpdatePacket updateToOthers = new ObjectUpdatePacket(); |
3212 | updateToOthers.RegionData.RegionHandle = obj.RegionHandle; | ||
3213 | //updateToOthers.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); | ||
3214 | updateToOthers.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
3215 | updateToOthers.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags, 0); | ||
3216 | |||
3217 | m_scene.ClientManager.ForEach( | ||
3218 | delegate(IClientAPI client) | ||
3219 | { | ||
3220 | if (client.AgentId != obj.OwnerID && client is LLClientView) | ||
3221 | { | ||
3222 | LLClientView llClient = (LLClientView)client; | ||
3223 | m_udpServer.SendPacket(llClient.UDPClient, updateToOthers, ThrottleOutPacketType.State, true); | ||
3224 | } | ||
3225 | } | ||
3226 | ); | ||
3193 | } | 3227 | } |
3194 | 3228 | ||
3195 | /// <summary> | 3229 | void SendObjectUpdateCompressed(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) |
3196 | /// Send a terse positional/rotation/velocity update about an avatar | ||
3197 | /// to the client. This avatar can be that of the client itself. | ||
3198 | /// </summary> | ||
3199 | public virtual void SendAvatarTerseUpdate(ulong regionHandle, | ||
3200 | ushort timeDilation, uint localID, Vector3 position, | ||
3201 | Vector3 velocity, Quaternion rotation, UUID agentid) | ||
3202 | { | 3230 | { |
3203 | if (rotation.X == rotation.Y && | 3231 | } |
3204 | rotation.Y == rotation.Z && | ||
3205 | rotation.Z == rotation.W && rotation.W == 0) | ||
3206 | rotation = Quaternion.Identity; | ||
3207 | 3232 | ||
3208 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = | 3233 | void SendImprovedTerseObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) |
3209 | CreateAvatarImprovedBlock(localID, position, velocity,rotation); | 3234 | { |
3210 | 3235 | } | |
3211 | lock (m_avatarTerseUpdates) | 3236 | |
3212 | { | 3237 | void UpdateFlagsToPacketType(PrimFlags creatorFlags, PrimUpdateFlags updateFlags, out bool canUseCompressed, out bool canUseImproved) |
3213 | m_avatarTerseUpdates.Add(terseBlock); | 3238 | { |
3239 | canUseCompressed = true; | ||
3240 | canUseImproved = true; | ||
3214 | 3241 | ||
3215 | // If packet is full or own movement packet, send it. | 3242 | if ((updateFlags & PrimUpdateFlags.FullUpdate) == PrimUpdateFlags.FullUpdate || creatorFlags != PrimFlags.None) |
3216 | if (m_avatarTerseUpdates.Count >= m_avatarTerseUpdatesPerPacket) | 3243 | { |
3244 | canUseCompressed = false; | ||
3245 | canUseImproved = false; | ||
3246 | } | ||
3247 | else | ||
3248 | { | ||
3249 | if ((updateFlags & PrimUpdateFlags.Velocity) != 0 || | ||
3250 | (updateFlags & PrimUpdateFlags.Acceleration) != 0 || | ||
3251 | (updateFlags & PrimUpdateFlags.CollisionPlane) != 0 || | ||
3252 | (updateFlags & PrimUpdateFlags.Joint) != 0) | ||
3217 | { | 3253 | { |
3218 | ProcessAvatarTerseUpdates(this, null); | 3254 | canUseCompressed = false; |
3219 | } | 3255 | } |
3220 | else if (m_avatarTerseUpdates.Count == 1) | 3256 | |
3257 | if ((updateFlags & PrimUpdateFlags.PrimFlags) != 0 || | ||
3258 | (updateFlags & PrimUpdateFlags.ParentID) != 0 || | ||
3259 | (updateFlags & PrimUpdateFlags.Scale) != 0 || | ||
3260 | (updateFlags & PrimUpdateFlags.PrimData) != 0 || | ||
3261 | (updateFlags & PrimUpdateFlags.Text) != 0 || | ||
3262 | (updateFlags & PrimUpdateFlags.NameValue) != 0 || | ||
3263 | (updateFlags & PrimUpdateFlags.ExtraData) != 0 || | ||
3264 | (updateFlags & PrimUpdateFlags.TextureAnim) != 0 || | ||
3265 | (updateFlags & PrimUpdateFlags.Sound) != 0 || | ||
3266 | (updateFlags & PrimUpdateFlags.Particles) != 0 || | ||
3267 | (updateFlags & PrimUpdateFlags.Material) != 0 || | ||
3268 | (updateFlags & PrimUpdateFlags.ClickAction) != 0 || | ||
3269 | (updateFlags & PrimUpdateFlags.MediaURL) != 0 || | ||
3270 | (updateFlags & PrimUpdateFlags.Joint) != 0) | ||
3221 | { | 3271 | { |
3222 | lock (m_avatarTerseUpdateTimer) | 3272 | canUseImproved = false; |
3223 | m_avatarTerseUpdateTimer.Start(); | ||
3224 | } | 3273 | } |
3225 | } | 3274 | } |
3226 | } | 3275 | }*/ |
3276 | |||
3277 | #endregion Prim/Avatar Updates | ||
3227 | 3278 | ||
3228 | private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e) | 3279 | #region Avatar Packet/Data Sending Methods |
3280 | |||
3281 | /// <summary> | ||
3282 | /// Send an ObjectUpdate packet with information about an avatar | ||
3283 | /// </summary> | ||
3284 | public void SendAvatarData(SendAvatarData data) | ||
3229 | { | 3285 | { |
3230 | lock (m_avatarTerseUpdates) | 3286 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); |
3231 | { | 3287 | objupdate.Header.Zerocoded = true; |
3232 | ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); | ||
3233 | 3288 | ||
3234 | terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock(); | 3289 | objupdate.RegionData.RegionHandle = data.RegionHandle; |
3290 | objupdate.RegionData.TimeDilation = ushort.MaxValue; | ||
3235 | 3291 | ||
3236 | terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; | 3292 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; |
3237 | terse.RegionData.TimeDilation = | 3293 | objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); |
3238 | (ushort)(Scene.TimeDilation * ushort.MaxValue); | ||
3239 | 3294 | ||
3240 | int max = m_avatarTerseUpdatesPerPacket; | 3295 | OutPacket(objupdate, ThrottleOutPacketType.Task); |
3241 | if (max > m_avatarTerseUpdates.Count) | 3296 | } |
3242 | max = m_avatarTerseUpdates.Count; | ||
3243 | 3297 | ||
3244 | int count = 0; | 3298 | /// <summary> |
3245 | int size = 0; | 3299 | /// Send a terse positional/rotation/velocity update about an avatar |
3300 | /// to the client. This avatar can be that of the client itself. | ||
3301 | /// </summary> | ||
3302 | public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||
3303 | { | ||
3304 | if (data.Priority == double.NaN) | ||
3305 | { | ||
3306 | m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update"); | ||
3307 | return; | ||
3308 | } | ||
3246 | 3309 | ||
3247 | byte[] zerobuffer = new byte[1024]; | 3310 | Quaternion rotation = data.Rotation; |
3248 | byte[] blockbuffer = new byte[1024]; | 3311 | if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) |
3312 | rotation = Quaternion.Identity; | ||
3249 | 3313 | ||
3250 | for (count = 0 ; count < max ; count++) | 3314 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data); |
3251 | { | ||
3252 | int length = 0; | ||
3253 | m_avatarTerseUpdates[count].ToBytes(blockbuffer, ref length); | ||
3254 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); | ||
3255 | if (size + length > Packet.MTU) | ||
3256 | break; | ||
3257 | size += length; | ||
3258 | } | ||
3259 | 3315 | ||
3260 | terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; | 3316 | lock (m_avatarTerseUpdates.SyncRoot) |
3317 | m_avatarTerseUpdates.Enqueue(data.Priority, terseBlock, data.LocalID); | ||
3261 | 3318 | ||
3262 | for (int i = 0 ; i < count ; i++) | 3319 | // If we received an update about our own avatar, process the avatar update priority queue immediately |
3263 | { | 3320 | if (data.AgentID == m_agentId) |
3264 | terse.ObjectData[i] = m_avatarTerseUpdates[0]; | 3321 | ProcessAvatarTerseUpdates(); |
3265 | m_avatarTerseUpdates.RemoveAt(0); | 3322 | } |
3266 | } | ||
3267 | 3323 | ||
3268 | terse.Header.Reliable = false; | 3324 | private void ProcessAvatarTerseUpdates() |
3269 | terse.Header.Zerocoded = true; | 3325 | { |
3270 | // FIXME: Move this to ThrottleOutPacketType.State when the real prioritization code is committed | 3326 | ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); |
3271 | OutPacket(terse, ThrottleOutPacketType.Task); | 3327 | terse.Header.Reliable = false; |
3328 | terse.Header.Zerocoded = true; | ||
3272 | 3329 | ||
3273 | if (m_avatarTerseUpdates.Count == 0) | 3330 | //terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock(); |
3274 | { | 3331 | terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; |
3275 | lock (m_avatarTerseUpdateTimer) | 3332 | terse.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); |
3276 | m_avatarTerseUpdateTimer.Stop(); | 3333 | |
3277 | } | 3334 | lock (m_avatarTerseUpdates.SyncRoot) |
3335 | { | ||
3336 | int count = Math.Min(m_avatarTerseUpdates.Count, m_avatarTerseUpdatesPerPacket); | ||
3337 | if (count == 0) | ||
3338 | return; | ||
3339 | |||
3340 | terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; | ||
3341 | for (int i = 0; i < count; i++) | ||
3342 | terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); | ||
3278 | } | 3343 | } |
3344 | |||
3345 | OutPacket(terse, ThrottleOutPacketType.Task); | ||
3279 | } | 3346 | } |
3280 | 3347 | ||
3281 | public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | 3348 | public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) |
@@ -3294,7 +3361,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3294 | { | 3361 | { |
3295 | CoarseLocationUpdatePacket.LocationBlock lb = | 3362 | CoarseLocationUpdatePacket.LocationBlock lb = |
3296 | new CoarseLocationUpdatePacket.LocationBlock(); | 3363 | new CoarseLocationUpdatePacket.LocationBlock(); |
3297 | 3364 | ||
3298 | lb.X = (byte)CoarseLocations[i].X; | 3365 | lb.X = (byte)CoarseLocations[i].X; |
3299 | lb.Y = (byte)CoarseLocations[i].Y; | 3366 | lb.Y = (byte)CoarseLocations[i].Y; |
3300 | 3367 | ||
@@ -3314,319 +3381,211 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3314 | OutPacket(loc, ThrottleOutPacketType.Task); | 3381 | OutPacket(loc, ThrottleOutPacketType.Task); |
3315 | } | 3382 | } |
3316 | 3383 | ||
3317 | #endregion | 3384 | #endregion Avatar Packet/Data Sending Methods |
3318 | 3385 | ||
3319 | #region Primitive Packet/data Sending Methods | 3386 | #region Primitive Packet/Data Sending Methods |
3320 | 3387 | ||
3321 | /// <summary> | 3388 | public void SendPrimitiveToClient(SendPrimitiveData data) |
3322 | /// | ||
3323 | /// </summary> | ||
3324 | /// <param name="localID"></param> | ||
3325 | /// <param name="rotation"></param> | ||
3326 | /// <param name="attachPoint"></param> | ||
3327 | public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||
3328 | { | 3389 | { |
3329 | if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD | 3390 | if (data.priority == double.NaN) |
3391 | { | ||
3392 | m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update"); | ||
3330 | return; | 3393 | return; |
3394 | } | ||
3331 | 3395 | ||
3332 | ObjectAttachPacket attach = (ObjectAttachPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAttach); | 3396 | Quaternion rotation = data.rotation; |
3333 | // TODO: don't create new blocks if recycling an old packet | 3397 | if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) |
3334 | attach.AgentData.AgentID = AgentId; | 3398 | rotation = Quaternion.Identity; |
3335 | attach.AgentData.SessionID = m_sessionId; | ||
3336 | attach.AgentData.AttachmentPoint = attachPoint; | ||
3337 | attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1]; | ||
3338 | attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock(); | ||
3339 | attach.ObjectData[0].ObjectLocalID = localID; | ||
3340 | attach.ObjectData[0].Rotation = rotation; | ||
3341 | attach.Header.Zerocoded = true; | ||
3342 | OutPacket(attach, ThrottleOutPacketType.Task); | ||
3343 | } | ||
3344 | |||
3345 | public void SendPrimitiveToClient( | ||
3346 | ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, | ||
3347 | Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, | ||
3348 | uint flags, UUID objectID, UUID ownerID, string text, byte[] color, | ||
3349 | uint parentID, byte[] particleSystem, byte clickAction, byte material) | ||
3350 | { | ||
3351 | byte[] textureanim = new byte[0]; | ||
3352 | |||
3353 | SendPrimitiveToClient(regionHandle, timeDilation, localID, primShape, pos, vel, | ||
3354 | acc, rotation, rvel, flags, | ||
3355 | objectID, ownerID, text, color, parentID, particleSystem, | ||
3356 | clickAction, material, textureanim, false, 0, UUID.Zero, UUID.Zero, 0, 0, 0); | ||
3357 | } | ||
3358 | |||
3359 | public void SendPrimitiveToClient( | ||
3360 | ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, | ||
3361 | Vector3 pos, Vector3 velocity, Vector3 acceleration, Quaternion rotation, Vector3 rotational_velocity, | ||
3362 | uint flags, | ||
3363 | UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, | ||
3364 | byte clickAction, byte material, byte[] textureanim, bool attachment, uint AttachPoint, UUID AssetId, UUID SoundId, double SoundGain, byte SoundFlags, double SoundRadius) | ||
3365 | { | ||
3366 | 3399 | ||
3367 | if (AttachPoint > 30 && ownerID != AgentId) // Someone else's HUD | 3400 | if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD |
3368 | return; | 3401 | return; |
3369 | if (primShape.PCode == 9 && primShape.State != 0 && parentID == 0) | 3402 | if (data.primShape.State != 0 && data.parentID == 0 && data.primShape.PCode == 9) |
3370 | return; | 3403 | return; |
3371 | 3404 | ||
3372 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) | 3405 | ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data); |
3373 | rotation = Quaternion.Identity; | ||
3374 | 3406 | ||
3375 | ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(primShape, flags); | 3407 | lock (m_primFullUpdates.SyncRoot) |
3408 | m_primFullUpdates.Enqueue(data.priority, objectData, data.localID); | ||
3409 | } | ||
3376 | 3410 | ||
3377 | objectData.ID = localID; | 3411 | void ProcessPrimFullUpdates() |
3378 | objectData.FullID = objectID; | 3412 | { |
3379 | objectData.OwnerID = ownerID; | 3413 | ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); |
3414 | outPacket.Header.Zerocoded = true; | ||
3380 | 3415 | ||
3381 | objectData.Text = Util.StringToBytes256(text); | 3416 | outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; |
3382 | objectData.TextColor[0] = color[0]; | 3417 | outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); |
3383 | objectData.TextColor[1] = color[1]; | ||
3384 | objectData.TextColor[2] = color[2]; | ||
3385 | objectData.TextColor[3] = color[3]; | ||
3386 | objectData.ParentID = parentID; | ||
3387 | objectData.PSBlock = particleSystem; | ||
3388 | objectData.ClickAction = clickAction; | ||
3389 | objectData.Material = material; | ||
3390 | objectData.Flags = 0; | ||
3391 | 3418 | ||
3392 | if (attachment) | 3419 | lock (m_primFullUpdates.SyncRoot) |
3393 | { | 3420 | { |
3394 | // Necessary??? | 3421 | int count = Math.Min(m_primFullUpdates.Count, m_primFullUpdatesPerPacket); |
3395 | objectData.JointAxisOrAnchor = new Vector3(0, 0, 2); | 3422 | if (count == 0) |
3396 | objectData.JointPivot = new Vector3(0, 0, 0); | 3423 | return; |
3397 | |||
3398 | // Item from inventory??? | ||
3399 | objectData.NameValue = | ||
3400 | Utils.StringToBytes("AttachItemID STRING RW SV " + AssetId.Guid); | ||
3401 | objectData.State = (byte)((AttachPoint % 16) * 16 + (AttachPoint / 16)); | ||
3402 | } | ||
3403 | 3424 | ||
3404 | // Xantor 20080528: Send sound info as well | 3425 | outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[count]; |
3405 | // Xantor 20080530: Zero out everything if there's no SoundId, so zerocompression will work again | 3426 | for (int i = 0; i < count; i++) |
3406 | objectData.Sound = SoundId; | 3427 | outPacket.ObjectData[i] = m_primFullUpdates.Dequeue(); |
3407 | if (SoundId == UUID.Zero) | ||
3408 | { | ||
3409 | objectData.OwnerID = UUID.Zero; | ||
3410 | objectData.Gain = 0.0f; | ||
3411 | objectData.Radius = 0.0f; | ||
3412 | objectData.Flags = 0; | ||
3413 | } | ||
3414 | else | ||
3415 | { | ||
3416 | objectData.OwnerID = ownerID; | ||
3417 | objectData.Gain = (float)SoundGain; | ||
3418 | objectData.Radius = (float)SoundRadius; | ||
3419 | objectData.Flags = SoundFlags; | ||
3420 | } | 3428 | } |
3421 | 3429 | ||
3422 | byte[] pb = pos.GetBytes(); | 3430 | OutPacket(outPacket, ThrottleOutPacketType.State); |
3423 | Array.Copy(pb, 0, objectData.ObjectData, 0, pb.Length); | 3431 | } |
3424 | |||
3425 | byte[] vel = velocity.GetBytes(); | ||
3426 | Array.Copy(vel, 0, objectData.ObjectData, pb.Length, vel.Length); | ||
3427 | |||
3428 | byte[] rot = rotation.GetBytes(); | ||
3429 | Array.Copy(rot, 0, objectData.ObjectData, 36, rot.Length); | ||
3430 | |||
3431 | byte[] rvel = rotational_velocity.GetBytes(); | ||
3432 | Array.Copy(rvel, 0, objectData.ObjectData, 36 + rot.Length, rvel.Length); | ||
3433 | 3432 | ||
3434 | if (textureanim.Length > 0) | 3433 | public void SendPrimTerseUpdate(SendPrimitiveTerseData data) |
3434 | { | ||
3435 | if (data.Priority == double.NaN) | ||
3435 | { | 3436 | { |
3436 | objectData.TextureAnim = textureanim; | 3437 | m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update"); |
3438 | return; | ||
3437 | } | 3439 | } |
3438 | 3440 | ||
3439 | lock (m_primFullUpdates) | 3441 | Quaternion rotation = data.Rotation; |
3440 | { | 3442 | if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) |
3441 | if (m_primFullUpdates.Count == 0) | 3443 | rotation = Quaternion.Identity; |
3442 | m_primFullUpdateTimer.Start(); | ||
3443 | 3444 | ||
3444 | m_primFullUpdates.Add(objectData); | 3445 | if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD |
3446 | return; | ||
3445 | 3447 | ||
3446 | if (m_primFullUpdates.Count >= m_primFullUpdatesPerPacket) | 3448 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data); |
3447 | ProcessPrimFullUpdates(this, null); | ||
3448 | } | ||
3449 | } | ||
3450 | 3449 | ||
3451 | void HandleQueueEmpty(ThrottleOutPacketType queue) | 3450 | lock (m_primTerseUpdates.SyncRoot) |
3452 | { | 3451 | m_primTerseUpdates.Enqueue(data.Priority, objectData, data.LocalID); |
3453 | switch (queue) | ||
3454 | { | ||
3455 | case ThrottleOutPacketType.Texture: | ||
3456 | ProcessTextureRequests(); | ||
3457 | break; | ||
3458 | } | ||
3459 | } | 3452 | } |
3460 | 3453 | ||
3461 | void ProcessTextureRequests() | 3454 | void ProcessPrimTerseUpdates() |
3462 | { | 3455 | { |
3463 | if (m_imageManager != null) | 3456 | ImprovedTerseObjectUpdatePacket outPacket = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); |
3464 | m_imageManager.ProcessImageQueue(m_textureSendLimit); | 3457 | outPacket.Header.Reliable = false; |
3465 | } | 3458 | outPacket.Header.Zerocoded = true; |
3466 | 3459 | ||
3467 | void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) | 3460 | outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; |
3468 | { | 3461 | outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); |
3469 | lock (m_primFullUpdates) | ||
3470 | { | ||
3471 | if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) | ||
3472 | { | ||
3473 | lock (m_primFullUpdateTimer) | ||
3474 | m_primFullUpdateTimer.Stop(); | ||
3475 | 3462 | ||
3463 | lock (m_primTerseUpdates.SyncRoot) | ||
3464 | { | ||
3465 | int count = Math.Min(m_primTerseUpdates.Count, m_primTerseUpdatesPerPacket); | ||
3466 | if (count == 0) | ||
3476 | return; | 3467 | return; |
3477 | } | ||
3478 | |||
3479 | ObjectUpdatePacket outPacket = | ||
3480 | (ObjectUpdatePacket)PacketPool.Instance.GetPacket( | ||
3481 | PacketType.ObjectUpdate); | ||
3482 | 3468 | ||
3483 | outPacket.RegionData.RegionHandle = | 3469 | outPacket.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; |
3484 | Scene.RegionInfo.RegionHandle; | 3470 | for (int i = 0; i < count; i++) |
3485 | outPacket.RegionData.TimeDilation = | 3471 | outPacket.ObjectData[i] = m_primTerseUpdates.Dequeue(); |
3486 | (ushort)(Scene.TimeDilation * ushort.MaxValue); | 3472 | } |
3487 | |||
3488 | int max = m_primFullUpdates.Count; | ||
3489 | if (max > m_primFullUpdatesPerPacket) | ||
3490 | max = m_primFullUpdatesPerPacket; | ||
3491 | |||
3492 | int count = 0; | ||
3493 | int size = 0; | ||
3494 | 3473 | ||
3495 | byte[] zerobuffer = new byte[1024]; | 3474 | OutPacket(outPacket, ThrottleOutPacketType.State); |
3496 | byte[] blockbuffer = new byte[1024]; | 3475 | } |
3497 | 3476 | ||
3498 | for (count = 0 ; count < max ; count++) | 3477 | public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) |
3478 | { | ||
3479 | PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler terse_update_priority_handler = | ||
3480 | delegate(ref double priority, uint local_id) | ||
3499 | { | 3481 | { |
3500 | int length = 0; | 3482 | priority = handler(new UpdatePriorityData(priority, local_id)); |
3501 | m_primFullUpdates[count].ToBytes(blockbuffer, ref length); | 3483 | return priority != double.NaN; |
3502 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); | 3484 | }; |
3503 | if (size + length > Packet.MTU) | 3485 | PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler update_priority_handler = |
3504 | break; | 3486 | delegate(ref double priority, uint local_id) |
3505 | size += length; | 3487 | { |
3506 | } | 3488 | priority = handler(new UpdatePriorityData(priority, local_id)); |
3489 | return priority != double.NaN; | ||
3490 | }; | ||
3507 | 3491 | ||
3508 | outPacket.ObjectData = | 3492 | if ((type & StateUpdateTypes.AvatarTerse) != 0) |
3509 | new ObjectUpdatePacket.ObjectDataBlock[count]; | 3493 | { |
3494 | lock (m_avatarTerseUpdates.SyncRoot) | ||
3495 | m_avatarTerseUpdates.Reprioritize(terse_update_priority_handler); | ||
3496 | } | ||
3510 | 3497 | ||
3511 | for (int index = 0 ; index < count ; index++) | 3498 | if ((type & StateUpdateTypes.PrimitiveFull) != 0) |
3512 | { | 3499 | { |
3513 | outPacket.ObjectData[index] = m_primFullUpdates[0]; | 3500 | lock (m_primFullUpdates.SyncRoot) |
3514 | m_primFullUpdates.RemoveAt(0); | 3501 | m_primFullUpdates.Reprioritize(update_priority_handler); |
3515 | } | 3502 | } |
3516 | 3503 | ||
3517 | outPacket.Header.Zerocoded = true; | 3504 | if ((type & StateUpdateTypes.PrimitiveTerse) != 0) |
3518 | OutPacket(outPacket, ThrottleOutPacketType.State); | 3505 | { |
3506 | lock (m_primTerseUpdates.SyncRoot) | ||
3507 | m_primTerseUpdates.Reprioritize(terse_update_priority_handler); | ||
3508 | } | ||
3509 | } | ||
3519 | 3510 | ||
3520 | if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) | 3511 | public void FlushPrimUpdates() |
3521 | lock (m_primFullUpdateTimer) | 3512 | { |
3522 | m_primFullUpdateTimer.Stop(); | 3513 | while (m_primFullUpdates.Count > 0) |
3514 | { | ||
3515 | ProcessPrimFullUpdates(); | ||
3516 | } | ||
3517 | while (m_primTerseUpdates.Count > 0) | ||
3518 | { | ||
3519 | ProcessPrimTerseUpdates(); | ||
3520 | } | ||
3521 | while (m_avatarTerseUpdates.Count > 0) | ||
3522 | { | ||
3523 | ProcessAvatarTerseUpdates(); | ||
3523 | } | 3524 | } |
3524 | } | 3525 | } |
3525 | 3526 | ||
3527 | #endregion Primitive Packet/Data Sending Methods | ||
3528 | |||
3526 | /// <summary> | 3529 | /// <summary> |
3527 | /// | 3530 | /// |
3528 | /// </summary> | 3531 | /// </summary> |
3529 | public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, | 3532 | /// <param name="localID"></param> |
3530 | Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint) | 3533 | /// <param name="rotation"></param> |
3534 | /// <param name="attachPoint"></param> | ||
3535 | public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||
3531 | { | 3536 | { |
3532 | if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD | 3537 | if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD |
3533 | return; | 3538 | return; |
3534 | 3539 | ||
3535 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) | 3540 | ObjectAttachPacket attach = (ObjectAttachPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAttach); |
3536 | rotation = Quaternion.Identity; | 3541 | // TODO: don't create new blocks if recycling an old packet |
3537 | 3542 | attach.AgentData.AgentID = AgentId; | |
3538 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = | 3543 | attach.AgentData.SessionID = m_sessionId; |
3539 | CreatePrimImprovedBlock(localID, position, rotation, | 3544 | attach.AgentData.AttachmentPoint = attachPoint; |
3540 | velocity, rotationalvelocity, state); | 3545 | attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1]; |
3541 | 3546 | attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock(); | |
3542 | lock (m_primTerseUpdates) | 3547 | attach.ObjectData[0].ObjectLocalID = localID; |
3543 | { | 3548 | attach.ObjectData[0].Rotation = rotation; |
3544 | if (m_primTerseUpdates.Count == 0) | 3549 | attach.Header.Zerocoded = true; |
3545 | m_primTerseUpdateTimer.Start(); | 3550 | OutPacket(attach, ThrottleOutPacketType.Task); |
3546 | |||
3547 | m_primTerseUpdates.Add(objectData); | ||
3548 | |||
3549 | if (m_primTerseUpdates.Count >= m_primTerseUpdatesPerPacket) | ||
3550 | ProcessPrimTerseUpdates(this, null); | ||
3551 | } | ||
3552 | } | 3551 | } |
3553 | 3552 | ||
3554 | void ProcessPrimTerseUpdates(object sender, ElapsedEventArgs e) | 3553 | void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) |
3555 | { | 3554 | { |
3556 | lock (m_primTerseUpdates) | 3555 | if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) |
3557 | { | 3556 | { |
3558 | if (m_primTerseUpdates.Count == 0) | 3557 | lock (m_avatarTerseUpdates.SyncRoot) |
3559 | { | 3558 | { |
3560 | lock (m_primTerseUpdateTimer) | 3559 | if (m_avatarTerseUpdates.Count > 0) |
3561 | m_primTerseUpdateTimer.Stop(); | 3560 | ProcessAvatarTerseUpdates(); |
3562 | |||
3563 | return; | ||
3564 | } | 3561 | } |
3562 | } | ||
3565 | 3563 | ||
3566 | ImprovedTerseObjectUpdatePacket outPacket = | 3564 | if ((categories & ThrottleOutPacketTypeFlags.State) != 0) |
3567 | (ImprovedTerseObjectUpdatePacket) | 3565 | { |
3568 | PacketPool.Instance.GetPacket( | 3566 | lock (m_primFullUpdates.SyncRoot) |
3569 | PacketType.ImprovedTerseObjectUpdate); | ||
3570 | |||
3571 | outPacket.RegionData.RegionHandle = | ||
3572 | Scene.RegionInfo.RegionHandle; | ||
3573 | outPacket.RegionData.TimeDilation = | ||
3574 | (ushort)(Scene.TimeDilation * ushort.MaxValue); | ||
3575 | |||
3576 | int max = m_primTerseUpdates.Count; | ||
3577 | if (max > m_primTerseUpdatesPerPacket) | ||
3578 | max = m_primTerseUpdatesPerPacket; | ||
3579 | |||
3580 | int count = 0; | ||
3581 | int size = 0; | ||
3582 | |||
3583 | byte[] zerobuffer = new byte[1024]; | ||
3584 | byte[] blockbuffer = new byte[1024]; | ||
3585 | |||
3586 | for (count = 0 ; count < max ; count++) | ||
3587 | { | 3567 | { |
3588 | int length = 0; | 3568 | if (m_primFullUpdates.Count > 0) |
3589 | m_primTerseUpdates[count].ToBytes(blockbuffer, ref length); | 3569 | ProcessPrimFullUpdates(); |
3590 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); | ||
3591 | if (size + length > Packet.MTU) | ||
3592 | break; | ||
3593 | size += length; | ||
3594 | } | 3570 | } |
3595 | 3571 | ||
3596 | outPacket.ObjectData = | 3572 | lock (m_primTerseUpdates.SyncRoot) |
3597 | new ImprovedTerseObjectUpdatePacket. | ||
3598 | ObjectDataBlock[count]; | ||
3599 | |||
3600 | for (int index = 0 ; index < count ; index++) | ||
3601 | { | 3573 | { |
3602 | outPacket.ObjectData[index] = m_primTerseUpdates[0]; | 3574 | if (m_primTerseUpdates.Count > 0) |
3603 | m_primTerseUpdates.RemoveAt(0); | 3575 | ProcessPrimTerseUpdates(); |
3604 | } | 3576 | } |
3577 | } | ||
3605 | 3578 | ||
3606 | outPacket.Header.Reliable = false; | 3579 | if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) |
3607 | outPacket.Header.Zerocoded = true; | 3580 | { |
3608 | OutPacket(outPacket, ThrottleOutPacketType.State); | 3581 | ProcessTextureRequests(); |
3609 | |||
3610 | if (m_primTerseUpdates.Count == 0) | ||
3611 | lock (m_primTerseUpdateTimer) | ||
3612 | m_primTerseUpdateTimer.Stop(); | ||
3613 | } | 3582 | } |
3614 | } | 3583 | } |
3615 | 3584 | ||
3616 | public void FlushPrimUpdates() | 3585 | void ProcessTextureRequests() |
3617 | { | 3586 | { |
3618 | while (m_primFullUpdates.Count > 0) | 3587 | if (m_imageManager != null) |
3619 | { | 3588 | m_imageManager.ProcessImageQueue(m_textureSendLimit); |
3620 | ProcessPrimFullUpdates(this, null); | ||
3621 | } | ||
3622 | while (m_primTerseUpdates.Count > 0) | ||
3623 | { | ||
3624 | ProcessPrimTerseUpdates(this, null); | ||
3625 | } | ||
3626 | while (m_avatarTerseUpdates.Count > 0) | ||
3627 | { | ||
3628 | ProcessAvatarTerseUpdates(this, null); | ||
3629 | } | ||
3630 | } | 3589 | } |
3631 | 3590 | ||
3632 | public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) | 3591 | public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) |
@@ -3659,7 +3618,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3659 | newPack.Header.Zerocoded = true; | 3618 | newPack.Header.Zerocoded = true; |
3660 | OutPacket(newPack, ThrottleOutPacketType.Asset); | 3619 | OutPacket(newPack, ThrottleOutPacketType.Asset); |
3661 | } | 3620 | } |
3662 | 3621 | ||
3663 | public void SendInitiateDownload(string simFileName, string clientFileName) | 3622 | public void SendInitiateDownload(string simFileName, string clientFileName) |
3664 | { | 3623 | { |
3665 | InitiateDownloadPacket newPack = new InitiateDownloadPacket(); | 3624 | InitiateDownloadPacket newPack = new InitiateDownloadPacket(); |
@@ -3668,7 +3627,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3668 | newPack.FileData.ViewerFilename = Utils.StringToBytes(clientFileName); | 3627 | newPack.FileData.ViewerFilename = Utils.StringToBytes(clientFileName); |
3669 | OutPacket(newPack, ThrottleOutPacketType.Asset); | 3628 | OutPacket(newPack, ThrottleOutPacketType.Asset); |
3670 | } | 3629 | } |
3671 | 3630 | ||
3672 | public void SendImageFirstPart( | 3631 | public void SendImageFirstPart( |
3673 | ushort numParts, UUID ImageUUID, uint ImageSize, byte[] ImageData, byte imageCodec) | 3632 | ushort numParts, UUID ImageUUID, uint ImageSize, byte[] ImageData, byte imageCodec) |
3674 | { | 3633 | { |
@@ -3810,8 +3769,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3810 | OutPacket(proper, ThrottleOutPacketType.Task); | 3769 | OutPacket(proper, ThrottleOutPacketType.Task); |
3811 | } | 3770 | } |
3812 | 3771 | ||
3813 | #endregion | ||
3814 | |||
3815 | #region Estate Data Sending Methods | 3772 | #region Estate Data Sending Methods |
3816 | 3773 | ||
3817 | private static bool convertParamStringToBool(byte[] field) | 3774 | private static bool convertParamStringToBool(byte[] field) |
@@ -3858,7 +3815,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3858 | 3815 | ||
3859 | public void SendBannedUserList(UUID invoice, EstateBan[] bl, uint estateID) | 3816 | public void SendBannedUserList(UUID invoice, EstateBan[] bl, uint estateID) |
3860 | { | 3817 | { |
3861 | List<UUID>BannedUsers = new List<UUID>(); | 3818 | List<UUID> BannedUsers = new List<UUID>(); |
3862 | 3819 | ||
3863 | for (int i = 0; i < bl.Length; i++) | 3820 | for (int i = 0; i < bl.Length; i++) |
3864 | { | 3821 | { |
@@ -3922,7 +3879,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3922 | rinfoblk.UseEstateSun = args.useEstateSun; | 3879 | rinfoblk.UseEstateSun = args.useEstateSun; |
3923 | rinfoblk.WaterHeight = args.waterHeight; | 3880 | rinfoblk.WaterHeight = args.waterHeight; |
3924 | rinfoblk.SimName = Utils.StringToBytes(args.simName); | 3881 | rinfoblk.SimName = Utils.StringToBytes(args.simName); |
3925 | 3882 | ||
3926 | rinfopack.RegionInfo2 = new RegionInfoPacket.RegionInfo2Block(); | 3883 | rinfopack.RegionInfo2 = new RegionInfoPacket.RegionInfo2Block(); |
3927 | rinfopack.RegionInfo2.HardMaxAgents = uint.MaxValue; | 3884 | rinfopack.RegionInfo2.HardMaxAgents = uint.MaxValue; |
3928 | rinfopack.RegionInfo2.HardMaxObjects = uint.MaxValue; | 3885 | rinfopack.RegionInfo2.HardMaxObjects = uint.MaxValue; |
@@ -4169,7 +4126,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4169 | 4126 | ||
4170 | public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount) | 4127 | public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount) |
4171 | { | 4128 | { |
4172 | 4129 | ||
4173 | 4130 | ||
4174 | int notifyCount = ownersAndCount.Count; | 4131 | int notifyCount = ownersAndCount.Count; |
4175 | ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply); | 4132 | ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply); |
@@ -4218,325 +4175,223 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4218 | 4175 | ||
4219 | #region Helper Methods | 4176 | #region Helper Methods |
4220 | 4177 | ||
4221 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateAvatarImprovedBlock(uint localID, Vector3 pos, | 4178 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendAvatarTerseData data) |
4222 | Vector3 velocity, | ||
4223 | Quaternion rotation) | ||
4224 | { | 4179 | { |
4225 | byte[] bytes = new byte[60]; | 4180 | return CreateImprovedTerseBlock(true, data.LocalID, 0, data.CollisionPlane, data.Position, data.Velocity, |
4226 | int i = 0; | 4181 | data.Acceleration, data.Rotation, Vector3.Zero, data.TextureEntry); |
4227 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = PacketPool.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||
4228 | |||
4229 | dat.TextureEntry = new byte[0]; // AvatarTemplate.TextureEntry; | ||
4230 | |||
4231 | uint ID = localID; | ||
4232 | |||
4233 | bytes[i++] = (byte)(ID % 256); | ||
4234 | bytes[i++] = (byte)((ID >> 8) % 256); | ||
4235 | bytes[i++] = (byte)((ID >> 16) % 256); | ||
4236 | bytes[i++] = (byte)((ID >> 24) % 256); | ||
4237 | bytes[i++] = 0; | ||
4238 | bytes[i++] = 1; | ||
4239 | i += 14; | ||
4240 | bytes[i++] = 128; | ||
4241 | bytes[i++] = 63; | ||
4242 | |||
4243 | byte[] pb = pos.GetBytes(); | ||
4244 | Array.Copy(pb, 0, bytes, i, pb.Length); | ||
4245 | i += 12; | ||
4246 | |||
4247 | Vector3 internDirec = new Vector3(velocity.X, velocity.Y, velocity.Z); | ||
4248 | |||
4249 | internDirec = internDirec / 128.0f; | ||
4250 | internDirec.X += 1; | ||
4251 | internDirec.Y += 1; | ||
4252 | internDirec.Z += 1; | ||
4253 | |||
4254 | ushort InternVelocityX = (ushort)(32768 * internDirec.X); | ||
4255 | ushort InternVelocityY = (ushort)(32768 * internDirec.Y); | ||
4256 | ushort InternVelocityZ = (ushort)(32768 * internDirec.Z); | ||
4257 | |||
4258 | ushort ac = 32767; | ||
4259 | bytes[i++] = (byte)(InternVelocityX % 256); | ||
4260 | bytes[i++] = (byte)((InternVelocityX >> 8) % 256); | ||
4261 | bytes[i++] = (byte)(InternVelocityY % 256); | ||
4262 | bytes[i++] = (byte)((InternVelocityY >> 8) % 256); | ||
4263 | bytes[i++] = (byte)(InternVelocityZ % 256); | ||
4264 | bytes[i++] = (byte)((InternVelocityZ >> 8) % 256); | ||
4265 | |||
4266 | //accel | ||
4267 | bytes[i++] = (byte)(ac % 256); | ||
4268 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4269 | bytes[i++] = (byte)(ac % 256); | ||
4270 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4271 | bytes[i++] = (byte)(ac % 256); | ||
4272 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4273 | |||
4274 | //rotation | ||
4275 | ushort rw, rx, ry, rz; | ||
4276 | rw = (ushort)(32768 * (rotation.W + 1)); | ||
4277 | rx = (ushort)(32768 * (rotation.X + 1)); | ||
4278 | ry = (ushort)(32768 * (rotation.Y + 1)); | ||
4279 | rz = (ushort)(32768 * (rotation.Z + 1)); | ||
4280 | |||
4281 | //rot | ||
4282 | bytes[i++] = (byte)(rx % 256); | ||
4283 | bytes[i++] = (byte)((rx >> 8) % 256); | ||
4284 | bytes[i++] = (byte)(ry % 256); | ||
4285 | bytes[i++] = (byte)((ry >> 8) % 256); | ||
4286 | bytes[i++] = (byte)(rz % 256); | ||
4287 | bytes[i++] = (byte)((rz >> 8) % 256); | ||
4288 | bytes[i++] = (byte)(rw % 256); | ||
4289 | bytes[i++] = (byte)((rw >> 8) % 256); | ||
4290 | |||
4291 | //rotation vel | ||
4292 | bytes[i++] = (byte)(ac % 256); | ||
4293 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4294 | bytes[i++] = (byte)(ac % 256); | ||
4295 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4296 | bytes[i++] = (byte)(ac % 256); | ||
4297 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4298 | |||
4299 | dat.Data = bytes; | ||
4300 | |||
4301 | return (dat); | ||
4302 | } | 4182 | } |
4303 | 4183 | ||
4304 | /// <summary> | 4184 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendPrimitiveTerseData data) |
4305 | /// | ||
4306 | /// </summary> | ||
4307 | /// <param name="localID"></param> | ||
4308 | /// <param name="position"></param> | ||
4309 | /// <param name="rotation"></param> | ||
4310 | /// <returns></returns> | ||
4311 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreatePrimImprovedBlock(uint localID, | ||
4312 | Vector3 position, | ||
4313 | Quaternion rotation, | ||
4314 | Vector3 velocity, | ||
4315 | Vector3 rotationalvelocity, | ||
4316 | byte state) | ||
4317 | { | 4185 | { |
4318 | uint ID = localID; | 4186 | return CreateImprovedTerseBlock(false, data.LocalID, data.State, Vector4.Zero, data.Position, data.Velocity, |
4319 | byte[] bytes = new byte[60]; | 4187 | data.Acceleration, data.Rotation, data.AngularVelocity, data.TextureEntry); |
4320 | |||
4321 | int i = 0; | ||
4322 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = PacketPool.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||
4323 | dat.TextureEntry = new byte[0]; | ||
4324 | bytes[i++] = (byte)(ID % 256); | ||
4325 | bytes[i++] = (byte)((ID >> 8) % 256); | ||
4326 | bytes[i++] = (byte)((ID >> 16) % 256); | ||
4327 | bytes[i++] = (byte)((ID >> 24) % 256); | ||
4328 | bytes[i++] = (byte)(((state & 0xf0) >> 4) | ((state & 0x0f) << 4)); | ||
4329 | bytes[i++] = 0; | ||
4330 | |||
4331 | byte[] pb = position.GetBytes(); | ||
4332 | Array.Copy(pb, 0, bytes, i, pb.Length); | ||
4333 | i += 12; | ||
4334 | ushort ac = 32767; | ||
4335 | |||
4336 | ushort velx, vely, velz; | ||
4337 | Vector3 vel = new Vector3(velocity.X, velocity.Y, velocity.Z); | ||
4338 | |||
4339 | vel = vel / 128.0f; | ||
4340 | vel.X += 1; | ||
4341 | vel.Y += 1; | ||
4342 | vel.Z += 1; | ||
4343 | //vel | ||
4344 | velx = (ushort)(32768 * (vel.X)); | ||
4345 | vely = (ushort)(32768 * (vel.Y)); | ||
4346 | velz = (ushort)(32768 * (vel.Z)); | ||
4347 | |||
4348 | bytes[i++] = (byte)(velx % 256); | ||
4349 | bytes[i++] = (byte)((velx >> 8) % 256); | ||
4350 | bytes[i++] = (byte)(vely % 256); | ||
4351 | bytes[i++] = (byte)((vely >> 8) % 256); | ||
4352 | bytes[i++] = (byte)(velz % 256); | ||
4353 | bytes[i++] = (byte)((velz >> 8) % 256); | ||
4354 | |||
4355 | //accel | ||
4356 | bytes[i++] = (byte)(ac % 256); | ||
4357 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4358 | bytes[i++] = (byte)(ac % 256); | ||
4359 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4360 | bytes[i++] = (byte)(ac % 256); | ||
4361 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4362 | |||
4363 | ushort rw, rx, ry, rz; | ||
4364 | rw = (ushort)(32768 * (rotation.W + 1)); | ||
4365 | rx = (ushort)(32768 * (rotation.X + 1)); | ||
4366 | ry = (ushort)(32768 * (rotation.Y + 1)); | ||
4367 | rz = (ushort)(32768 * (rotation.Z + 1)); | ||
4368 | |||
4369 | //rot | ||
4370 | bytes[i++] = (byte)(rx % 256); | ||
4371 | bytes[i++] = (byte)((rx >> 8) % 256); | ||
4372 | bytes[i++] = (byte)(ry % 256); | ||
4373 | bytes[i++] = (byte)((ry >> 8) % 256); | ||
4374 | bytes[i++] = (byte)(rz % 256); | ||
4375 | bytes[i++] = (byte)((rz >> 8) % 256); | ||
4376 | bytes[i++] = (byte)(rw % 256); | ||
4377 | bytes[i++] = (byte)((rw >> 8) % 256); | ||
4378 | |||
4379 | //rotation vel | ||
4380 | Vector3 rvel = new Vector3(rotationalvelocity.X, rotationalvelocity.Y, rotationalvelocity.Z); | ||
4381 | |||
4382 | rvel = rvel / 128.0f; | ||
4383 | rvel.X += 1; | ||
4384 | rvel.Y += 1; | ||
4385 | rvel.Z += 1; | ||
4386 | //vel | ||
4387 | ushort rvelx = (ushort)(32768 * (rvel.X)); | ||
4388 | ushort rvely = (ushort)(32768 * (rvel.Y)); | ||
4389 | ushort rvelz = (ushort)(32768 * (rvel.Z)); | ||
4390 | |||
4391 | bytes[i++] = (byte)(rvelx % 256); | ||
4392 | bytes[i++] = (byte)((rvelx >> 8) % 256); | ||
4393 | bytes[i++] = (byte)(rvely % 256); | ||
4394 | bytes[i++] = (byte)((rvely >> 8) % 256); | ||
4395 | bytes[i++] = (byte)(rvelz % 256); | ||
4396 | bytes[i++] = (byte)((rvelz >> 8) % 256); | ||
4397 | dat.Data = bytes; | ||
4398 | |||
4399 | return dat; | ||
4400 | } | 4188 | } |
4401 | 4189 | ||
4402 | /// <summary> | 4190 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, byte state, |
4403 | /// Create the ObjectDataBlock for a ObjectUpdatePacket (for a Primitive) | 4191 | Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation, |
4404 | /// </summary> | 4192 | Vector3 angularVelocity, byte[] textureEntry) |
4405 | /// <param name="primData"></param> | 4193 | { |
4406 | /// <returns></returns> | 4194 | int pos = 0; |
4407 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(PrimitiveBaseShape primShape, uint flags) | 4195 | byte[] data = new byte[(avatar ? 60 : 44)]; |
4408 | { | ||
4409 | ObjectUpdatePacket.ObjectDataBlock objupdate = PacketPool.GetDataBlock<ObjectUpdatePacket.ObjectDataBlock>(); | ||
4410 | SetDefaultPrimPacketValues(objupdate); | ||
4411 | objupdate.UpdateFlags = flags; | ||
4412 | SetPrimPacketShapeData(objupdate, primShape); | ||
4413 | |||
4414 | if ((primShape.PCode == (byte)PCode.NewTree) || (primShape.PCode == (byte)PCode.Tree) || (primShape.PCode == (byte)PCode.Grass)) | ||
4415 | { | ||
4416 | objupdate.Data = new byte[1]; | ||
4417 | objupdate.Data[0] = primShape.State; | ||
4418 | } | ||
4419 | return objupdate; | ||
4420 | } | ||
4421 | |||
4422 | protected void SetPrimPacketShapeData(ObjectUpdatePacket.ObjectDataBlock objectData, PrimitiveBaseShape primData) | ||
4423 | { | ||
4424 | objectData.TextureEntry = primData.TextureEntry; | ||
4425 | objectData.PCode = primData.PCode; | ||
4426 | objectData.State = primData.State; | ||
4427 | objectData.PathBegin = primData.PathBegin; | ||
4428 | objectData.PathEnd = primData.PathEnd; | ||
4429 | objectData.PathScaleX = primData.PathScaleX; | ||
4430 | objectData.PathScaleY = primData.PathScaleY; | ||
4431 | objectData.PathShearX = primData.PathShearX; | ||
4432 | objectData.PathShearY = primData.PathShearY; | ||
4433 | objectData.PathSkew = primData.PathSkew; | ||
4434 | objectData.ProfileBegin = primData.ProfileBegin; | ||
4435 | objectData.ProfileEnd = primData.ProfileEnd; | ||
4436 | objectData.Scale = primData.Scale; | ||
4437 | objectData.PathCurve = primData.PathCurve; | ||
4438 | objectData.ProfileCurve = primData.ProfileCurve; | ||
4439 | objectData.ProfileHollow = primData.ProfileHollow; | ||
4440 | objectData.PathRadiusOffset = primData.PathRadiusOffset; | ||
4441 | objectData.PathRevolutions = primData.PathRevolutions; | ||
4442 | objectData.PathTaperX = primData.PathTaperX; | ||
4443 | objectData.PathTaperY = primData.PathTaperY; | ||
4444 | objectData.PathTwist = primData.PathTwist; | ||
4445 | objectData.PathTwistBegin = primData.PathTwistBegin; | ||
4446 | objectData.ExtraParams = primData.ExtraParams; | ||
4447 | } | ||
4448 | 4196 | ||
4449 | /// <summary> | 4197 | // LocalID |
4450 | /// Set some default values in a ObjectUpdatePacket | 4198 | Utils.UIntToBytes(localID, data, pos); |
4451 | /// </summary> | 4199 | pos += 4; |
4452 | /// <param name="objdata"></param> | ||
4453 | protected void SetDefaultPrimPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata) | ||
4454 | { | ||
4455 | objdata.PSBlock = new byte[0]; | ||
4456 | objdata.ExtraParams = new byte[1]; | ||
4457 | objdata.MediaURL = new byte[0]; | ||
4458 | objdata.NameValue = new byte[0]; | ||
4459 | objdata.Text = new byte[0]; | ||
4460 | objdata.TextColor = new byte[4]; | ||
4461 | objdata.JointAxisOrAnchor = new Vector3(0, 0, 0); | ||
4462 | objdata.JointPivot = new Vector3(0, 0, 0); | ||
4463 | objdata.Material = 3; | ||
4464 | objdata.TextureAnim = new byte[0]; | ||
4465 | objdata.Sound = UUID.Zero; | ||
4466 | objdata.State = 0; | ||
4467 | objdata.Data = new byte[0]; | ||
4468 | |||
4469 | objdata.ObjectData = new byte[60]; | ||
4470 | objdata.ObjectData[46] = 128; | ||
4471 | objdata.ObjectData[47] = 63; | ||
4472 | } | ||
4473 | 4200 | ||
4474 | /// <summary> | 4201 | // Avatar/CollisionPlane |
4475 | /// | 4202 | data[pos++] = state; |
4476 | /// </summary> | 4203 | if (avatar) |
4477 | /// <returns></returns> | 4204 | { |
4478 | public ObjectUpdatePacket.ObjectDataBlock CreateDefaultAvatarPacket(byte[] textureEntry) | 4205 | data[pos++] = 1; |
4479 | { | 4206 | |
4480 | ObjectUpdatePacket.ObjectDataBlock objdata = PacketPool.GetDataBlock<ObjectUpdatePacket.ObjectDataBlock>(); | 4207 | if (collisionPlane == Vector4.Zero) |
4481 | // new OpenMetaverse.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i); | 4208 | collisionPlane = Vector4.UnitW; |
4482 | 4209 | ||
4483 | SetDefaultAvatarPacketValues(ref objdata); | 4210 | collisionPlane.ToBytes(data, pos); |
4484 | objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24); | 4211 | pos += 16; |
4485 | objdata.PathCurve = 16; | 4212 | } |
4486 | objdata.ProfileCurve = 1; | 4213 | else |
4487 | objdata.PathScaleX = 100; | ||
4488 | objdata.PathScaleY = 100; | ||
4489 | objdata.ParentID = 0; | ||
4490 | objdata.OwnerID = UUID.Zero; | ||
4491 | objdata.Scale = new Vector3(1, 1, 1); | ||
4492 | objdata.PCode = (byte)PCode.Avatar; | ||
4493 | if (textureEntry != null) | ||
4494 | { | 4214 | { |
4495 | objdata.TextureEntry = textureEntry; | 4215 | ++pos; |
4496 | } | 4216 | } |
4497 | Vector3 pos = new Vector3(objdata.ObjectData, 16); | ||
4498 | pos.X = 100f; | ||
4499 | objdata.ID = 8880000; | ||
4500 | objdata.NameValue = Utils.StringToBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User "); | ||
4501 | //Vector3 pos2 = new Vector3(100f, 100f, 23f); | ||
4502 | //objdata.FullID=user.AgentId; | ||
4503 | byte[] pb = pos.GetBytes(); | ||
4504 | Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length); | ||
4505 | 4217 | ||
4506 | return objdata; | 4218 | // Position |
4507 | } | 4219 | position.ToBytes(data, pos); |
4220 | pos += 12; | ||
4508 | 4221 | ||
4509 | /// <summary> | 4222 | // Velocity |
4510 | /// | 4223 | Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.X, -128.0f, 128.0f), data, pos); pos += 2; |
4511 | /// </summary> | 4224 | Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Y, -128.0f, 128.0f), data, pos); pos += 2; |
4512 | /// <param name="objdata"></param> | 4225 | Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Z, -128.0f, 128.0f), data, pos); pos += 2; |
4513 | protected void SetDefaultAvatarPacketValues(ref ObjectUpdatePacket.ObjectDataBlock objdata) | 4226 | |
4514 | { | 4227 | // Acceleration |
4515 | objdata.PSBlock = new byte[0]; | 4228 | Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.X, -64.0f, 64.0f), data, pos); pos += 2; |
4516 | objdata.ExtraParams = new byte[1]; | 4229 | Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2; |
4517 | objdata.MediaURL = new byte[0]; | 4230 | Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2; |
4518 | objdata.NameValue = new byte[0]; | 4231 | |
4519 | objdata.Text = new byte[0]; | 4232 | // Rotation |
4520 | objdata.TextColor = new byte[4]; | 4233 | Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.X, -1.0f, 1.0f), data, pos); pos += 2; |
4521 | objdata.JointAxisOrAnchor = new Vector3(0, 0, 0); | 4234 | Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.Y, -1.0f, 1.0f), data, pos); pos += 2; |
4522 | objdata.JointPivot = new Vector3(0, 0, 0); | 4235 | Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.Z, -1.0f, 1.0f), data, pos); pos += 2; |
4523 | objdata.Material = 4; | 4236 | Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.W, -1.0f, 1.0f), data, pos); pos += 2; |
4524 | objdata.TextureAnim = new byte[0]; | 4237 | |
4525 | objdata.Sound = UUID.Zero; | 4238 | // Angular Velocity |
4526 | Primitive.TextureEntry ntex = new Primitive.TextureEntry(new UUID("00000000-0000-0000-5005-000000000005")); | 4239 | Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2; |
4527 | objdata.TextureEntry = ntex.GetBytes(); | 4240 | Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2; |
4528 | 4241 | Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2; | |
4529 | objdata.State = 0; | 4242 | |
4530 | objdata.Data = new byte[0]; | 4243 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); |
4531 | 4244 | block.Data = data; | |
4532 | objdata.ObjectData = new byte[76]; | 4245 | |
4533 | objdata.ObjectData[15] = 128; | 4246 | if (textureEntry != null && textureEntry.Length > 0) |
4534 | objdata.ObjectData[16] = 63; | 4247 | { |
4535 | objdata.ObjectData[56] = 128; | 4248 | byte[] teBytesFinal = new byte[textureEntry.Length + 4]; |
4536 | objdata.ObjectData[61] = 102; | 4249 | |
4537 | objdata.ObjectData[62] = 40; | 4250 | // Texture Length |
4538 | objdata.ObjectData[63] = 61; | 4251 | Utils.IntToBytes(textureEntry.Length, textureEntry, 0); |
4539 | objdata.ObjectData[64] = 189; | 4252 | // Texture |
4253 | Buffer.BlockCopy(textureEntry, 0, teBytesFinal, 4, textureEntry.Length); | ||
4254 | |||
4255 | block.TextureEntry = teBytesFinal; | ||
4256 | } | ||
4257 | else | ||
4258 | { | ||
4259 | block.TextureEntry = Utils.EmptyBytes; | ||
4260 | } | ||
4261 | |||
4262 | return block; | ||
4263 | } | ||
4264 | |||
4265 | protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(SendAvatarData data) | ||
4266 | { | ||
4267 | byte[] objectData = new byte[76]; | ||
4268 | |||
4269 | Vector4.UnitW.ToBytes(objectData, 0); // TODO: Collision plane support | ||
4270 | data.Position.ToBytes(objectData, 16); | ||
4271 | //data.Velocity.ToBytes(objectData, 28); | ||
4272 | //data.Acceleration.ToBytes(objectData, 40); | ||
4273 | data.Rotation.ToBytes(objectData, 52); | ||
4274 | //data.AngularVelocity.ToBytes(objectData, 64); | ||
4275 | |||
4276 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); | ||
4277 | |||
4278 | update.Data = Utils.EmptyBytes; | ||
4279 | update.ExtraParams = new byte[1]; | ||
4280 | update.FullID = data.AvatarID; | ||
4281 | update.ID = data.AvatarLocalID; | ||
4282 | update.Material = (byte)Material.Flesh; | ||
4283 | update.MediaURL = Utils.EmptyBytes; | ||
4284 | update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.FirstName + "\nLastName STRING RW SV " + | ||
4285 | data.LastName + "\nTitle STRING RW SV " + data.GroupTitle); | ||
4286 | update.ObjectData = objectData; | ||
4287 | update.ParentID = data.ParentID; | ||
4288 | update.PathCurve = 16; | ||
4289 | update.PathScaleX = 100; | ||
4290 | update.PathScaleY = 100; | ||
4291 | update.PCode = (byte)PCode.Avatar; | ||
4292 | update.ProfileCurve = 1; | ||
4293 | update.PSBlock = Utils.EmptyBytes; | ||
4294 | update.Scale = Vector3.One; | ||
4295 | update.Text = Utils.EmptyBytes; | ||
4296 | update.TextColor = new byte[4]; | ||
4297 | update.TextureAnim = Utils.EmptyBytes; | ||
4298 | update.TextureEntry = data.TextureEntry ?? Utils.EmptyBytes; | ||
4299 | update.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24); // TODO: Replace these numbers with PrimFlags | ||
4300 | |||
4301 | return update; | ||
4302 | } | ||
4303 | |||
4304 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SendPrimitiveData data) | ||
4305 | { | ||
4306 | byte[] objectData = new byte[60]; | ||
4307 | data.pos.ToBytes(objectData, 0); | ||
4308 | data.vel.ToBytes(objectData, 12); | ||
4309 | data.acc.ToBytes(objectData, 24); | ||
4310 | data.rotation.ToBytes(objectData, 36); | ||
4311 | data.rvel.ToBytes(objectData, 48); | ||
4312 | |||
4313 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); | ||
4314 | update.ClickAction = (byte)data.clickAction; | ||
4315 | update.CRC = 0; | ||
4316 | update.ExtraParams = data.primShape.ExtraParams ?? Utils.EmptyBytes; | ||
4317 | update.FullID = data.objectID; | ||
4318 | update.ID = data.localID; | ||
4319 | //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated | ||
4320 | //update.JointPivot = Vector3.Zero; | ||
4321 | //update.JointType = 0; | ||
4322 | update.Material = data.material; | ||
4323 | update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim | ||
4324 | if (data.attachment) | ||
4325 | { | ||
4326 | update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.AssetId); | ||
4327 | update.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16)); | ||
4328 | } | ||
4329 | else | ||
4330 | { | ||
4331 | update.NameValue = Utils.EmptyBytes; | ||
4332 | update.State = data.primShape.State; | ||
4333 | } | ||
4334 | update.ObjectData = objectData; | ||
4335 | update.ParentID = data.parentID; | ||
4336 | update.PathBegin = data.primShape.PathBegin; | ||
4337 | update.PathCurve = data.primShape.PathCurve; | ||
4338 | update.PathEnd = data.primShape.PathEnd; | ||
4339 | update.PathRadiusOffset = data.primShape.PathRadiusOffset; | ||
4340 | update.PathRevolutions = data.primShape.PathRevolutions; | ||
4341 | update.PathScaleX = data.primShape.PathScaleX; | ||
4342 | update.PathScaleY = data.primShape.PathScaleY; | ||
4343 | update.PathShearX = data.primShape.PathShearX; | ||
4344 | update.PathShearY = data.primShape.PathShearY; | ||
4345 | update.PathSkew = data.primShape.PathSkew; | ||
4346 | update.PathTaperX = data.primShape.PathTaperX; | ||
4347 | update.PathTaperY = data.primShape.PathTaperY; | ||
4348 | update.PathTwist = data.primShape.PathTwist; | ||
4349 | update.PathTwistBegin = data.primShape.PathTwistBegin; | ||
4350 | update.PCode = data.primShape.PCode; | ||
4351 | update.ProfileBegin = data.primShape.ProfileBegin; | ||
4352 | update.ProfileCurve = data.primShape.ProfileCurve; | ||
4353 | update.ProfileEnd = data.primShape.ProfileEnd; | ||
4354 | update.ProfileHollow = data.primShape.ProfileHollow; | ||
4355 | update.PSBlock = data.particleSystem ?? Utils.EmptyBytes; | ||
4356 | update.TextColor = data.color ?? Color4.Black.GetBytes(true); | ||
4357 | update.TextureAnim = data.textureanim ?? Utils.EmptyBytes; | ||
4358 | update.TextureEntry = data.primShape.TextureEntry ?? Utils.EmptyBytes; | ||
4359 | update.Scale = data.primShape.Scale; | ||
4360 | update.Text = Util.StringToBytes256(data.text); | ||
4361 | update.UpdateFlags = (uint)data.flags; | ||
4362 | |||
4363 | if (data.SoundId != UUID.Zero) | ||
4364 | { | ||
4365 | update.Sound = data.SoundId; | ||
4366 | update.OwnerID = data.ownerID; | ||
4367 | update.Gain = (float)data.SoundVolume; | ||
4368 | update.Radius = (float)data.SoundRadius; | ||
4369 | update.Flags = data.SoundFlags; | ||
4370 | } | ||
4371 | |||
4372 | switch ((PCode)data.primShape.PCode) | ||
4373 | { | ||
4374 | case PCode.Grass: | ||
4375 | case PCode.Tree: | ||
4376 | case PCode.NewTree: | ||
4377 | update.Data = new byte[] { data.primShape.State }; | ||
4378 | break; | ||
4379 | default: | ||
4380 | // TODO: Support ScratchPad | ||
4381 | //if (prim.ScratchPad != null) | ||
4382 | //{ | ||
4383 | // update.Data = new byte[prim.ScratchPad.Length]; | ||
4384 | // Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length); | ||
4385 | //} | ||
4386 | //else | ||
4387 | //{ | ||
4388 | // update.Data = Utils.EmptyBytes; | ||
4389 | //} | ||
4390 | update.Data = Utils.EmptyBytes; | ||
4391 | break; | ||
4392 | } | ||
4393 | |||
4394 | return update; | ||
4540 | } | 4395 | } |
4541 | 4396 | ||
4542 | public void SendNameReply(UUID profileId, string firstname, string lastname) | 4397 | public void SendNameReply(UUID profileId, string firstname, string lastname) |
@@ -4546,8 +4401,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4546 | packet.UUIDNameBlock = new UUIDNameReplyPacket.UUIDNameBlockBlock[1]; | 4401 | packet.UUIDNameBlock = new UUIDNameReplyPacket.UUIDNameBlockBlock[1]; |
4547 | packet.UUIDNameBlock[0] = new UUIDNameReplyPacket.UUIDNameBlockBlock(); | 4402 | packet.UUIDNameBlock[0] = new UUIDNameReplyPacket.UUIDNameBlockBlock(); |
4548 | packet.UUIDNameBlock[0].ID = profileId; | 4403 | packet.UUIDNameBlock[0].ID = profileId; |
4549 | packet.UUIDNameBlock[0].FirstName = Utils.StringToBytes(firstname); | 4404 | packet.UUIDNameBlock[0].FirstName = Util.StringToBytes256(firstname); |
4550 | packet.UUIDNameBlock[0].LastName = Utils.StringToBytes(lastname); | 4405 | packet.UUIDNameBlock[0].LastName = Util.StringToBytes256(lastname); |
4551 | 4406 | ||
4552 | OutPacket(packet, ThrottleOutPacketType.Task); | 4407 | OutPacket(packet, ThrottleOutPacketType.Task); |
4553 | } | 4408 | } |
@@ -4593,7 +4448,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4593 | 4448 | ||
4594 | private bool HandleMoneyTransferRequest(IClientAPI sender, Packet Pack) | 4449 | private bool HandleMoneyTransferRequest(IClientAPI sender, Packet Pack) |
4595 | { | 4450 | { |
4596 | MoneyTransferRequestPacket money = (MoneyTransferRequestPacket) Pack; | 4451 | MoneyTransferRequestPacket money = (MoneyTransferRequestPacket)Pack; |
4597 | // validate the agent owns the agentID and sessionID | 4452 | // validate the agent owns the agentID and sessionID |
4598 | if (money.MoneyData.SourceID == sender.AgentId && money.AgentData.AgentID == sender.AgentId && | 4453 | if (money.MoneyData.SourceID == sender.AgentId && money.AgentData.AgentID == sender.AgentId && |
4599 | money.AgentData.SessionID == sender.SessionId) | 4454 | money.AgentData.SessionID == sender.SessionId) |
@@ -4614,7 +4469,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4614 | 4469 | ||
4615 | private bool HandleParcelBuyRequest(IClientAPI sender, Packet Pack) | 4470 | private bool HandleParcelBuyRequest(IClientAPI sender, Packet Pack) |
4616 | { | 4471 | { |
4617 | ParcelBuyPacket parcel = (ParcelBuyPacket) Pack; | 4472 | ParcelBuyPacket parcel = (ParcelBuyPacket)Pack; |
4618 | if (parcel.AgentData.AgentID == AgentId && parcel.AgentData.SessionID == SessionId) | 4473 | if (parcel.AgentData.AgentID == AgentId && parcel.AgentData.SessionID == SessionId) |
4619 | { | 4474 | { |
4620 | ParcelBuy handlerParcelBuy = OnParcelBuy; | 4475 | ParcelBuy handlerParcelBuy = OnParcelBuy; |
@@ -4634,7 +4489,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4634 | private bool HandleUUIDGroupNameRequest(IClientAPI sender, Packet Pack) | 4489 | private bool HandleUUIDGroupNameRequest(IClientAPI sender, Packet Pack) |
4635 | { | 4490 | { |
4636 | UUIDGroupNameRequestPacket upack = (UUIDGroupNameRequestPacket)Pack; | 4491 | UUIDGroupNameRequestPacket upack = (UUIDGroupNameRequestPacket)Pack; |
4637 | 4492 | ||
4638 | 4493 | ||
4639 | for (int i = 0; i < upack.UUIDNameBlock.Length; i++) | 4494 | for (int i = 0; i < upack.UUIDNameBlock.Length; i++) |
4640 | { | 4495 | { |
@@ -4650,7 +4505,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4650 | 4505 | ||
4651 | public bool HandleGenericMessage(IClientAPI sender, Packet pack) | 4506 | public bool HandleGenericMessage(IClientAPI sender, Packet pack) |
4652 | { | 4507 | { |
4653 | GenericMessagePacket gmpack = (GenericMessagePacket) pack; | 4508 | GenericMessagePacket gmpack = (GenericMessagePacket)pack; |
4654 | if (m_genericPacketHandlers.Count == 0) return false; | 4509 | if (m_genericPacketHandlers.Count == 0) return false; |
4655 | if (gmpack.AgentData.SessionID != SessionId) return false; | 4510 | if (gmpack.AgentData.SessionID != SessionId) return false; |
4656 | 4511 | ||
@@ -4743,8 +4598,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4743 | scriptQuestion.Data.TaskID = taskID; | 4598 | scriptQuestion.Data.TaskID = taskID; |
4744 | scriptQuestion.Data.ItemID = itemID; | 4599 | scriptQuestion.Data.ItemID = itemID; |
4745 | scriptQuestion.Data.Questions = question; | 4600 | scriptQuestion.Data.Questions = question; |
4746 | scriptQuestion.Data.ObjectName = Utils.StringToBytes(taskName); | 4601 | scriptQuestion.Data.ObjectName = Util.StringToBytes256(taskName); |
4747 | scriptQuestion.Data.ObjectOwner = Utils.StringToBytes(ownerName); | 4602 | scriptQuestion.Data.ObjectOwner = Util.StringToBytes256(ownerName); |
4748 | 4603 | ||
4749 | OutPacket(scriptQuestion, ThrottleOutPacketType.Task); | 4604 | OutPacket(scriptQuestion, ThrottleOutPacketType.Task); |
4750 | } | 4605 | } |
@@ -4787,7 +4642,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4787 | { | 4642 | { |
4788 | if (((LogoutRequestPacket)packet).AgentData.SessionID != SessionId) return false; | 4643 | if (((LogoutRequestPacket)packet).AgentData.SessionID != SessionId) return false; |
4789 | } | 4644 | } |
4790 | 4645 | ||
4791 | return Logout(client); | 4646 | return Logout(client); |
4792 | } | 4647 | } |
4793 | 4648 | ||
@@ -4845,7 +4700,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4845 | 4700 | ||
4846 | cachedresp.Header.Zerocoded = true; | 4701 | cachedresp.Header.Zerocoded = true; |
4847 | OutPacket(cachedresp, ThrottleOutPacketType.Task); | 4702 | OutPacket(cachedresp, ThrottleOutPacketType.Task); |
4848 | 4703 | ||
4849 | return true; | 4704 | return true; |
4850 | } | 4705 | } |
4851 | 4706 | ||
@@ -4895,7 +4750,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4895 | UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; | 4750 | UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; |
4896 | if (handlerUpdatePrimSingleRotation != null) | 4751 | if (handlerUpdatePrimSingleRotation != null) |
4897 | { | 4752 | { |
4898 | // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W); | 4753 | // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W); |
4899 | handlerUpdatePrimSingleRotation(localId, rot1, this); | 4754 | handlerUpdatePrimSingleRotation(localId, rot1, this); |
4900 | } | 4755 | } |
4901 | break; | 4756 | break; |
@@ -4906,8 +4761,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4906 | UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; | 4761 | UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; |
4907 | if (handlerUpdatePrimSingleRotationPosition != null) | 4762 | if (handlerUpdatePrimSingleRotationPosition != null) |
4908 | { | 4763 | { |
4909 | // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z); | 4764 | // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z); |
4910 | // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W); | 4765 | // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W); |
4911 | handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this); | 4766 | handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this); |
4912 | } | 4767 | } |
4913 | break; | 4768 | break; |
@@ -4918,7 +4773,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4918 | UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; | 4773 | UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; |
4919 | if (handlerUpdatePrimScale != null) | 4774 | if (handlerUpdatePrimScale != null) |
4920 | { | 4775 | { |
4921 | // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z); | 4776 | // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z); |
4922 | handlerUpdatePrimScale(localId, scale4, this); | 4777 | handlerUpdatePrimScale(localId, scale4, this); |
4923 | } | 4778 | } |
4924 | break; | 4779 | break; |
@@ -4957,7 +4812,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4957 | UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; | 4812 | UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; |
4958 | if (handlerUpdatePrimRotation != null) | 4813 | if (handlerUpdatePrimRotation != null) |
4959 | { | 4814 | { |
4960 | // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W); | 4815 | // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W); |
4961 | handlerUpdatePrimRotation(localId, rot3, this); | 4816 | handlerUpdatePrimRotation(localId, rot3, this); |
4962 | } | 4817 | } |
4963 | break; | 4818 | break; |
@@ -4968,8 +4823,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4968 | handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; | 4823 | handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; |
4969 | if (handlerUpdatePrimGroupRotation != null) | 4824 | if (handlerUpdatePrimGroupRotation != null) |
4970 | { | 4825 | { |
4971 | // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z); | 4826 | // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z); |
4972 | // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W); | 4827 | // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W); |
4973 | handlerUpdatePrimGroupRotation(localId, pos3, rot4, this); | 4828 | handlerUpdatePrimGroupRotation(localId, pos3, rot4, this); |
4974 | } | 4829 | } |
4975 | break; | 4830 | break; |
@@ -4980,7 +4835,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4980 | UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; | 4835 | UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; |
4981 | if (handlerUpdatePrimGroupScale != null) | 4836 | if (handlerUpdatePrimGroupScale != null) |
4982 | { | 4837 | { |
4983 | // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z); | 4838 | // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z); |
4984 | handlerUpdatePrimGroupScale(localId, scale7, this); | 4839 | handlerUpdatePrimGroupScale(localId, scale7, this); |
4985 | } | 4840 | } |
4986 | break; | 4841 | break; |
@@ -5138,7 +4993,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5138 | if (m_moneyBalance + debit >= 0) | 4993 | if (m_moneyBalance + debit >= 0) |
5139 | { | 4994 | { |
5140 | m_moneyBalance += debit; | 4995 | m_moneyBalance += debit; |
5141 | SendMoneyBalance(UUID.Zero, true, Utils.StringToBytes("Poof Poof!"), m_moneyBalance); | 4996 | SendMoneyBalance(UUID.Zero, true, Util.StringToBytes256("Poof Poof!"), m_moneyBalance); |
5142 | return true; | 4997 | return true; |
5143 | } | 4998 | } |
5144 | return false; | 4999 | return false; |
@@ -5212,7 +5067,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5212 | // Main packet processing conditional | 5067 | // Main packet processing conditional |
5213 | switch (Pack.Type) | 5068 | switch (Pack.Type) |
5214 | { | 5069 | { |
5215 | #region Scene/Avatar | 5070 | #region Scene/Avatar |
5216 | 5071 | ||
5217 | case PacketType.AvatarPropertiesRequest: | 5072 | case PacketType.AvatarPropertiesRequest: |
5218 | AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; | 5073 | AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; |
@@ -5463,7 +5318,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5463 | break; | 5318 | break; |
5464 | 5319 | ||
5465 | case PacketType.DeRezObject: | 5320 | case PacketType.DeRezObject: |
5466 | DeRezObjectPacket DeRezPacket = (DeRezObjectPacket) Pack; | 5321 | DeRezObjectPacket DeRezPacket = (DeRezObjectPacket)Pack; |
5467 | 5322 | ||
5468 | #region Packet Session and User Check | 5323 | #region Packet Session and User Check |
5469 | if (m_checkPackets) | 5324 | if (m_checkPackets) |
@@ -5484,13 +5339,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5484 | { | 5339 | { |
5485 | deRezIDs.Add(data.ObjectLocalID); | 5340 | deRezIDs.Add(data.ObjectLocalID); |
5486 | } | 5341 | } |
5487 | // It just so happens that the values on the DeRezAction enumerator match the Destination | 5342 | // It just so happens that the values on the DeRezAction enumerator match the Destination |
5488 | // values given by a Second Life client | 5343 | // values given by a Second Life client |
5489 | handlerDeRezObject(this, deRezIDs, | 5344 | handlerDeRezObject(this, deRezIDs, |
5490 | DeRezPacket.AgentBlock.GroupID, | 5345 | DeRezPacket.AgentBlock.GroupID, |
5491 | (DeRezAction)DeRezPacket.AgentBlock.Destination, | 5346 | (DeRezAction)DeRezPacket.AgentBlock.Destination, |
5492 | DeRezPacket.AgentBlock.DestinationID); | 5347 | DeRezPacket.AgentBlock.DestinationID); |
5493 | 5348 | ||
5494 | } | 5349 | } |
5495 | break; | 5350 | break; |
5496 | 5351 | ||
@@ -5594,7 +5449,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5594 | } | 5449 | } |
5595 | 5450 | ||
5596 | break; | 5451 | break; |
5597 | 5452 | ||
5598 | case PacketType.AgentIsNowWearing: | 5453 | case PacketType.AgentIsNowWearing: |
5599 | if (OnAvatarNowWearing != null) | 5454 | if (OnAvatarNowWearing != null) |
5600 | { | 5455 | { |
@@ -5798,7 +5653,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5798 | 5653 | ||
5799 | if (lastarg != null) | 5654 | if (lastarg != null) |
5800 | { | 5655 | { |
5801 | update = | 5656 | update = |
5802 | ( | 5657 | ( |
5803 | (x.BodyRotation != lastarg.BodyRotation) || | 5658 | (x.BodyRotation != lastarg.BodyRotation) || |
5804 | (x.CameraAtAxis != lastarg.CameraAtAxis) || | 5659 | (x.CameraAtAxis != lastarg.CameraAtAxis) || |
@@ -5991,7 +5846,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5991 | } | 5846 | } |
5992 | 5847 | ||
5993 | break; | 5848 | break; |
5994 | 5849 | ||
5995 | case PacketType.UserInfoRequest: | 5850 | case PacketType.UserInfoRequest: |
5996 | UserInfoRequest handlerUserInfoRequest = OnUserInfoRequest; | 5851 | UserInfoRequest handlerUserInfoRequest = OnUserInfoRequest; |
5997 | if (handlerUserInfoRequest != null) | 5852 | if (handlerUserInfoRequest != null) |
@@ -6003,7 +5858,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6003 | SendUserInfoReply(false, true, ""); | 5858 | SendUserInfoReply(false, true, ""); |
6004 | } | 5859 | } |
6005 | break; | 5860 | break; |
6006 | 5861 | ||
6007 | case PacketType.UpdateUserInfo: | 5862 | case PacketType.UpdateUserInfo: |
6008 | UpdateUserInfoPacket updateUserInfo = (UpdateUserInfoPacket)Pack; | 5863 | UpdateUserInfoPacket updateUserInfo = (UpdateUserInfoPacket)Pack; |
6009 | 5864 | ||
@@ -6030,7 +5885,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6030 | visible, this); | 5885 | visible, this); |
6031 | } | 5886 | } |
6032 | break; | 5887 | break; |
6033 | 5888 | ||
6034 | case PacketType.SetStartLocationRequest: | 5889 | case PacketType.SetStartLocationRequest: |
6035 | SetStartLocationRequestPacket avSetStartLocationRequestPacket = (SetStartLocationRequestPacket)Pack; | 5890 | SetStartLocationRequestPacket avSetStartLocationRequestPacket = (SetStartLocationRequestPacket)Pack; |
6036 | 5891 | ||
@@ -6088,9 +5943,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6088 | } | 5943 | } |
6089 | break; | 5944 | break; |
6090 | 5945 | ||
6091 | #endregion | 5946 | #endregion |
6092 | 5947 | ||
6093 | #region Objects/m_sceneObjects | 5948 | #region Objects/m_sceneObjects |
6094 | 5949 | ||
6095 | case PacketType.ObjectLink: | 5950 | case PacketType.ObjectLink: |
6096 | ObjectLinkPacket link = (ObjectLinkPacket)Pack; | 5951 | ObjectLinkPacket link = (ObjectLinkPacket)Pack; |
@@ -6121,7 +5976,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6121 | handlerLinkObjects(this, parentprimid, childrenprims); | 5976 | handlerLinkObjects(this, parentprimid, childrenprims); |
6122 | } | 5977 | } |
6123 | break; | 5978 | break; |
6124 | 5979 | ||
6125 | case PacketType.ObjectDelink: | 5980 | case PacketType.ObjectDelink: |
6126 | ObjectDelinkPacket delink = (ObjectDelinkPacket)Pack; | 5981 | ObjectDelinkPacket delink = (ObjectDelinkPacket)Pack; |
6127 | 5982 | ||
@@ -6150,7 +6005,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6150 | } | 6005 | } |
6151 | 6006 | ||
6152 | break; | 6007 | break; |
6153 | 6008 | ||
6154 | case PacketType.ObjectAdd: | 6009 | case PacketType.ObjectAdd: |
6155 | if (OnAddPrim != null) | 6010 | if (OnAddPrim != null) |
6156 | { | 6011 | { |
@@ -6180,7 +6035,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6180 | handlerAddPrim(AgentId, ActiveGroupId, addPacket.ObjectData.RayEnd, addPacket.ObjectData.Rotation, shape, addPacket.ObjectData.BypassRaycast, addPacket.ObjectData.RayStart, addPacket.ObjectData.RayTargetID, addPacket.ObjectData.RayEndIsIntersection); | 6035 | handlerAddPrim(AgentId, ActiveGroupId, addPacket.ObjectData.RayEnd, addPacket.ObjectData.Rotation, shape, addPacket.ObjectData.BypassRaycast, addPacket.ObjectData.RayStart, addPacket.ObjectData.RayTargetID, addPacket.ObjectData.RayEndIsIntersection); |
6181 | } | 6036 | } |
6182 | break; | 6037 | break; |
6183 | 6038 | ||
6184 | case PacketType.ObjectShape: | 6039 | case PacketType.ObjectShape: |
6185 | ObjectShapePacket shapePacket = (ObjectShapePacket)Pack; | 6040 | ObjectShapePacket shapePacket = (ObjectShapePacket)Pack; |
6186 | 6041 | ||
@@ -6225,7 +6080,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6225 | } | 6080 | } |
6226 | } | 6081 | } |
6227 | break; | 6082 | break; |
6228 | 6083 | ||
6229 | case PacketType.ObjectExtraParams: | 6084 | case PacketType.ObjectExtraParams: |
6230 | ObjectExtraParamsPacket extraPar = (ObjectExtraParamsPacket)Pack; | 6085 | ObjectExtraParamsPacket extraPar = (ObjectExtraParamsPacket)Pack; |
6231 | 6086 | ||
@@ -6241,7 +6096,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6241 | ObjectExtraParams handlerUpdateExtraParams = OnUpdateExtraParams; | 6096 | ObjectExtraParams handlerUpdateExtraParams = OnUpdateExtraParams; |
6242 | if (handlerUpdateExtraParams != null) | 6097 | if (handlerUpdateExtraParams != null) |
6243 | { | 6098 | { |
6244 | for (int i = 0 ; i < extraPar.ObjectData.Length ; i++) | 6099 | for (int i = 0; i < extraPar.ObjectData.Length; i++) |
6245 | { | 6100 | { |
6246 | handlerUpdateExtraParams(m_agentId, extraPar.ObjectData[i].ObjectLocalID, | 6101 | handlerUpdateExtraParams(m_agentId, extraPar.ObjectData[i].ObjectLocalID, |
6247 | extraPar.ObjectData[i].ParamType, | 6102 | extraPar.ObjectData[i].ParamType, |
@@ -6642,7 +6497,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6642 | break; | 6497 | break; |
6643 | case PacketType.ObjectName: | 6498 | case PacketType.ObjectName: |
6644 | ObjectNamePacket objName = (ObjectNamePacket)Pack; | 6499 | ObjectNamePacket objName = (ObjectNamePacket)Pack; |
6645 | 6500 | ||
6646 | #region Packet Session and User Check | 6501 | #region Packet Session and User Check |
6647 | if (m_checkPackets) | 6502 | if (m_checkPackets) |
6648 | { | 6503 | { |
@@ -6651,7 +6506,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6651 | break; | 6506 | break; |
6652 | } | 6507 | } |
6653 | #endregion | 6508 | #endregion |
6654 | 6509 | ||
6655 | GenericCall7 handlerObjectName = null; | 6510 | GenericCall7 handlerObjectName = null; |
6656 | for (int i = 0; i < objName.ObjectData.Length; i++) | 6511 | for (int i = 0; i < objName.ObjectData.Length; i++) |
6657 | { | 6512 | { |
@@ -6884,14 +6739,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6884 | } | 6739 | } |
6885 | break; | 6740 | break; |
6886 | 6741 | ||
6887 | #endregion | 6742 | #endregion |
6888 | 6743 | ||
6889 | #region Inventory/Asset/Other related packets | 6744 | #region Inventory/Asset/Other related packets |
6890 | 6745 | ||
6891 | case PacketType.RequestImage: | 6746 | case PacketType.RequestImage: |
6892 | RequestImagePacket imageRequest = (RequestImagePacket)Pack; | 6747 | RequestImagePacket imageRequest = (RequestImagePacket)Pack; |
6893 | //m_log.Debug("image request: " + Pack.ToString()); | 6748 | //m_log.Debug("image request: " + Pack.ToString()); |
6894 | 6749 | ||
6895 | #region Packet Session and User Check | 6750 | #region Packet Session and User Check |
6896 | if (m_checkPackets) | 6751 | if (m_checkPackets) |
6897 | { | 6752 | { |
@@ -6915,7 +6770,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6915 | //handlerTextureRequest = OnRequestTexture; | 6770 | //handlerTextureRequest = OnRequestTexture; |
6916 | 6771 | ||
6917 | //if (handlerTextureRequest != null) | 6772 | //if (handlerTextureRequest != null) |
6918 | //OnRequestTexture(this, args); | 6773 | //OnRequestTexture(this, args); |
6919 | 6774 | ||
6920 | // in the end, we null this, so we have to check if it's null | 6775 | // in the end, we null this, so we have to check if it's null |
6921 | if (m_imageManager != null) | 6776 | if (m_imageManager != null) |
@@ -6961,7 +6816,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6961 | if (ti.OwnerID != AgentId) | 6816 | if (ti.OwnerID != AgentId) |
6962 | break; | 6817 | break; |
6963 | 6818 | ||
6964 | if ((ti.CurrentPermissions & ((uint)PermissionMask.Modify| (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) != ((uint)PermissionMask.Modify| (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) | 6819 | if ((ti.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) != ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) |
6965 | break; | 6820 | break; |
6966 | 6821 | ||
6967 | if (ti.AssetID != requestID) | 6822 | if (ti.AssetID != requestID) |
@@ -7019,7 +6874,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7019 | case PacketType.AssetUploadRequest: | 6874 | case PacketType.AssetUploadRequest: |
7020 | AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack; | 6875 | AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack; |
7021 | 6876 | ||
7022 | 6877 | ||
7023 | // m_log.Debug("upload request " + request.ToString()); | 6878 | // m_log.Debug("upload request " + request.ToString()); |
7024 | // m_log.Debug("upload request was for assetid: " + request.AssetBlock.TransactionID.Combine(this.SecureSessionId).ToString()); | 6879 | // m_log.Debug("upload request was for assetid: " + request.AssetBlock.TransactionID.Combine(this.SecureSessionId).ToString()); |
7025 | UUID temp = UUID.Combine(request.AssetBlock.TransactionID, SecureSessionId); | 6880 | UUID temp = UUID.Combine(request.AssetBlock.TransactionID, SecureSessionId); |
@@ -7036,7 +6891,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7036 | break; | 6891 | break; |
7037 | case PacketType.RequestXfer: | 6892 | case PacketType.RequestXfer: |
7038 | RequestXferPacket xferReq = (RequestXferPacket)Pack; | 6893 | RequestXferPacket xferReq = (RequestXferPacket)Pack; |
7039 | 6894 | ||
7040 | RequestXfer handlerRequestXfer = OnRequestXfer; | 6895 | RequestXfer handlerRequestXfer = OnRequestXfer; |
7041 | 6896 | ||
7042 | if (handlerRequestXfer != null) | 6897 | if (handlerRequestXfer != null) |
@@ -7055,7 +6910,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7055 | break; | 6910 | break; |
7056 | case PacketType.ConfirmXferPacket: | 6911 | case PacketType.ConfirmXferPacket: |
7057 | ConfirmXferPacketPacket confirmXfer = (ConfirmXferPacketPacket)Pack; | 6912 | ConfirmXferPacketPacket confirmXfer = (ConfirmXferPacketPacket)Pack; |
7058 | 6913 | ||
7059 | ConfirmXfer handlerConfirmXfer = OnConfirmXfer; | 6914 | ConfirmXfer handlerConfirmXfer = OnConfirmXfer; |
7060 | if (handlerConfirmXfer != null) | 6915 | if (handlerConfirmXfer != null) |
7061 | { | 6916 | { |
@@ -7150,7 +7005,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7150 | break; | 7005 | break; |
7151 | case PacketType.CreateInventoryItem: | 7006 | case PacketType.CreateInventoryItem: |
7152 | CreateInventoryItemPacket createItem = (CreateInventoryItemPacket)Pack; | 7007 | CreateInventoryItemPacket createItem = (CreateInventoryItemPacket)Pack; |
7153 | 7008 | ||
7154 | #region Packet Session and User Check | 7009 | #region Packet Session and User Check |
7155 | if (m_checkPackets) | 7010 | if (m_checkPackets) |
7156 | { | 7011 | { |
@@ -7243,7 +7098,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7243 | break; | 7098 | break; |
7244 | case PacketType.UpdateInventoryItem: | 7099 | case PacketType.UpdateInventoryItem: |
7245 | UpdateInventoryItemPacket inventoryItemUpdate = (UpdateInventoryItemPacket)Pack; | 7100 | UpdateInventoryItemPacket inventoryItemUpdate = (UpdateInventoryItemPacket)Pack; |
7246 | 7101 | ||
7247 | #region Packet Session and User Check | 7102 | #region Packet Session and User Check |
7248 | if (m_checkPackets) | 7103 | if (m_checkPackets) |
7249 | { | 7104 | { |
@@ -7735,7 +7590,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7735 | } | 7590 | } |
7736 | break; | 7591 | break; |
7737 | 7592 | ||
7738 | #endregion | 7593 | #endregion |
7739 | 7594 | ||
7740 | case PacketType.UUIDNameRequest: | 7595 | case PacketType.UUIDNameRequest: |
7741 | UUIDNameRequestPacket incoming = (UUIDNameRequestPacket)Pack; | 7596 | UUIDNameRequestPacket incoming = (UUIDNameRequestPacket)Pack; |
@@ -7750,7 +7605,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7750 | } | 7605 | } |
7751 | break; | 7606 | break; |
7752 | 7607 | ||
7753 | #region Parcel related packets | 7608 | #region Parcel related packets |
7754 | 7609 | ||
7755 | case PacketType.RegionHandleRequest: | 7610 | case PacketType.RegionHandleRequest: |
7756 | RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; | 7611 | RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; |
@@ -8131,9 +7986,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
8131 | } | 7986 | } |
8132 | break; | 7987 | break; |
8133 | 7988 | ||
8134 | #endregion | 7989 | #endregion |
8135 | 7990 | ||
8136 | #region Estate Packets | 7991 | #region Estate Packets |
8137 | 7992 | ||
8138 | case PacketType.EstateOwnerMessage: | 7993 | case PacketType.EstateOwnerMessage: |
8139 | EstateOwnerMessagePacket messagePacket = (EstateOwnerMessagePacket)Pack; | 7994 | EstateOwnerMessagePacket messagePacket = (EstateOwnerMessagePacket)Pack; |
@@ -8167,21 +8022,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
8167 | convertParamStringToBool(messagePacket.ParamList[7].Parameter), convertParamStringToBool(messagePacket.ParamList[8].Parameter)); | 8022 | convertParamStringToBool(messagePacket.ParamList[7].Parameter), convertParamStringToBool(messagePacket.ParamList[8].Parameter)); |
8168 | } | 8023 | } |
8169 | break; | 8024 | break; |
8170 | // case "texturebase": | 8025 | // case "texturebase": |
8171 | // if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false)) | 8026 | // if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false)) |
8172 | // { | 8027 | // { |
8173 | // foreach (EstateOwnerMessagePacket.ParamListBlock block in messagePacket.ParamList) | 8028 | // foreach (EstateOwnerMessagePacket.ParamListBlock block in messagePacket.ParamList) |
8174 | // { | 8029 | // { |
8175 | // string s = Utils.BytesToString(block.Parameter); | 8030 | // string s = Utils.BytesToString(block.Parameter); |
8176 | // string[] splitField = s.Split(' '); | 8031 | // string[] splitField = s.Split(' '); |
8177 | // if (splitField.Length == 2) | 8032 | // if (splitField.Length == 2) |
8178 | // { | 8033 | // { |
8179 | // UUID tempUUID = new UUID(splitField[1]); | 8034 | // UUID tempUUID = new UUID(splitField[1]); |
8180 | // OnSetEstateTerrainBaseTexture(this, Convert.ToInt16(splitField[0]), tempUUID); | 8035 | // OnSetEstateTerrainBaseTexture(this, Convert.ToInt16(splitField[0]), tempUUID); |
8181 | // } | 8036 | // } |
8182 | // } | 8037 | // } |
8183 | // } | 8038 | // } |
8184 | // break; | 8039 | // break; |
8185 | case "texturedetail": | 8040 | case "texturedetail": |
8186 | if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false)) | 8041 | if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false)) |
8187 | { | 8042 | { |
@@ -8423,7 +8278,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
8423 | m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket); | 8278 | m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket); |
8424 | break; | 8279 | break; |
8425 | } | 8280 | } |
8426 | 8281 | ||
8427 | //int parcelID, uint reportType, uint requestflags, string filter | 8282 | //int parcelID, uint reportType, uint requestflags, string filter |
8428 | 8283 | ||
8429 | //lsrp.RequestData.ParcelLocalID; | 8284 | //lsrp.RequestData.ParcelLocalID; |
@@ -8463,9 +8318,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
8463 | } | 8318 | } |
8464 | break; | 8319 | break; |
8465 | 8320 | ||
8466 | #endregion | 8321 | #endregion |
8467 | 8322 | ||
8468 | #region GodPackets | 8323 | #region GodPackets |
8469 | 8324 | ||
8470 | case PacketType.RequestGodlikePowers: | 8325 | case PacketType.RequestGodlikePowers: |
8471 | RequestGodlikePowersPacket rglpPack = (RequestGodlikePowersPacket)Pack; | 8326 | RequestGodlikePowersPacket rglpPack = (RequestGodlikePowersPacket)Pack; |
@@ -8511,9 +8366,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
8511 | //OutPacket(kupack, ThrottleOutPacketType.Task); | 8366 | //OutPacket(kupack, ThrottleOutPacketType.Task); |
8512 | break; | 8367 | break; |
8513 | 8368 | ||
8514 | #endregion | 8369 | #endregion |
8515 | 8370 | ||
8516 | #region Economy/Transaction Packets | 8371 | #region Economy/Transaction Packets |
8517 | 8372 | ||
8518 | case PacketType.MoneyBalanceRequest: | 8373 | case PacketType.MoneyBalanceRequest: |
8519 | MoneyBalanceRequestPacket moneybalancerequestpacket = (MoneyBalanceRequestPacket)Pack; | 8374 | MoneyBalanceRequestPacket moneybalancerequestpacket = (MoneyBalanceRequestPacket)Pack; |
@@ -8537,7 +8392,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
8537 | break; | 8392 | break; |
8538 | case PacketType.EconomyDataRequest: | 8393 | case PacketType.EconomyDataRequest: |
8539 | 8394 | ||
8540 | 8395 | ||
8541 | EconomyDataRequest handlerEconomoyDataRequest = OnEconomyDataRequest; | 8396 | EconomyDataRequest handlerEconomoyDataRequest = OnEconomyDataRequest; |
8542 | if (handlerEconomoyDataRequest != null) | 8397 | if (handlerEconomoyDataRequest != null) |
8543 | { | 8398 | { |
@@ -8613,9 +8468,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
8613 | } | 8468 | } |
8614 | break; | 8469 | break; |
8615 | 8470 | ||
8616 | #endregion | 8471 | #endregion |
8617 | 8472 | ||
8618 | #region Script Packets | 8473 | #region Script Packets |
8619 | 8474 | ||
8620 | case PacketType.GetScriptRunning: | 8475 | case PacketType.GetScriptRunning: |
8621 | GetScriptRunningPacket scriptRunning = (GetScriptRunningPacket)Pack; | 8476 | GetScriptRunningPacket scriptRunning = (GetScriptRunningPacket)Pack; |
@@ -8665,9 +8520,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
8665 | } | 8520 | } |
8666 | break; | 8521 | break; |
8667 | 8522 | ||
8668 | #endregion | 8523 | #endregion |
8669 | 8524 | ||
8670 | #region Gesture Managment | 8525 | #region Gesture Managment |
8671 | 8526 | ||
8672 | case PacketType.ActivateGestures: | 8527 | case PacketType.ActivateGestures: |
8673 | ActivateGesturesPacket activateGesturePacket = (ActivateGesturesPacket)Pack; | 8528 | ActivateGesturesPacket activateGesturePacket = (ActivateGesturesPacket)Pack; |
@@ -8734,21 +8589,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
8734 | } | 8589 | } |
8735 | break; | 8590 | break; |
8736 | 8591 | ||
8737 | #endregion | 8592 | #endregion |
8738 | |||
8739 | 8593 | ||
8740 | #region unimplemented handlers | 8594 | case PacketType.AgentFOV: |
8595 | AgentFOVPacket fovPacket = (AgentFOVPacket)Pack; | ||
8741 | 8596 | ||
8742 | case PacketType.StartPingCheck: | 8597 | if (fovPacket.FOVBlock.GenCounter > m_agentFOVCounter) |
8743 | StartPingCheckPacket pingStart = (StartPingCheckPacket)Pack; | 8598 | { |
8744 | CompletePingCheckPacket pingComplete = new CompletePingCheckPacket(); | 8599 | m_agentFOVCounter = fovPacket.FOVBlock.GenCounter; |
8745 | pingComplete.PingID.PingID = pingStart.PingID.PingID; | 8600 | AgentFOV handlerAgentFOV = OnAgentFOV; |
8746 | m_udpServer.SendPacket(m_udpClient, pingComplete, ThrottleOutPacketType.Unknown, false); | 8601 | if (handlerAgentFOV != null) |
8602 | { | ||
8603 | handlerAgentFOV(this, fovPacket.FOVBlock.VerticalAngle); | ||
8604 | } | ||
8605 | } | ||
8747 | break; | 8606 | break; |
8748 | 8607 | ||
8749 | case PacketType.CompletePingCheck: | 8608 | #region unimplemented handlers |
8750 | // TODO: Do stats tracking or something with these? | ||
8751 | break; | ||
8752 | 8609 | ||
8753 | case PacketType.ViewerStats: | 8610 | case PacketType.ViewerStats: |
8754 | // TODO: handle this packet | 8611 | // TODO: handle this packet |
@@ -8771,8 +8628,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
8771 | MapItemRequest handlerMapItemRequest = OnMapItemRequest; | 8628 | MapItemRequest handlerMapItemRequest = OnMapItemRequest; |
8772 | if (handlerMapItemRequest != null) | 8629 | if (handlerMapItemRequest != null) |
8773 | { | 8630 | { |
8774 | handlerMapItemRequest(this,mirpk.AgentData.Flags, mirpk.AgentData.EstateID, | 8631 | handlerMapItemRequest(this, mirpk.AgentData.Flags, mirpk.AgentData.EstateID, |
8775 | mirpk.AgentData.Godlike,mirpk.RequestData.ItemType, | 8632 | mirpk.AgentData.Godlike, mirpk.RequestData.ItemType, |
8776 | mirpk.RequestData.RegionHandle); | 8633 | mirpk.RequestData.RegionHandle); |
8777 | 8634 | ||
8778 | } | 8635 | } |
@@ -9080,7 +8937,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9080 | new GroupTitlesReplyPacket.GroupDataBlock(); | 8937 | new GroupTitlesReplyPacket.GroupDataBlock(); |
9081 | 8938 | ||
9082 | groupTitlesReply.GroupData[i].Title = | 8939 | groupTitlesReply.GroupData[i].Title = |
9083 | Utils.StringToBytes(d.Name); | 8940 | Util.StringToBytes256(d.Name); |
9084 | groupTitlesReply.GroupData[i].RoleID = | 8941 | groupTitlesReply.GroupData[i].RoleID = |
9085 | d.UUID; | 8942 | d.UUID; |
9086 | groupTitlesReply.GroupData[i].Selected = | 8943 | groupTitlesReply.GroupData[i].Selected = |
@@ -9117,10 +8974,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9117 | groupProfileRequest.GroupData.GroupID); | 8974 | groupProfileRequest.GroupData.GroupID); |
9118 | 8975 | ||
9119 | groupProfileReply.GroupData.GroupID = d.GroupID; | 8976 | groupProfileReply.GroupData.GroupID = d.GroupID; |
9120 | groupProfileReply.GroupData.Name = Utils.StringToBytes(d.Name); | 8977 | groupProfileReply.GroupData.Name = Util.StringToBytes256(d.Name); |
9121 | groupProfileReply.GroupData.Charter = Utils.StringToBytes(d.Charter); | 8978 | groupProfileReply.GroupData.Charter = Util.StringToBytes1024(d.Charter); |
9122 | groupProfileReply.GroupData.ShowInList = d.ShowInList; | 8979 | groupProfileReply.GroupData.ShowInList = d.ShowInList; |
9123 | groupProfileReply.GroupData.MemberTitle = Utils.StringToBytes(d.MemberTitle); | 8980 | groupProfileReply.GroupData.MemberTitle = Util.StringToBytes256(d.MemberTitle); |
9124 | groupProfileReply.GroupData.PowersMask = d.PowersMask; | 8981 | groupProfileReply.GroupData.PowersMask = d.PowersMask; |
9125 | groupProfileReply.GroupData.InsigniaID = d.InsigniaID; | 8982 | groupProfileReply.GroupData.InsigniaID = d.InsigniaID; |
9126 | groupProfileReply.GroupData.FounderID = d.FounderID; | 8983 | groupProfileReply.GroupData.FounderID = d.FounderID; |
@@ -9180,7 +9037,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9180 | groupMembersRequestPacket.GroupData.RequestID; | 9037 | groupMembersRequestPacket.GroupData.RequestID; |
9181 | groupMembersReply.GroupData.MemberCount = memberCount; | 9038 | groupMembersReply.GroupData.MemberCount = memberCount; |
9182 | 9039 | ||
9183 | for (int i = 0 ; i < blockCount ; i++) | 9040 | for (int i = 0; i < blockCount; i++) |
9184 | { | 9041 | { |
9185 | GroupMembersData m = members[0]; | 9042 | GroupMembersData m = members[0]; |
9186 | members.RemoveAt(0); | 9043 | members.RemoveAt(0); |
@@ -9192,11 +9049,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9192 | groupMembersReply.MemberData[i].Contribution = | 9049 | groupMembersReply.MemberData[i].Contribution = |
9193 | m.Contribution; | 9050 | m.Contribution; |
9194 | groupMembersReply.MemberData[i].OnlineStatus = | 9051 | groupMembersReply.MemberData[i].OnlineStatus = |
9195 | Utils.StringToBytes(m.OnlineStatus); | 9052 | Util.StringToBytes256(m.OnlineStatus); |
9196 | groupMembersReply.MemberData[i].AgentPowers = | 9053 | groupMembersReply.MemberData[i].AgentPowers = |
9197 | m.AgentPowers; | 9054 | m.AgentPowers; |
9198 | groupMembersReply.MemberData[i].Title = | 9055 | groupMembersReply.MemberData[i].Title = |
9199 | Utils.StringToBytes(m.Title); | 9056 | Util.StringToBytes256(m.Title); |
9200 | groupMembersReply.MemberData[i].IsOwner = | 9057 | groupMembersReply.MemberData[i].IsOwner = |
9201 | m.IsOwner; | 9058 | m.IsOwner; |
9202 | } | 9059 | } |
@@ -9257,11 +9114,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9257 | groupRolesReply.RoleData[i].RoleID = | 9114 | groupRolesReply.RoleData[i].RoleID = |
9258 | d.RoleID; | 9115 | d.RoleID; |
9259 | groupRolesReply.RoleData[i].Name = | 9116 | groupRolesReply.RoleData[i].Name = |
9260 | Utils.StringToBytes(d.Name); | 9117 | Util.StringToBytes256(d.Name); |
9261 | groupRolesReply.RoleData[i].Title = | 9118 | groupRolesReply.RoleData[i].Title = |
9262 | Utils.StringToBytes(d.Title); | 9119 | Util.StringToBytes256(d.Title); |
9263 | groupRolesReply.RoleData[i].Description = | 9120 | groupRolesReply.RoleData[i].Description = |
9264 | Utils.StringToBytes(d.Description); | 9121 | Util.StringToBytes1024(d.Description); |
9265 | groupRolesReply.RoleData[i].Powers = | 9122 | groupRolesReply.RoleData[i].Powers = |
9266 | d.Powers; | 9123 | d.Powers; |
9267 | groupRolesReply.RoleData[i].Members = | 9124 | groupRolesReply.RoleData[i].Members = |
@@ -9317,7 +9174,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9317 | groupRoleMembersReply.MemberData = | 9174 | groupRoleMembersReply.MemberData = |
9318 | new GroupRoleMembersReplyPacket.MemberDataBlock[pairs]; | 9175 | new GroupRoleMembersReplyPacket.MemberDataBlock[pairs]; |
9319 | 9176 | ||
9320 | for (int i = 0 ; i < pairs ; i++) | 9177 | for (int i = 0; i < pairs; i++) |
9321 | { | 9178 | { |
9322 | GroupRoleMembersData d = mappings[0]; | 9179 | GroupRoleMembersData d = mappings[0]; |
9323 | mappings.RemoveAt(0); | 9180 | mappings.RemoveAt(0); |
@@ -9444,7 +9301,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9444 | ParcelDeedToGroup handlerParcelDeedToGroup = OnParcelDeedToGroup; | 9301 | ParcelDeedToGroup handlerParcelDeedToGroup = OnParcelDeedToGroup; |
9445 | if (handlerParcelDeedToGroup != null) | 9302 | if (handlerParcelDeedToGroup != null) |
9446 | { | 9303 | { |
9447 | handlerParcelDeedToGroup(parcelDeedToGroup.Data.LocalID, parcelDeedToGroup.Data.GroupID,this); | 9304 | handlerParcelDeedToGroup(parcelDeedToGroup.Data.LocalID, parcelDeedToGroup.Data.GroupID, this); |
9448 | 9305 | ||
9449 | } | 9306 | } |
9450 | } | 9307 | } |
@@ -9488,9 +9345,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9488 | groupNoticesListReply.Data[i].Timestamp = | 9345 | groupNoticesListReply.Data[i].Timestamp = |
9489 | g.Timestamp; | 9346 | g.Timestamp; |
9490 | groupNoticesListReply.Data[i].FromName = | 9347 | groupNoticesListReply.Data[i].FromName = |
9491 | Utils.StringToBytes(g.FromName); | 9348 | Util.StringToBytes256(g.FromName); |
9492 | groupNoticesListReply.Data[i].Subject = | 9349 | groupNoticesListReply.Data[i].Subject = |
9493 | Utils.StringToBytes(g.Subject); | 9350 | Util.StringToBytes256(g.Subject); |
9494 | groupNoticesListReply.Data[i].HasAttachment = | 9351 | groupNoticesListReply.Data[i].HasAttachment = |
9495 | g.HasAttachment; | 9352 | g.HasAttachment; |
9496 | groupNoticesListReply.Data[i].AssetType = | 9353 | groupNoticesListReply.Data[i].AssetType = |
@@ -9902,7 +9759,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9902 | 9759 | ||
9903 | PickDelete handlerPickDelete = OnPickDelete; | 9760 | PickDelete handlerPickDelete = OnPickDelete; |
9904 | if (handlerPickDelete != null) | 9761 | if (handlerPickDelete != null) |
9905 | handlerPickDelete(this, pickDelete.Data.PickID); | 9762 | handlerPickDelete(this, pickDelete.Data.PickID); |
9906 | break; | 9763 | break; |
9907 | case PacketType.PickGodDelete: | 9764 | case PacketType.PickGodDelete: |
9908 | PickGodDeletePacket pickGodDelete = | 9765 | PickGodDeletePacket pickGodDelete = |
@@ -9922,7 +9779,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9922 | handlerPickGodDelete(this, | 9779 | handlerPickGodDelete(this, |
9923 | pickGodDelete.AgentData.AgentID, | 9780 | pickGodDelete.AgentData.AgentID, |
9924 | pickGodDelete.Data.PickID, | 9781 | pickGodDelete.Data.PickID, |
9925 | pickGodDelete.Data.QueryID); | 9782 | pickGodDelete.Data.QueryID); |
9926 | break; | 9783 | break; |
9927 | case PacketType.PickInfoUpdate: | 9784 | case PacketType.PickInfoUpdate: |
9928 | PickInfoUpdatePacket pickInfoUpdate = | 9785 | PickInfoUpdatePacket pickInfoUpdate = |
@@ -10013,7 +9870,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10013 | m_log.Warn("[CLIENT]: unhandled packet " + Pack); | 9870 | m_log.Warn("[CLIENT]: unhandled packet " + Pack); |
10014 | break; | 9871 | break; |
10015 | 9872 | ||
10016 | #endregion | 9873 | #endregion |
10017 | } | 9874 | } |
10018 | 9875 | ||
10019 | PacketPool.Instance.ReturnPacket(Pack); | 9876 | PacketPool.Instance.ReturnPacket(Pack); |
@@ -10050,7 +9907,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10050 | //shape.Textures = ntex; | 9907 | //shape.Textures = ntex; |
10051 | return shape; | 9908 | return shape; |
10052 | } | 9909 | } |
10053 | 9910 | ||
10054 | public ClientInfo GetClientInfo() | 9911 | public ClientInfo GetClientInfo() |
10055 | { | 9912 | { |
10056 | ClientInfo info = m_udpClient.GetClientInfo(); | 9913 | ClientInfo info = m_udpClient.GetClientInfo(); |
@@ -10078,7 +9935,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10078 | { | 9935 | { |
10079 | ParcelMediaCommandMessagePacket commandMessagePacket = new ParcelMediaCommandMessagePacket(); | 9936 | ParcelMediaCommandMessagePacket commandMessagePacket = new ParcelMediaCommandMessagePacket(); |
10080 | commandMessagePacket.CommandBlock.Flags = flags; | 9937 | commandMessagePacket.CommandBlock.Flags = flags; |
10081 | commandMessagePacket.CommandBlock.Command =(uint) command; | 9938 | commandMessagePacket.CommandBlock.Command = (uint)command; |
10082 | commandMessagePacket.CommandBlock.Time = time; | 9939 | commandMessagePacket.CommandBlock.Time = time; |
10083 | 9940 | ||
10084 | OutPacket(commandMessagePacket, ThrottleOutPacketType.Unknown); | 9941 | OutPacket(commandMessagePacket, ThrottleOutPacketType.Unknown); |
@@ -10089,12 +9946,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10089 | byte mediaLoop) | 9946 | byte mediaLoop) |
10090 | { | 9947 | { |
10091 | ParcelMediaUpdatePacket updatePacket = new ParcelMediaUpdatePacket(); | 9948 | ParcelMediaUpdatePacket updatePacket = new ParcelMediaUpdatePacket(); |
10092 | updatePacket.DataBlock.MediaURL = Utils.StringToBytes(mediaUrl); | 9949 | updatePacket.DataBlock.MediaURL = Util.StringToBytes256(mediaUrl); |
10093 | updatePacket.DataBlock.MediaID = mediaTextureID; | 9950 | updatePacket.DataBlock.MediaID = mediaTextureID; |
10094 | updatePacket.DataBlock.MediaAutoScale = autoScale; | 9951 | updatePacket.DataBlock.MediaAutoScale = autoScale; |
10095 | 9952 | ||
10096 | updatePacket.DataBlockExtended.MediaType = Utils.StringToBytes(mediaType); | 9953 | updatePacket.DataBlockExtended.MediaType = Util.StringToBytes256(mediaType); |
10097 | updatePacket.DataBlockExtended.MediaDesc = Utils.StringToBytes(mediaDesc); | 9954 | updatePacket.DataBlockExtended.MediaDesc = Util.StringToBytes256(mediaDesc); |
10098 | updatePacket.DataBlockExtended.MediaWidth = mediaWidth; | 9955 | updatePacket.DataBlockExtended.MediaWidth = mediaWidth; |
10099 | updatePacket.DataBlockExtended.MediaHeight = mediaHeight; | 9956 | updatePacket.DataBlockExtended.MediaHeight = mediaHeight; |
10100 | updatePacket.DataBlockExtended.MediaLoop = mediaLoop; | 9957 | updatePacket.DataBlockExtended.MediaLoop = mediaLoop; |
@@ -10106,7 +9963,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10106 | 9963 | ||
10107 | #region Camera | 9964 | #region Camera |
10108 | 9965 | ||
10109 | public void SendSetFollowCamProperties (UUID objectID, SortedDictionary<int, float> parameters) | 9966 | public void SendSetFollowCamProperties(UUID objectID, SortedDictionary<int, float> parameters) |
10110 | { | 9967 | { |
10111 | SetFollowCamPropertiesPacket packet = (SetFollowCamPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.SetFollowCamProperties); | 9968 | SetFollowCamPropertiesPacket packet = (SetFollowCamPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.SetFollowCamProperties); |
10112 | packet.ObjectData.ObjectID = objectID; | 9969 | packet.ObjectData.ObjectID = objectID; |
@@ -10124,7 +9981,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10124 | OutPacket(packet, ThrottleOutPacketType.Task); | 9981 | OutPacket(packet, ThrottleOutPacketType.Task); |
10125 | } | 9982 | } |
10126 | 9983 | ||
10127 | public void SendClearFollowCamProperties (UUID objectID) | 9984 | public void SendClearFollowCamProperties(UUID objectID) |
10128 | { | 9985 | { |
10129 | ClearFollowCamPropertiesPacket packet = (ClearFollowCamPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ClearFollowCamProperties); | 9986 | ClearFollowCamPropertiesPacket packet = (ClearFollowCamPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ClearFollowCamProperties); |
10130 | packet.ObjectData.ObjectID = objectID; | 9987 | packet.ObjectData.ObjectID = objectID; |
@@ -10226,8 +10083,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10226 | { | 10083 | { |
10227 | return m_udpClient.GetStats(); | 10084 | return m_udpClient.GetStats(); |
10228 | } | 10085 | } |
10229 | 10086 | ||
10230 | public string XReport(string uptime, string version) | 10087 | public string XReport(string uptime, string version) |
10231 | { | 10088 | { |
10232 | return String.Empty; | 10089 | return String.Empty; |
10233 | } | 10090 | } |
@@ -10301,7 +10158,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10301 | } | 10158 | } |
10302 | 10159 | ||
10303 | //m_log.DebugFormat("[ASSET CACHE]: Asset transfer request for asset which is {0} already known to be missing. Dropping", requestID); | 10160 | //m_log.DebugFormat("[ASSET CACHE]: Asset transfer request for asset which is {0} already known to be missing. Dropping", requestID); |
10304 | 10161 | ||
10305 | // FIXME: We never tell the client about assets which do not exist when requested by this transfer mechanism, which can't be right. | 10162 | // FIXME: We never tell the client about assets which do not exist when requested by this transfer mechanism, which can't be right. |
10306 | return; | 10163 | return; |
10307 | } | 10164 | } |
@@ -10371,5 +10228,167 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10371 | pack.TextureData.TextureID = textureID; | 10228 | pack.TextureData.TextureID = textureID; |
10372 | OutPacket(pack, ThrottleOutPacketType.Task); | 10229 | OutPacket(pack, ThrottleOutPacketType.Task); |
10373 | } | 10230 | } |
10231 | |||
10232 | #region PriorityQueue | ||
10233 | private class PriorityQueue<TPriority, TValue> | ||
10234 | { | ||
10235 | internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id); | ||
10236 | |||
10237 | private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[1]; | ||
10238 | private Dictionary<uint, LookupItem> m_lookupTable; | ||
10239 | private Comparison<TPriority> m_comparison; | ||
10240 | private object m_syncRoot = new object(); | ||
10241 | |||
10242 | internal PriorityQueue() : | ||
10243 | this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, Comparer<TPriority>.Default) { } | ||
10244 | internal PriorityQueue(int capacity) : | ||
10245 | this(capacity, Comparer<TPriority>.Default) { } | ||
10246 | internal PriorityQueue(IComparer<TPriority> comparer) : | ||
10247 | this(new Comparison<TPriority>(comparer.Compare)) { } | ||
10248 | internal PriorityQueue(Comparison<TPriority> comparison) : | ||
10249 | this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, comparison) { } | ||
10250 | internal PriorityQueue(int capacity, IComparer<TPriority> comparer) : | ||
10251 | this(capacity, new Comparison<TPriority>(comparer.Compare)) { } | ||
10252 | internal PriorityQueue(int capacity, Comparison<TPriority> comparison) | ||
10253 | { | ||
10254 | m_lookupTable = new Dictionary<uint, LookupItem>(capacity); | ||
10255 | |||
10256 | for (int i = 0; i < m_heaps.Length; ++i) | ||
10257 | m_heaps[i] = new MinHeap<MinHeapItem>(capacity); | ||
10258 | this.m_comparison = comparison; | ||
10259 | } | ||
10260 | |||
10261 | internal object SyncRoot { get { return this.m_syncRoot; } } | ||
10262 | internal int Count | ||
10263 | { | ||
10264 | get | ||
10265 | { | ||
10266 | int count = 0; | ||
10267 | for (int i = 0; i < m_heaps.Length; ++i) | ||
10268 | count = m_heaps[i].Count; | ||
10269 | return count; | ||
10270 | } | ||
10271 | } | ||
10272 | |||
10273 | internal bool Enqueue(TPriority priority, TValue value, uint local_id) | ||
10274 | { | ||
10275 | LookupItem item; | ||
10276 | |||
10277 | if (m_lookupTable.TryGetValue(local_id, out item)) | ||
10278 | { | ||
10279 | item.Heap[item.Handle] = new MinHeapItem(priority, value, local_id, this.m_comparison); | ||
10280 | return false; | ||
10281 | } | ||
10282 | else | ||
10283 | { | ||
10284 | item.Heap = m_heaps[0]; | ||
10285 | item.Heap.Add(new MinHeapItem(priority, value, local_id, this.m_comparison), ref item.Handle); | ||
10286 | m_lookupTable.Add(local_id, item); | ||
10287 | return true; | ||
10288 | } | ||
10289 | } | ||
10290 | |||
10291 | internal TValue Peek() | ||
10292 | { | ||
10293 | for (int i = 0; i < m_heaps.Length; ++i) | ||
10294 | if (m_heaps[i].Count > 0) | ||
10295 | return m_heaps[i].Min().Value; | ||
10296 | throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); | ||
10297 | } | ||
10298 | |||
10299 | internal TValue Dequeue() | ||
10300 | { | ||
10301 | for (int i = 0; i < m_heaps.Length; ++i) | ||
10302 | { | ||
10303 | if (m_heaps[i].Count > 0) | ||
10304 | { | ||
10305 | MinHeapItem item = m_heaps[i].RemoveMin(); | ||
10306 | m_lookupTable.Remove(item.LocalID); | ||
10307 | return item.Value; | ||
10308 | } | ||
10309 | } | ||
10310 | throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); | ||
10311 | } | ||
10312 | |||
10313 | internal void Reprioritize(UpdatePriorityHandler handler) | ||
10314 | { | ||
10315 | MinHeapItem item; | ||
10316 | TPriority priority; | ||
10317 | |||
10318 | foreach (LookupItem lookup in new List<LookupItem>(this.m_lookupTable.Values)) | ||
10319 | { | ||
10320 | if (lookup.Heap.TryGetValue(lookup.Handle, out item)) | ||
10321 | { | ||
10322 | priority = item.Priority; | ||
10323 | if (handler(ref priority, item.LocalID)) | ||
10324 | { | ||
10325 | if (lookup.Heap.ContainsHandle(lookup.Handle)) | ||
10326 | lookup.Heap[lookup.Handle] = | ||
10327 | new MinHeapItem(priority, item.Value, item.LocalID, this.m_comparison); | ||
10328 | } | ||
10329 | else | ||
10330 | { | ||
10331 | m_log.Warn("[LLCLIENTVIEW]: UpdatePriorityHandler returned false, dropping update"); | ||
10332 | lookup.Heap.Remove(lookup.Handle); | ||
10333 | this.m_lookupTable.Remove(item.LocalID); | ||
10334 | } | ||
10335 | } | ||
10336 | } | ||
10337 | } | ||
10338 | |||
10339 | #region MinHeapItem | ||
10340 | private struct MinHeapItem : IComparable<MinHeapItem> | ||
10341 | { | ||
10342 | private TPriority priority; | ||
10343 | private TValue value; | ||
10344 | private uint local_id; | ||
10345 | private Comparison<TPriority> comparison; | ||
10346 | |||
10347 | internal MinHeapItem(TPriority priority, TValue value, uint local_id) : | ||
10348 | this(priority, value, local_id, Comparer<TPriority>.Default) { } | ||
10349 | internal MinHeapItem(TPriority priority, TValue value, uint local_id, IComparer<TPriority> comparer) : | ||
10350 | this(priority, value, local_id, new Comparison<TPriority>(comparer.Compare)) { } | ||
10351 | internal MinHeapItem(TPriority priority, TValue value, uint local_id, Comparison<TPriority> comparison) | ||
10352 | { | ||
10353 | this.priority = priority; | ||
10354 | this.value = value; | ||
10355 | this.local_id = local_id; | ||
10356 | this.comparison = comparison; | ||
10357 | } | ||
10358 | |||
10359 | internal TPriority Priority { get { return this.priority; } } | ||
10360 | internal TValue Value { get { return this.value; } } | ||
10361 | internal uint LocalID { get { return this.local_id; } } | ||
10362 | |||
10363 | public override string ToString() | ||
10364 | { | ||
10365 | StringBuilder sb = new StringBuilder(); | ||
10366 | sb.Append("["); | ||
10367 | if (this.priority != null) | ||
10368 | sb.Append(this.priority.ToString()); | ||
10369 | sb.Append(","); | ||
10370 | if (this.value != null) | ||
10371 | sb.Append(this.value.ToString()); | ||
10372 | sb.Append("]"); | ||
10373 | return sb.ToString(); | ||
10374 | } | ||
10375 | |||
10376 | public int CompareTo(MinHeapItem other) | ||
10377 | { | ||
10378 | return this.comparison(this.priority, other.priority); | ||
10379 | } | ||
10380 | } | ||
10381 | #endregion | ||
10382 | |||
10383 | #region LookupItem | ||
10384 | private struct LookupItem | ||
10385 | { | ||
10386 | internal MinHeap<MinHeapItem> Heap; | ||
10387 | internal IHandle Handle; | ||
10388 | } | ||
10389 | #endregion | ||
10390 | } | ||
10391 | #endregion | ||
10392 | |||
10374 | } | 10393 | } |
10375 | } | 10394 | } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs index d25bf95..938cf50 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs | |||
@@ -51,7 +51,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
51 | 51 | ||
52 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 52 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
53 | private bool m_shuttingdown; | 53 | private bool m_shuttingdown; |
54 | private long m_lastloopprocessed; | ||
55 | private AssetBase m_missingImage; | 54 | private AssetBase m_missingImage; |
56 | private LLClientView m_client; //Client we're assigned to | 55 | private LLClientView m_client; //Client we're assigned to |
57 | private IAssetService m_assetCache; //Asset Cache | 56 | private IAssetService m_assetCache; //Asset Cache |
@@ -169,7 +168,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
169 | 168 | ||
170 | public bool ProcessImageQueue(int packetsToSend) | 169 | public bool ProcessImageQueue(int packetsToSend) |
171 | { | 170 | { |
172 | m_lastloopprocessed = DateTime.Now.Ticks; | ||
173 | int packetsSent = 0; | 171 | int packetsSent = 0; |
174 | 172 | ||
175 | while (packetsSent < packetsToSend) | 173 | while (packetsSent < packetsToSend) |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 4eee6b6..a9bc7d2 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | |||
@@ -33,6 +33,8 @@ using OpenSim.Framework; | |||
33 | using OpenMetaverse; | 33 | using OpenMetaverse; |
34 | using OpenMetaverse.Packets; | 34 | using OpenMetaverse.Packets; |
35 | 35 | ||
36 | using TokenBucket = OpenSim.Region.ClientStack.LindenUDP.TokenBucket; | ||
37 | |||
36 | namespace OpenSim.Region.ClientStack.LindenUDP | 38 | namespace OpenSim.Region.ClientStack.LindenUDP |
37 | { | 39 | { |
38 | #region Delegates | 40 | #region Delegates |
@@ -48,11 +50,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
48 | /// are waiting on ACKs for</param> | 50 | /// are waiting on ACKs for</param> |
49 | public delegate void PacketStats(int inPackets, int outPackets, int unAckedBytes); | 51 | public delegate void PacketStats(int inPackets, int outPackets, int unAckedBytes); |
50 | /// <summary> | 52 | /// <summary> |
51 | /// Fired when the queue for a packet category is empty. This event can be | 53 | /// Fired when the queue for one or more packet categories is empty. This |
52 | /// hooked to put more data on the empty queue | 54 | /// event can be hooked to put more data on the empty queues |
53 | /// </summary> | 55 | /// </summary> |
54 | /// <param name="category">Category of the packet queue that is empty</param> | 56 | /// <param name="category">Categories of the packet queues that are empty</param> |
55 | public delegate void QueueEmpty(ThrottleOutPacketType category); | 57 | public delegate void QueueEmpty(ThrottleOutPacketTypeFlags categories); |
56 | 58 | ||
57 | #endregion Delegates | 59 | #endregion Delegates |
58 | 60 | ||
@@ -98,12 +100,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
98 | /// <summary>True when this connection is alive, otherwise false</summary> | 100 | /// <summary>True when this connection is alive, otherwise false</summary> |
99 | public bool IsConnected = true; | 101 | public bool IsConnected = true; |
100 | /// <summary>True when this connection is paused, otherwise false</summary> | 102 | /// <summary>True when this connection is paused, otherwise false</summary> |
101 | public bool IsPaused = true; | 103 | public bool IsPaused; |
102 | /// <summary>Environment.TickCount when the last packet was received for this client</summary> | 104 | /// <summary>Environment.TickCount when the last packet was received for this client</summary> |
103 | public int TickLastPacketReceived; | 105 | public int TickLastPacketReceived; |
104 | 106 | ||
105 | /// <summary>Timer granularity. This is set to the measured resolution of Environment.TickCount</summary> | ||
106 | public readonly float G; | ||
107 | /// <summary>Smoothed round-trip time. A smoothed average of the round-trip time for sending a | 107 | /// <summary>Smoothed round-trip time. A smoothed average of the round-trip time for sending a |
108 | /// reliable packet to the client and receiving an ACK</summary> | 108 | /// reliable packet to the client and receiving an ACK</summary> |
109 | public float SRTT; | 109 | public float SRTT; |
@@ -128,6 +128,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
128 | private int m_packetsReceivedReported; | 128 | private int m_packetsReceivedReported; |
129 | /// <summary>Total number of sent packets that we have reported to the OnPacketStats event(s)</summary> | 129 | /// <summary>Total number of sent packets that we have reported to the OnPacketStats event(s)</summary> |
130 | private int m_packetsSentReported; | 130 | private int m_packetsSentReported; |
131 | /// <summary>Holds the Environment.TickCount value of when the next OnQueueEmpty can be fired</summary> | ||
132 | private int m_nextOnQueueEmpty = 1; | ||
131 | 133 | ||
132 | /// <summary>Throttle bucket for this agent's connection</summary> | 134 | /// <summary>Throttle bucket for this agent's connection</summary> |
133 | private readonly TokenBucket m_throttle; | 135 | private readonly TokenBucket m_throttle; |
@@ -140,9 +142,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
140 | /// <summary>A container that can hold one packet for each outbox, used to store | 142 | /// <summary>A container that can hold one packet for each outbox, used to store |
141 | /// dequeued packets that are being held for throttling</summary> | 143 | /// dequeued packets that are being held for throttling</summary> |
142 | private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; | 144 | private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; |
143 | /// <summary>Flags to prevent queue empty callbacks from stacking up on | ||
144 | /// top of each other</summary> | ||
145 | private readonly bool[] m_onQueueEmptyRunning = new bool[THROTTLE_CATEGORY_COUNT]; | ||
146 | /// <summary>A reference to the LLUDPServer that is managing this client</summary> | 145 | /// <summary>A reference to the LLUDPServer that is managing this client</summary> |
147 | private readonly LLUDPServer m_udpServer; | 146 | private readonly LLUDPServer m_udpServer; |
148 | 147 | ||
@@ -163,26 +162,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
163 | CircuitCode = circuitCode; | 162 | CircuitCode = circuitCode; |
164 | m_udpServer = server; | 163 | m_udpServer = server; |
165 | m_defaultThrottleRates = rates; | 164 | m_defaultThrottleRates = rates; |
165 | // Create a token bucket throttle for this client that has the scene token bucket as a parent | ||
166 | m_throttle = new TokenBucket(parentThrottle, rates.TotalLimit, rates.Total); | 166 | m_throttle = new TokenBucket(parentThrottle, rates.TotalLimit, rates.Total); |
167 | // Create an array of token buckets for this clients different throttle categories | ||
167 | m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; | 168 | m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; |
168 | 169 | ||
169 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) | 170 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) |
170 | { | 171 | { |
171 | ThrottleOutPacketType type = (ThrottleOutPacketType)i; | 172 | ThrottleOutPacketType type = (ThrottleOutPacketType)i; |
172 | 173 | ||
174 | // Initialize the packet outboxes, where packets sit while they are waiting for tokens | ||
173 | m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); | 175 | m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); |
176 | // Initialize the token buckets that control the throttling for each category | ||
174 | m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type)); | 177 | m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type)); |
175 | } | 178 | } |
176 | 179 | ||
177 | // Set the granularity variable used for retransmission calculations to | ||
178 | // the measured resolution of Environment.TickCount | ||
179 | G = server.TickCountResolution; | ||
180 | |||
181 | // Default the retransmission timeout to three seconds | 180 | // Default the retransmission timeout to three seconds |
182 | RTO = 3000; | 181 | RTO = 3000; |
183 | 182 | ||
184 | // Initialize this to a sane value to prevent early disconnects | 183 | // Initialize this to a sane value to prevent early disconnects |
185 | TickLastPacketReceived = Environment.TickCount; | 184 | TickLastPacketReceived = Environment.TickCount & Int32.MaxValue; |
186 | } | 185 | } |
187 | 186 | ||
188 | /// <summary> | 187 | /// <summary> |
@@ -191,7 +190,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
191 | public void Shutdown() | 190 | public void Shutdown() |
192 | { | 191 | { |
193 | IsConnected = false; | 192 | IsConnected = false; |
194 | NeedAcks.Clear(); | ||
195 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) | 193 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) |
196 | { | 194 | { |
197 | m_packetOutboxes[i].Clear(); | 195 | m_packetOutboxes[i].Clear(); |
@@ -293,36 +291,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
293 | int state = (int)((float)task * STATE_TASK_PERCENTAGE); | 291 | int state = (int)((float)task * STATE_TASK_PERCENTAGE); |
294 | task -= state; | 292 | task -= state; |
295 | 293 | ||
296 | int ceiling = Int32.MaxValue; | 294 | // Make sure none of the throttles are set below our packet MTU, |
297 | if (m_defaultThrottleRates.Total != 0) | 295 | // otherwise a throttle could become permanently clogged |
298 | { | 296 | resend = Math.Max(resend, LLUDPServer.MTU); |
299 | ceiling = m_defaultThrottleRates.Total; | 297 | land = Math.Max(land, LLUDPServer.MTU); |
300 | if (ceiling < Packet.MTU) ceiling = Packet.MTU; | 298 | wind = Math.Max(wind, LLUDPServer.MTU); |
301 | } | 299 | cloud = Math.Max(cloud, LLUDPServer.MTU); |
302 | 300 | task = Math.Max(task, LLUDPServer.MTU); | |
303 | resend = Utils.Clamp(resend, Packet.MTU, ceiling); | 301 | texture = Math.Max(texture, LLUDPServer.MTU); |
304 | land = Utils.Clamp(land, Packet.MTU, ceiling); | 302 | asset = Math.Max(asset, LLUDPServer.MTU); |
305 | wind = Utils.Clamp(wind, Packet.MTU, ceiling); | 303 | state = Math.Max(state, LLUDPServer.MTU); |
306 | cloud = Utils.Clamp(cloud, Packet.MTU, ceiling); | ||
307 | task = Utils.Clamp(task, Packet.MTU, ceiling); | ||
308 | texture = Utils.Clamp(texture, Packet.MTU, ceiling); | ||
309 | asset = Utils.Clamp(asset, Packet.MTU, ceiling); | ||
310 | state = Utils.Clamp(state, Packet.MTU, ceiling); | ||
311 | 304 | ||
312 | int total = resend + land + wind + cloud + task + texture + asset + state; | 305 | int total = resend + land + wind + cloud + task + texture + asset + state; |
313 | int taskTotal = task + state; | ||
314 | 306 | ||
315 | m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, State={8}, Total={9}", | 307 | m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, State={8}, Total={9}", |
316 | AgentID, resend, land, wind, cloud, task, texture, asset, state, total); | 308 | AgentID, resend, land, wind, cloud, task, texture, asset, state, total); |
317 | 309 | ||
318 | SetThrottle(ThrottleOutPacketType.Resend, resend, resend); | 310 | // Update the token buckets with new throttle values |
319 | SetThrottle(ThrottleOutPacketType.Land, land, land); | 311 | TokenBucket bucket; |
320 | SetThrottle(ThrottleOutPacketType.Wind, wind, wind); | 312 | |
321 | SetThrottle(ThrottleOutPacketType.Cloud, cloud, cloud); | 313 | bucket = m_throttle; |
322 | SetThrottle(ThrottleOutPacketType.Task, task, taskTotal); | 314 | bucket.MaxBurst = total; |
323 | SetThrottle(ThrottleOutPacketType.Texture, texture, texture); | 315 | |
324 | SetThrottle(ThrottleOutPacketType.Asset, asset, asset); | 316 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; |
325 | SetThrottle(ThrottleOutPacketType.State, state, taskTotal); | 317 | bucket.DripRate = resend; |
318 | bucket.MaxBurst = resend; | ||
319 | |||
320 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land]; | ||
321 | bucket.DripRate = land; | ||
322 | bucket.MaxBurst = land; | ||
323 | |||
324 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind]; | ||
325 | bucket.DripRate = wind; | ||
326 | bucket.MaxBurst = wind; | ||
327 | |||
328 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud]; | ||
329 | bucket.DripRate = cloud; | ||
330 | bucket.MaxBurst = cloud; | ||
331 | |||
332 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset]; | ||
333 | bucket.DripRate = asset; | ||
334 | bucket.MaxBurst = asset; | ||
335 | |||
336 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task]; | ||
337 | bucket.DripRate = task + state; | ||
338 | bucket.MaxBurst = task + state; | ||
339 | |||
340 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.State]; | ||
341 | bucket.DripRate = state; | ||
342 | bucket.MaxBurst = state; | ||
343 | |||
344 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; | ||
345 | bucket.DripRate = texture; | ||
346 | bucket.MaxBurst = texture; | ||
326 | } | 347 | } |
327 | 348 | ||
328 | public byte[] GetThrottlesPacked() | 349 | public byte[] GetThrottlesPacked() |
@@ -342,17 +363,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
342 | return data; | 363 | return data; |
343 | } | 364 | } |
344 | 365 | ||
345 | public void SetThrottle(ThrottleOutPacketType category, int rate, int maxBurst) | ||
346 | { | ||
347 | int i = (int)category; | ||
348 | if (i >= 0 && i < m_throttleCategories.Length) | ||
349 | { | ||
350 | TokenBucket bucket = m_throttleCategories[(int)category]; | ||
351 | bucket.DripRate = rate; | ||
352 | bucket.MaxBurst = maxBurst; | ||
353 | } | ||
354 | } | ||
355 | |||
356 | public bool EnqueueOutgoing(OutgoingPacket packet) | 366 | public bool EnqueueOutgoing(OutgoingPacket packet) |
357 | { | 367 | { |
358 | int category = (int)packet.Category; | 368 | int category = (int)packet.Category; |
@@ -394,10 +404,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
394 | OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; | 404 | OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; |
395 | TokenBucket bucket; | 405 | TokenBucket bucket; |
396 | bool packetSent = false; | 406 | bool packetSent = false; |
407 | ThrottleOutPacketTypeFlags emptyCategories = 0; | ||
408 | |||
409 | //string queueDebugOutput = String.Empty; // Serious debug business | ||
397 | 410 | ||
398 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) | 411 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) |
399 | { | 412 | { |
400 | bucket = m_throttleCategories[i]; | 413 | bucket = m_throttleCategories[i]; |
414 | //queueDebugOutput += m_packetOutboxes[i].Count + " "; // Serious debug business | ||
401 | 415 | ||
402 | if (m_nextPackets[i] != null) | 416 | if (m_nextPackets[i] != null) |
403 | { | 417 | { |
@@ -438,17 +452,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
438 | // empty callback now so it has a chance to fill before we | 452 | // empty callback now so it has a chance to fill before we |
439 | // get back here | 453 | // get back here |
440 | if (queue.Count == 0) | 454 | if (queue.Count == 0) |
441 | BeginFireQueueEmpty(i); | 455 | emptyCategories |= CategoryToFlag(i); |
442 | } | 456 | } |
443 | else | 457 | else |
444 | { | 458 | { |
445 | // No packets in this queue. Fire the queue empty callback | 459 | // No packets in this queue. Fire the queue empty callback |
446 | // if it has not been called recently | 460 | // if it has not been called recently |
447 | BeginFireQueueEmpty(i); | 461 | emptyCategories |= CategoryToFlag(i); |
448 | } | 462 | } |
449 | } | 463 | } |
450 | } | 464 | } |
451 | 465 | ||
466 | if (emptyCategories != 0) | ||
467 | BeginFireQueueEmpty(emptyCategories); | ||
468 | |||
469 | //m_log.Info("[LLUDPCLIENT]: Queues: " + queueDebugOutput); // Serious debug business | ||
452 | return packetSent; | 470 | return packetSent; |
453 | } | 471 | } |
454 | 472 | ||
@@ -479,8 +497,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
479 | SRTT = (1.0f - ALPHA) * SRTT + ALPHA * r; | 497 | SRTT = (1.0f - ALPHA) * SRTT + ALPHA * r; |
480 | } | 498 | } |
481 | 499 | ||
482 | // Always round retransmission timeout up to two seconds | 500 | RTO = (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR)); |
483 | RTO = Math.Max(2000, (int)(SRTT + Math.Max(G, K * RTTVAR))); | 501 | |
502 | // Clamp the retransmission timeout to manageable values | ||
503 | RTO = Utils.Clamp(RTO, 3000, 10000); | ||
504 | |||
484 | //m_log.Debug("[LLUDPCLIENT]: Setting agent " + this.Agent.FullName + "'s RTO to " + RTO + "ms with an RTTVAR of " + | 505 | //m_log.Debug("[LLUDPCLIENT]: Setting agent " + this.Agent.FullName + "'s RTO to " + RTO + "ms with an RTTVAR of " + |
485 | // RTTVAR + " based on new RTT of " + r + "ms"); | 506 | // RTTVAR + " based on new RTT of " + r + "ms"); |
486 | } | 507 | } |
@@ -491,33 +512,89 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
491 | /// </summary> | 512 | /// </summary> |
492 | /// <param name="throttleIndex">Throttle category to fire the callback | 513 | /// <param name="throttleIndex">Throttle category to fire the callback |
493 | /// for</param> | 514 | /// for</param> |
494 | private void BeginFireQueueEmpty(int throttleIndex) | 515 | private void BeginFireQueueEmpty(ThrottleOutPacketTypeFlags categories) |
495 | { | 516 | { |
496 | if (!m_onQueueEmptyRunning[throttleIndex]) | 517 | if (m_nextOnQueueEmpty != 0 && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty) |
497 | Util.FireAndForget(FireQueueEmpty, throttleIndex); | 518 | { |
519 | // Use a value of 0 to signal that FireQueueEmpty is running | ||
520 | m_nextOnQueueEmpty = 0; | ||
521 | // Asynchronously run the callback | ||
522 | Util.FireAndForget(FireQueueEmpty, categories); | ||
523 | } | ||
498 | } | 524 | } |
499 | 525 | ||
500 | /// <summary> | 526 | /// <summary> |
501 | /// Checks to see if this queue empty callback is already running, | 527 | /// Fires the OnQueueEmpty callback and sets the minimum time that it |
502 | /// then firing the event | 528 | /// can be called again |
503 | /// </summary> | 529 | /// </summary> |
504 | /// <param name="o">Throttle category to fire the callback for, stored | 530 | /// <param name="o">Throttle categories to fire the callback for, |
505 | /// as an object to match the WaitCallback delegate signature</param> | 531 | /// stored as an object to match the WaitCallback delegate |
532 | /// signature</param> | ||
506 | private void FireQueueEmpty(object o) | 533 | private void FireQueueEmpty(object o) |
507 | { | 534 | { |
508 | int i = (int)o; | 535 | const int MIN_CALLBACK_MS = 30; |
509 | ThrottleOutPacketType type = (ThrottleOutPacketType)i; | 536 | |
537 | ThrottleOutPacketTypeFlags categories = (ThrottleOutPacketTypeFlags)o; | ||
510 | QueueEmpty callback = OnQueueEmpty; | 538 | QueueEmpty callback = OnQueueEmpty; |
539 | |||
540 | int start = Environment.TickCount & Int32.MaxValue; | ||
511 | 541 | ||
512 | if (callback != null) | 542 | if (callback != null) |
513 | { | 543 | { |
514 | if (!m_onQueueEmptyRunning[i]) | 544 | try { callback(categories); } |
515 | { | 545 | catch (Exception e) { m_log.Error("[LLUDPCLIENT]: OnQueueEmpty(" + categories + ") threw an exception: " + e.Message, e); } |
516 | m_onQueueEmptyRunning[i] = true; | 546 | } |
517 | try { callback(type); } | 547 | |
518 | catch (Exception e) { m_log.Error("[LLUDPCLIENT]: OnQueueEmpty(" + type + ") threw an exception: " + e.Message, e); } | 548 | m_nextOnQueueEmpty = start + MIN_CALLBACK_MS; |
519 | m_onQueueEmptyRunning[i] = false; | 549 | if (m_nextOnQueueEmpty == 0) |
520 | } | 550 | m_nextOnQueueEmpty = 1; |
551 | } | ||
552 | |||
553 | /// <summary> | ||
554 | /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a | ||
555 | /// flag value | ||
556 | /// </summary> | ||
557 | /// <param name="i">Throttle category to convert</param> | ||
558 | /// <returns>Flag representation of the throttle category</returns> | ||
559 | private static ThrottleOutPacketTypeFlags CategoryToFlag(int i) | ||
560 | { | ||
561 | ThrottleOutPacketType category = (ThrottleOutPacketType)i; | ||
562 | |||
563 | /* | ||
564 | * Land = 1, | ||
565 | /// <summary>Wind data</summary> | ||
566 | Wind = 2, | ||
567 | /// <summary>Cloud data</summary> | ||
568 | Cloud = 3, | ||
569 | /// <summary>Any packets that do not fit into the other throttles</summary> | ||
570 | Task = 4, | ||
571 | /// <summary>Texture assets</summary> | ||
572 | Texture = 5, | ||
573 | /// <summary>Non-texture assets</summary> | ||
574 | Asset = 6, | ||
575 | /// <summary>Avatar and primitive data</summary> | ||
576 | /// <remarks>This is a sub-category of Task</remarks> | ||
577 | State = 7, | ||
578 | */ | ||
579 | |||
580 | switch (category) | ||
581 | { | ||
582 | case ThrottleOutPacketType.Land: | ||
583 | return ThrottleOutPacketTypeFlags.Land; | ||
584 | case ThrottleOutPacketType.Wind: | ||
585 | return ThrottleOutPacketTypeFlags.Wind; | ||
586 | case ThrottleOutPacketType.Cloud: | ||
587 | return ThrottleOutPacketTypeFlags.Cloud; | ||
588 | case ThrottleOutPacketType.Task: | ||
589 | return ThrottleOutPacketTypeFlags.Task; | ||
590 | case ThrottleOutPacketType.Texture: | ||
591 | return ThrottleOutPacketTypeFlags.Texture; | ||
592 | case ThrottleOutPacketType.Asset: | ||
593 | return ThrottleOutPacketTypeFlags.Asset; | ||
594 | case ThrottleOutPacketType.State: | ||
595 | return ThrottleOutPacketTypeFlags.State; | ||
596 | default: | ||
597 | return 0; | ||
521 | } | 598 | } |
522 | } | 599 | } |
523 | } | 600 | } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 545a0bc..a9f4b2c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -39,6 +39,8 @@ using OpenSim.Framework.Statistics; | |||
39 | using OpenSim.Region.Framework.Scenes; | 39 | using OpenSim.Region.Framework.Scenes; |
40 | using OpenMetaverse; | 40 | using OpenMetaverse; |
41 | 41 | ||
42 | using TokenBucket = OpenSim.Region.ClientStack.LindenUDP.TokenBucket; | ||
43 | |||
42 | namespace OpenSim.Region.ClientStack.LindenUDP | 44 | namespace OpenSim.Region.ClientStack.LindenUDP |
43 | { | 45 | { |
44 | /// <summary> | 46 | /// <summary> |
@@ -89,8 +91,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
89 | /// </summary> | 91 | /// </summary> |
90 | public class LLUDPServer : OpenSimUDPBase | 92 | public class LLUDPServer : OpenSimUDPBase |
91 | { | 93 | { |
94 | /// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary> | ||
95 | public const int MTU = 1400; | ||
96 | |||
92 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 97 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
93 | 98 | ||
99 | /// <summary>The measured resolution of Environment.TickCount</summary> | ||
100 | public readonly float TickCountResolution; | ||
101 | |||
94 | /// <summary>Handlers for incoming packets</summary> | 102 | /// <summary>Handlers for incoming packets</summary> |
95 | //PacketEventDictionary packetEvents = new PacketEventDictionary(); | 103 | //PacketEventDictionary packetEvents = new PacketEventDictionary(); |
96 | /// <summary>Incoming packets that are awaiting handling</summary> | 104 | /// <summary>Incoming packets that are awaiting handling</summary> |
@@ -104,20 +112,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
104 | /// <summary>Manages authentication for agent circuits</summary> | 112 | /// <summary>Manages authentication for agent circuits</summary> |
105 | private AgentCircuitManager m_circuitManager; | 113 | private AgentCircuitManager m_circuitManager; |
106 | /// <summary>Reference to the scene this UDP server is attached to</summary> | 114 | /// <summary>Reference to the scene this UDP server is attached to</summary> |
107 | private IScene m_scene; | 115 | private Scene m_scene; |
108 | /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary> | 116 | /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary> |
109 | private Location m_location; | 117 | private Location m_location; |
110 | /// <summary>The measured resolution of Environment.TickCount</summary> | ||
111 | private float m_tickCountResolution; | ||
112 | /// <summary>The size of the receive buffer for the UDP socket. This value | 118 | /// <summary>The size of the receive buffer for the UDP socket. This value |
113 | /// is passed up to the operating system and used in the system networking | 119 | /// is passed up to the operating system and used in the system networking |
114 | /// stack. Use zero to leave this value as the default</summary> | 120 | /// stack. Use zero to leave this value as the default</summary> |
115 | private int m_recvBufferSize; | 121 | private int m_recvBufferSize; |
116 | /// <summary>Flag to process packets asynchronously or synchronously</summary> | 122 | /// <summary>Flag to process packets asynchronously or synchronously</summary> |
117 | private bool m_asyncPacketHandling; | 123 | private bool m_asyncPacketHandling; |
124 | /// <summary>Tracks whether or not a packet was sent each round so we know | ||
125 | /// whether or not to sleep</summary> | ||
126 | private bool m_packetSent; | ||
127 | |||
128 | /// <summary>Environment.TickCount of the last time the outgoing packet handler executed</summary> | ||
129 | private int m_tickLastOutgoingPacketHandler; | ||
130 | /// <summary>Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler looped</summary> | ||
131 | private int m_elapsedMSOutgoingPacketHandler; | ||
132 | /// <summary>Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed</summary> | ||
133 | private int m_elapsed100MSOutgoingPacketHandler; | ||
134 | /// <summary>Keeps track of the number of 500 millisecond periods elapsed in the outgoing packet handler executed</summary> | ||
135 | private int m_elapsed500MSOutgoingPacketHandler; | ||
136 | |||
137 | /// <summary>Flag to signal when clients should check for resends</summary> | ||
138 | private bool m_resendUnacked; | ||
139 | /// <summary>Flag to signal when clients should send ACKs</summary> | ||
140 | private bool m_sendAcks; | ||
141 | /// <summary>Flag to signal when clients should send pings</summary> | ||
142 | private bool m_sendPing; | ||
118 | 143 | ||
119 | /// <summary>The measured resolution of Environment.TickCount</summary> | ||
120 | public float TickCountResolution { get { return m_tickCountResolution; } } | ||
121 | public Socket Server { get { return null; } } | 144 | public Socket Server { get { return null; } } |
122 | 145 | ||
123 | public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) | 146 | public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) |
@@ -126,16 +149,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
126 | #region Environment.TickCount Measurement | 149 | #region Environment.TickCount Measurement |
127 | 150 | ||
128 | // Measure the resolution of Environment.TickCount | 151 | // Measure the resolution of Environment.TickCount |
129 | m_tickCountResolution = 0f; | 152 | TickCountResolution = 0f; |
130 | for (int i = 0; i < 5; i++) | 153 | for (int i = 0; i < 5; i++) |
131 | { | 154 | { |
132 | int start = Environment.TickCount; | 155 | int start = Environment.TickCount; |
133 | int now = start; | 156 | int now = start; |
134 | while (now == start) | 157 | while (now == start) |
135 | now = Environment.TickCount; | 158 | now = Environment.TickCount; |
136 | m_tickCountResolution += (float)(now - start) * 0.2f; | 159 | TickCountResolution += (float)(now - start) * 0.2f; |
137 | } | 160 | } |
138 | m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms"); | 161 | m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms"); |
162 | TickCountResolution = (float)Math.Ceiling(TickCountResolution); | ||
139 | 163 | ||
140 | #endregion Environment.TickCount Measurement | 164 | #endregion Environment.TickCount Measurement |
141 | 165 | ||
@@ -181,15 +205,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
181 | 205 | ||
182 | public void AddScene(IScene scene) | 206 | public void AddScene(IScene scene) |
183 | { | 207 | { |
184 | if (m_scene == null) | 208 | if (m_scene != null) |
185 | { | 209 | { |
186 | m_scene = scene; | 210 | m_log.Error("[LLUDPSERVER]: AddScene() called on an LLUDPServer that already has a scene"); |
187 | m_location = new Location(m_scene.RegionInfo.RegionHandle); | 211 | return; |
188 | } | 212 | } |
189 | else | 213 | |
214 | if (!(scene is Scene)) | ||
190 | { | 215 | { |
191 | m_log.Error("[LLUDPSERVER]: AddScene() called on an LLUDPServer that already has a scene"); | 216 | m_log.Error("[LLUDPSERVER]: AddScene() called with an unrecognized scene type " + scene.GetType()); |
217 | return; | ||
192 | } | 218 | } |
219 | |||
220 | m_scene = (Scene)scene; | ||
221 | m_location = new Location(m_scene.RegionInfo.RegionHandle); | ||
193 | } | 222 | } |
194 | 223 | ||
195 | public bool HandlesRegion(Location x) | 224 | public bool HandlesRegion(Location x) |
@@ -267,38 +296,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
267 | { | 296 | { |
268 | int dataLength = data.Length; | 297 | int dataLength = data.Length; |
269 | bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0; | 298 | bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0; |
299 | bool doCopy = true; | ||
270 | 300 | ||
271 | // Frequency analysis of outgoing packet sizes shows a large clump of packets at each end of the spectrum. | 301 | // Frequency analysis of outgoing packet sizes shows a large clump of packets at each end of the spectrum. |
272 | // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting | 302 | // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting |
273 | // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here | 303 | // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here |
274 | // to accomodate for both common scenarios and provide ample room for ACK appending in both | 304 | // to accomodate for both common scenarios and provide ample room for ACK appending in both |
275 | int bufferSize = (dataLength > 180) ? Packet.MTU : 200; | 305 | int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200; |
276 | 306 | ||
277 | UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); | 307 | UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); |
278 | 308 | ||
279 | // Zerocode if needed | 309 | // Zerocode if needed |
280 | if (doZerocode) | 310 | if (doZerocode) |
281 | { | 311 | { |
282 | try { dataLength = Helpers.ZeroEncode(data, dataLength, buffer.Data); } | 312 | try |
313 | { | ||
314 | dataLength = Helpers.ZeroEncode(data, dataLength, buffer.Data); | ||
315 | doCopy = false; | ||
316 | } | ||
283 | catch (IndexOutOfRangeException) | 317 | catch (IndexOutOfRangeException) |
284 | { | 318 | { |
285 | // The packet grew larger than the bufferSize while zerocoding. | 319 | // The packet grew larger than the bufferSize while zerocoding. |
286 | // Remove the MSG_ZEROCODED flag and send the unencoded data | 320 | // Remove the MSG_ZEROCODED flag and send the unencoded data |
287 | // instead | 321 | // instead |
288 | m_log.Debug("[LLUDPSERVER]: Packet exceeded buffer size during zerocoding for " + type + ". Removing MSG_ZEROCODED flag"); | 322 | m_log.Debug("[LLUDPSERVER]: Packet exceeded buffer size during zerocoding for " + type + ". DataLength=" + dataLength + |
323 | " and BufferLength=" + buffer.Data.Length + ". Removing MSG_ZEROCODED flag"); | ||
289 | data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED); | 324 | data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED); |
290 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); | ||
291 | } | 325 | } |
292 | } | 326 | } |
293 | else | 327 | |
328 | // If the packet data wasn't already copied during zerocoding, copy it now | ||
329 | if (doCopy) | ||
294 | { | 330 | { |
295 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); | 331 | if (dataLength <= buffer.Data.Length) |
332 | { | ||
333 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); | ||
334 | } | ||
335 | else | ||
336 | { | ||
337 | m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" + | ||
338 | type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length + ". Dropping packet"); | ||
339 | return; | ||
340 | } | ||
296 | } | 341 | } |
342 | |||
297 | buffer.DataLength = dataLength; | 343 | buffer.DataLength = dataLength; |
298 | 344 | ||
299 | #region Queue or Send | 345 | #region Queue or Send |
300 | 346 | ||
301 | // Look up the UDPClient this is going to | ||
302 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); | 347 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); |
303 | 348 | ||
304 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) | 349 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) |
@@ -338,57 +383,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
338 | StartPingCheckPacket pc = (StartPingCheckPacket)PacketPool.Instance.GetPacket(PacketType.StartPingCheck); | 383 | StartPingCheckPacket pc = (StartPingCheckPacket)PacketPool.Instance.GetPacket(PacketType.StartPingCheck); |
339 | pc.Header.Reliable = false; | 384 | pc.Header.Reliable = false; |
340 | 385 | ||
341 | OutgoingPacket oldestPacket = udpClient.NeedAcks.GetOldest(); | ||
342 | |||
343 | pc.PingID.PingID = (byte)udpClient.CurrentPingSequence++; | 386 | pc.PingID.PingID = (byte)udpClient.CurrentPingSequence++; |
344 | pc.PingID.OldestUnacked = (oldestPacket != null) ? oldestPacket.SequenceNumber : 0; | 387 | // We *could* get OldestUnacked, but it would hurt performance and not provide any benefit |
388 | pc.PingID.OldestUnacked = 0; | ||
345 | 389 | ||
346 | SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false); | 390 | SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false); |
347 | } | 391 | } |
348 | 392 | ||
349 | public void ResendUnacked(LLUDPClient udpClient) | 393 | public void ResendUnacked(LLUDPClient udpClient) |
350 | { | 394 | { |
351 | if (udpClient.IsConnected && udpClient.NeedAcks.Count > 0) | 395 | if (!udpClient.IsConnected) |
396 | return; | ||
397 | |||
398 | // Disconnect an agent if no packets are received for some time | ||
399 | //FIXME: Make 60 an .ini setting | ||
400 | if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60) | ||
352 | { | 401 | { |
353 | // Disconnect an agent if no packets are received for some time | 402 | m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); |
354 | //FIXME: Make 60 an .ini setting | ||
355 | if (Environment.TickCount - udpClient.TickLastPacketReceived > 1000 * 60) | ||
356 | { | ||
357 | m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); | ||
358 | 403 | ||
359 | RemoveClient(udpClient); | 404 | RemoveClient(udpClient); |
360 | return; | 405 | return; |
361 | } | 406 | } |
362 | 407 | ||
363 | // Get a list of all of the packets that have been sitting unacked longer than udpClient.RTO | 408 | // Get a list of all of the packets that have been sitting unacked longer than udpClient.RTO |
364 | List<OutgoingPacket> expiredPackets = udpClient.NeedAcks.GetExpiredPackets(udpClient.RTO); | 409 | List<OutgoingPacket> expiredPackets = udpClient.NeedAcks.GetExpiredPackets(udpClient.RTO); |
365 | 410 | ||
366 | if (expiredPackets != null) | 411 | if (expiredPackets != null) |
367 | { | 412 | { |
368 | // Resend packets | 413 | m_log.Debug("[LLUDPSERVER]: Resending " + expiredPackets.Count + " packets to " + udpClient.AgentID + ", RTO=" + udpClient.RTO); |
369 | for (int i = 0; i < expiredPackets.Count; i++) | ||
370 | { | ||
371 | OutgoingPacket outgoingPacket = expiredPackets[i]; | ||
372 | 414 | ||
373 | //m_log.DebugFormat("[LLUDPSERVER]: Resending packet #{0} (attempt {1}), {2}ms have passed", | 415 | // Resend packets |
374 | // outgoingPacket.SequenceNumber, outgoingPacket.ResendCount, Environment.TickCount - outgoingPacket.TickCount); | 416 | for (int i = 0; i < expiredPackets.Count; i++) |
417 | { | ||
418 | OutgoingPacket outgoingPacket = expiredPackets[i]; | ||
375 | 419 | ||
376 | // Set the resent flag | 420 | //m_log.DebugFormat("[LLUDPSERVER]: Resending packet #{0} (attempt {1}), {2}ms have passed", |
377 | outgoingPacket.Buffer.Data[0] = (byte)(outgoingPacket.Buffer.Data[0] | Helpers.MSG_RESENT); | 421 | // outgoingPacket.SequenceNumber, outgoingPacket.ResendCount, Environment.TickCount - outgoingPacket.TickCount); |
378 | outgoingPacket.Category = ThrottleOutPacketType.Resend; | ||
379 | 422 | ||
380 | // The TickCount will be set to the current time when the packet | 423 | // Set the resent flag |
381 | // is actually sent out again | 424 | outgoingPacket.Buffer.Data[0] = (byte)(outgoingPacket.Buffer.Data[0] | Helpers.MSG_RESENT); |
382 | outgoingPacket.TickCount = 0; | 425 | outgoingPacket.Category = ThrottleOutPacketType.Resend; |
383 | 426 | ||
384 | // Bump up the resend count on this packet | 427 | // Bump up the resend count on this packet |
385 | Interlocked.Increment(ref outgoingPacket.ResendCount); | 428 | Interlocked.Increment(ref outgoingPacket.ResendCount); |
386 | //Interlocked.Increment(ref Stats.ResentPackets); | 429 | //Interlocked.Increment(ref Stats.ResentPackets); |
387 | 430 | ||
388 | // Requeue or resend the packet | 431 | // Requeue or resend the packet |
389 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) | 432 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) |
390 | SendPacketFinal(outgoingPacket); | 433 | SendPacketFinal(outgoingPacket); |
391 | } | ||
392 | } | 434 | } |
393 | } | 435 | } |
394 | } | 436 | } |
@@ -409,9 +451,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
409 | if (!udpClient.IsConnected) | 451 | if (!udpClient.IsConnected) |
410 | return; | 452 | return; |
411 | 453 | ||
412 | // Keep track of when this packet was sent out (right now) | ||
413 | outgoingPacket.TickCount = Environment.TickCount; | ||
414 | |||
415 | #region ACK Appending | 454 | #region ACK Appending |
416 | 455 | ||
417 | int dataLength = buffer.DataLength; | 456 | int dataLength = buffer.DataLength; |
@@ -464,6 +503,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
464 | 503 | ||
465 | // Put the UDP payload on the wire | 504 | // Put the UDP payload on the wire |
466 | AsyncBeginSend(buffer); | 505 | AsyncBeginSend(buffer); |
506 | |||
507 | // Keep track of when this packet was sent out (right now) | ||
508 | outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; | ||
467 | } | 509 | } |
468 | 510 | ||
469 | protected override void PacketReceived(UDPPacketBuffer buffer) | 511 | protected override void PacketReceived(UDPPacketBuffer buffer) |
@@ -506,14 +548,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
506 | // UseCircuitCode handling | 548 | // UseCircuitCode handling |
507 | if (packet.Type == PacketType.UseCircuitCode) | 549 | if (packet.Type == PacketType.UseCircuitCode) |
508 | { | 550 | { |
509 | AddNewClient((UseCircuitCodePacket)packet, (IPEndPoint)buffer.RemoteEndPoint); | 551 | Util.FireAndForget( |
552 | delegate(object o) | ||
553 | { | ||
554 | IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint; | ||
555 | |||
556 | // Begin the process of adding the client to the simulator | ||
557 | AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint); | ||
558 | |||
559 | // Acknowledge the UseCircuitCode packet | ||
560 | SendAckImmediate(remoteEndPoint, packet.Header.Sequence); | ||
561 | } | ||
562 | ); | ||
563 | return; | ||
510 | } | 564 | } |
511 | 565 | ||
512 | // Determine which agent this packet came from | 566 | // Determine which agent this packet came from |
513 | IClientAPI client; | 567 | IClientAPI client; |
514 | if (!m_scene.ClientManager.TryGetValue(address, out client) || !(client is LLClientView)) | 568 | if (!m_scene.ClientManager.TryGetValue(address, out client) || !(client is LLClientView)) |
515 | { | 569 | { |
516 | m_log.Warn("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + | 570 | m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + |
517 | " in " + m_scene.RegionInfo.RegionName + ", currently tracking " + m_scene.ClientManager.Count + " clients"); | 571 | " in " + m_scene.RegionInfo.RegionName + ", currently tracking " + m_scene.ClientManager.Count + " clients"); |
518 | return; | 572 | return; |
519 | } | 573 | } |
@@ -528,19 +582,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
528 | // Stats tracking | 582 | // Stats tracking |
529 | Interlocked.Increment(ref udpClient.PacketsReceived); | 583 | Interlocked.Increment(ref udpClient.PacketsReceived); |
530 | 584 | ||
531 | #region ACK Receiving | 585 | int now = Environment.TickCount & Int32.MaxValue; |
532 | |||
533 | int now = Environment.TickCount; | ||
534 | udpClient.TickLastPacketReceived = now; | 586 | udpClient.TickLastPacketReceived = now; |
535 | 587 | ||
588 | #region ACK Receiving | ||
589 | |||
536 | // Handle appended ACKs | 590 | // Handle appended ACKs |
537 | if (packet.Header.AppendedAcks && packet.Header.AckList != null) | 591 | if (packet.Header.AppendedAcks && packet.Header.AckList != null) |
538 | { | 592 | { |
539 | lock (udpClient.NeedAcks.SyncRoot) | 593 | for (int i = 0; i < packet.Header.AckList.Length; i++) |
540 | { | 594 | udpClient.NeedAcks.Remove(packet.Header.AckList[i], now, packet.Header.Resent); |
541 | for (int i = 0; i < packet.Header.AckList.Length; i++) | ||
542 | AcknowledgePacket(udpClient, packet.Header.AckList[i], now, packet.Header.Resent); | ||
543 | } | ||
544 | } | 595 | } |
545 | 596 | ||
546 | // Handle PacketAck packets | 597 | // Handle PacketAck packets |
@@ -548,11 +599,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
548 | { | 599 | { |
549 | PacketAckPacket ackPacket = (PacketAckPacket)packet; | 600 | PacketAckPacket ackPacket = (PacketAckPacket)packet; |
550 | 601 | ||
551 | lock (udpClient.NeedAcks.SyncRoot) | 602 | for (int i = 0; i < ackPacket.Packets.Length; i++) |
552 | { | 603 | udpClient.NeedAcks.Remove(ackPacket.Packets[i].ID, now, packet.Header.Resent); |
553 | for (int i = 0; i < ackPacket.Packets.Length; i++) | 604 | |
554 | AcknowledgePacket(udpClient, ackPacket.Packets[i].ID, now, packet.Header.Resent); | 605 | // We don't need to do anything else with PacketAck packets |
555 | } | 606 | return; |
556 | } | 607 | } |
557 | 608 | ||
558 | #endregion ACK Receiving | 609 | #endregion ACK Receiving |
@@ -560,20 +611,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
560 | #region ACK Sending | 611 | #region ACK Sending |
561 | 612 | ||
562 | if (packet.Header.Reliable) | 613 | if (packet.Header.Reliable) |
614 | { | ||
563 | udpClient.PendingAcks.Enqueue(packet.Header.Sequence); | 615 | udpClient.PendingAcks.Enqueue(packet.Header.Sequence); |
564 | 616 | ||
565 | // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out, | 617 | // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out, |
566 | // add the current received bytes to it, test if 2*MTU bytes have been sent, if so remove | 618 | // add the current received bytes to it, test if 2*MTU bytes have been sent, if so remove |
567 | // 2*MTU bytes from the value and send ACKs, and finally add the local value back to | 619 | // 2*MTU bytes from the value and send ACKs, and finally add the local value back to |
568 | // client.BytesSinceLastACK. Lockless thread safety | 620 | // client.BytesSinceLastACK. Lockless thread safety |
569 | int bytesSinceLastACK = Interlocked.Exchange(ref udpClient.BytesSinceLastACK, 0); | 621 | int bytesSinceLastACK = Interlocked.Exchange(ref udpClient.BytesSinceLastACK, 0); |
570 | bytesSinceLastACK += buffer.DataLength; | 622 | bytesSinceLastACK += buffer.DataLength; |
571 | if (bytesSinceLastACK > Packet.MTU * 2) | 623 | if (bytesSinceLastACK > LLUDPServer.MTU * 2) |
572 | { | 624 | { |
573 | bytesSinceLastACK -= Packet.MTU * 2; | 625 | bytesSinceLastACK -= LLUDPServer.MTU * 2; |
574 | SendAcks(udpClient); | 626 | SendAcks(udpClient); |
627 | } | ||
628 | Interlocked.Add(ref udpClient.BytesSinceLastACK, bytesSinceLastACK); | ||
575 | } | 629 | } |
576 | Interlocked.Add(ref udpClient.BytesSinceLastACK, bytesSinceLastACK); | ||
577 | 630 | ||
578 | #endregion ACK Sending | 631 | #endregion ACK Sending |
579 | 632 | ||
@@ -593,16 +646,47 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
593 | 646 | ||
594 | #endregion Incoming Packet Accounting | 647 | #endregion Incoming Packet Accounting |
595 | 648 | ||
596 | // Don't bother clogging up the queue with PacketAck packets that are already handled here | 649 | #region Ping Check Handling |
597 | if (packet.Type != PacketType.PacketAck) | 650 | |
651 | if (packet.Type == PacketType.StartPingCheck) | ||
598 | { | 652 | { |
599 | // Inbox insertion | 653 | // We don't need to do anything else with ping checks |
600 | packetInbox.Enqueue(new IncomingPacket(udpClient, packet)); | 654 | StartPingCheckPacket startPing = (StartPingCheckPacket)packet; |
655 | |||
656 | CompletePingCheckPacket completePing = new CompletePingCheckPacket(); | ||
657 | completePing.PingID.PingID = startPing.PingID.PingID; | ||
658 | SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false); | ||
659 | return; | ||
601 | } | 660 | } |
661 | else if (packet.Type == PacketType.CompletePingCheck) | ||
662 | { | ||
663 | // We don't currently track client ping times | ||
664 | return; | ||
665 | } | ||
666 | |||
667 | #endregion Ping Check Handling | ||
668 | |||
669 | // Inbox insertion | ||
670 | packetInbox.Enqueue(new IncomingPacket(udpClient, packet)); | ||
602 | } | 671 | } |
603 | 672 | ||
604 | protected override void PacketSent(UDPPacketBuffer buffer, int bytesSent) | 673 | private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber) |
605 | { | 674 | { |
675 | PacketAckPacket ack = new PacketAckPacket(); | ||
676 | ack.Header.Reliable = false; | ||
677 | ack.Packets = new PacketAckPacket.PacketsBlock[1]; | ||
678 | ack.Packets[0] = new PacketAckPacket.PacketsBlock(); | ||
679 | ack.Packets[0].ID = sequenceNumber; | ||
680 | |||
681 | byte[] packetData = ack.ToBytes(); | ||
682 | int length = packetData.Length; | ||
683 | |||
684 | UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length); | ||
685 | buffer.DataLength = length; | ||
686 | |||
687 | Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); | ||
688 | |||
689 | AsyncBeginSend(buffer); | ||
606 | } | 690 | } |
607 | 691 | ||
608 | private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) | 692 | private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) |
@@ -672,33 +756,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
672 | client.Close(); | 756 | client.Close(); |
673 | } | 757 | } |
674 | 758 | ||
675 | private void AcknowledgePacket(LLUDPClient client, uint ack, int currentTime, bool fromResend) | ||
676 | { | ||
677 | OutgoingPacket ackedPacket; | ||
678 | if (client.NeedAcks.RemoveUnsafe(ack, out ackedPacket) && !fromResend) | ||
679 | { | ||
680 | // Update stats | ||
681 | Interlocked.Add(ref client.UnackedBytes, -ackedPacket.Buffer.DataLength); | ||
682 | |||
683 | // Calculate the round-trip time for this packet and its ACK | ||
684 | int rtt = currentTime - ackedPacket.TickCount; | ||
685 | if (rtt > 0) | ||
686 | client.UpdateRoundTrip(rtt); | ||
687 | } | ||
688 | } | ||
689 | |||
690 | private void IncomingPacketHandler() | 759 | private void IncomingPacketHandler() |
691 | { | 760 | { |
692 | // Set this culture for the thread that incoming packets are received | 761 | // Set this culture for the thread that incoming packets are received |
693 | // on to en-US to avoid number parsing issues | 762 | // on to en-US to avoid number parsing issues |
694 | Culture.SetCurrentCulture(); | 763 | Culture.SetCurrentCulture(); |
695 | 764 | ||
696 | IncomingPacket incomingPacket = null; | ||
697 | |||
698 | while (base.IsRunning) | 765 | while (base.IsRunning) |
699 | { | 766 | { |
700 | if (packetInbox.Dequeue(100, ref incomingPacket)) | 767 | try |
701 | Util.FireAndForget(ProcessInPacket, incomingPacket); | 768 | { |
769 | IncomingPacket incomingPacket = null; | ||
770 | |||
771 | if (packetInbox.Dequeue(100, ref incomingPacket)) | ||
772 | Util.FireAndForget(ProcessInPacket, incomingPacket); | ||
773 | } | ||
774 | catch (Exception ex) | ||
775 | { | ||
776 | m_log.Error("[LLUDPSERVER]: Error in the incoming packet handler loop: " + ex.Message, ex); | ||
777 | } | ||
702 | } | 778 | } |
703 | 779 | ||
704 | if (packetInbox.Count > 0) | 780 | if (packetInbox.Count > 0) |
@@ -712,68 +788,97 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
712 | // on to en-US to avoid number parsing issues | 788 | // on to en-US to avoid number parsing issues |
713 | Culture.SetCurrentCulture(); | 789 | Culture.SetCurrentCulture(); |
714 | 790 | ||
715 | int now = Environment.TickCount; | ||
716 | int elapsedMS = 0; | ||
717 | int elapsed100MS = 0; | ||
718 | int elapsed500MS = 0; | ||
719 | |||
720 | while (base.IsRunning) | 791 | while (base.IsRunning) |
721 | { | 792 | { |
722 | bool resendUnacked = false; | 793 | try |
723 | bool sendAcks = false; | 794 | { |
724 | bool sendPings = false; | 795 | m_packetSent = false; |
725 | bool packetSent = false; | ||
726 | 796 | ||
727 | elapsedMS += Environment.TickCount - now; | 797 | #region Update Timers |
728 | 798 | ||
729 | // Check for pending outgoing resends every 100ms | 799 | m_resendUnacked = false; |
730 | if (elapsedMS >= 100) | 800 | m_sendAcks = false; |
731 | { | 801 | m_sendPing = false; |
732 | resendUnacked = true; | 802 | |
733 | elapsedMS -= 100; | 803 | // Update elapsed time |
734 | ++elapsed100MS; | 804 | int thisTick = Environment.TickCount & Int32.MaxValue; |
805 | if (m_tickLastOutgoingPacketHandler > thisTick) | ||
806 | m_elapsedMSOutgoingPacketHandler += ((Int32.MaxValue - m_tickLastOutgoingPacketHandler) + thisTick); | ||
807 | else | ||
808 | m_elapsedMSOutgoingPacketHandler += (thisTick - m_tickLastOutgoingPacketHandler); | ||
809 | |||
810 | m_tickLastOutgoingPacketHandler = thisTick; | ||
811 | |||
812 | // Check for pending outgoing resends every 100ms | ||
813 | if (m_elapsedMSOutgoingPacketHandler >= 100) | ||
814 | { | ||
815 | m_resendUnacked = true; | ||
816 | m_elapsedMSOutgoingPacketHandler = 0; | ||
817 | m_elapsed100MSOutgoingPacketHandler += 1; | ||
818 | } | ||
819 | |||
820 | // Check for pending outgoing ACKs every 500ms | ||
821 | if (m_elapsed100MSOutgoingPacketHandler >= 5) | ||
822 | { | ||
823 | m_sendAcks = true; | ||
824 | m_elapsed100MSOutgoingPacketHandler = 0; | ||
825 | m_elapsed500MSOutgoingPacketHandler += 1; | ||
826 | } | ||
827 | |||
828 | // Send pings to clients every 5000ms | ||
829 | if (m_elapsed500MSOutgoingPacketHandler >= 10) | ||
830 | { | ||
831 | m_sendPing = true; | ||
832 | m_elapsed500MSOutgoingPacketHandler = 0; | ||
833 | } | ||
834 | |||
835 | #endregion Update Timers | ||
836 | |||
837 | // Handle outgoing packets, resends, acknowledgements, and pings for each | ||
838 | // client. m_packetSent will be set to true if a packet is sent | ||
839 | m_scene.ClientManager.ForEachSync(ClientOutgoingPacketHandler); | ||
840 | |||
841 | // If nothing was sent, sleep for the minimum amount of time before a | ||
842 | // token bucket could get more tokens | ||
843 | if (!m_packetSent) | ||
844 | Thread.Sleep((int)TickCountResolution); | ||
735 | } | 845 | } |
736 | // Check for pending outgoing ACKs every 500ms | 846 | catch (Exception ex) |
737 | if (elapsed100MS >= 5) | ||
738 | { | 847 | { |
739 | sendAcks = true; | 848 | m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex); |
740 | elapsed100MS = 0; | ||
741 | ++elapsed500MS; | ||
742 | } | 849 | } |
743 | // Send pings to clients every 5000ms | 850 | } |
744 | if (elapsed500MS >= 10) | 851 | } |
852 | |||
853 | private void ClientOutgoingPacketHandler(IClientAPI client) | ||
854 | { | ||
855 | try | ||
856 | { | ||
857 | if (client is LLClientView) | ||
745 | { | 858 | { |
746 | sendPings = true; | 859 | LLUDPClient udpClient = ((LLClientView)client).UDPClient; |
747 | elapsed500MS = 0; | ||
748 | } | ||
749 | 860 | ||
750 | m_scene.ClientManager.ForEach( | 861 | if (udpClient.IsConnected) |
751 | delegate(IClientAPI client) | ||
752 | { | 862 | { |
753 | if (client is LLClientView) | 863 | if (m_resendUnacked) |
754 | { | 864 | ResendUnacked(udpClient); |
755 | LLUDPClient udpClient = ((LLClientView)client).UDPClient; | 865 | |
756 | 866 | if (m_sendAcks) | |
757 | if (udpClient.IsConnected) | 867 | SendAcks(udpClient); |
758 | { | 868 | |
759 | if (udpClient.DequeueOutgoing()) | 869 | if (m_sendPing) |
760 | packetSent = true; | 870 | SendPing(udpClient); |
761 | if (resendUnacked) | ||
762 | ResendUnacked(udpClient); | ||
763 | if (sendAcks) | ||
764 | { | ||
765 | SendAcks(udpClient); | ||
766 | udpClient.SendPacketStats(); | ||
767 | } | ||
768 | if (sendPings) | ||
769 | SendPing(udpClient); | ||
770 | } | ||
771 | } | ||
772 | } | ||
773 | ); | ||
774 | 871 | ||
775 | if (!packetSent) | 872 | // Dequeue any outgoing packets that are within the throttle limits |
776 | Thread.Sleep(20); | 873 | if (udpClient.DequeueOutgoing()) |
874 | m_packetSent = true; | ||
875 | } | ||
876 | } | ||
877 | } | ||
878 | catch (Exception ex) | ||
879 | { | ||
880 | m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name + | ||
881 | " threw an exception: " + ex.Message, ex); | ||
777 | } | 882 | } |
778 | } | 883 | } |
779 | 884 | ||
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs index d16837d..552cc4a 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs | |||
@@ -45,13 +45,6 @@ namespace OpenMetaverse | |||
45 | /// </summary> | 45 | /// </summary> |
46 | /// <param name="buffer">Incoming packet buffer</param> | 46 | /// <param name="buffer">Incoming packet buffer</param> |
47 | protected abstract void PacketReceived(UDPPacketBuffer buffer); | 47 | protected abstract void PacketReceived(UDPPacketBuffer buffer); |
48 | |||
49 | /// <summary> | ||
50 | /// This method is called when an outgoing packet is sent | ||
51 | /// </summary> | ||
52 | /// <param name="buffer">Outgoing packet buffer</param> | ||
53 | /// <param name="bytesSent">Number of bytes written to the wire</param> | ||
54 | protected abstract void PacketSent(UDPPacketBuffer buffer, int bytesSent); | ||
55 | 48 | ||
56 | /// <summary>UDP port to bind to in server mode</summary> | 49 | /// <summary>UDP port to bind to in server mode</summary> |
57 | protected int m_udpPort; | 50 | protected int m_udpPort; |
@@ -279,8 +272,6 @@ namespace OpenMetaverse | |||
279 | { | 272 | { |
280 | UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState; | 273 | UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState; |
281 | int bytesSent = m_udpSocket.EndSendTo(result); | 274 | int bytesSent = m_udpSocket.EndSendTo(result); |
282 | |||
283 | PacketSent(buf, bytesSent); | ||
284 | } | 275 | } |
285 | catch (SocketException) { } | 276 | catch (SocketException) { } |
286 | catch (ObjectDisposedException) { } | 277 | catch (ObjectDisposedException) { } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs new file mode 100644 index 0000000..bdbd284 --- /dev/null +++ b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs | |||
@@ -0,0 +1,217 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | |||
30 | namespace OpenSim.Region.ClientStack.LindenUDP | ||
31 | { | ||
32 | /// <summary> | ||
33 | /// A hierarchical token bucket for bandwidth throttling. See | ||
34 | /// http://en.wikipedia.org/wiki/Token_bucket for more information | ||
35 | /// </summary> | ||
36 | public class TokenBucket | ||
37 | { | ||
38 | /// <summary>Parent bucket to this bucket, or null if this is a root | ||
39 | /// bucket</summary> | ||
40 | TokenBucket parent; | ||
41 | /// <summary>Size of the bucket in bytes. If zero, the bucket has | ||
42 | /// infinite capacity</summary> | ||
43 | int maxBurst; | ||
44 | /// <summary>Rate that the bucket fills, in bytes per millisecond. If | ||
45 | /// zero, the bucket always remains full</summary> | ||
46 | int tokensPerMS; | ||
47 | /// <summary>Number of tokens currently in the bucket</summary> | ||
48 | int content; | ||
49 | /// <summary>Time of the last drip, in system ticks</summary> | ||
50 | int lastDrip; | ||
51 | |||
52 | #region Properties | ||
53 | |||
54 | /// <summary> | ||
55 | /// The parent bucket of this bucket, or null if this bucket has no | ||
56 | /// parent. The parent bucket will limit the aggregate bandwidth of all | ||
57 | /// of its children buckets | ||
58 | /// </summary> | ||
59 | public TokenBucket Parent | ||
60 | { | ||
61 | get { return parent; } | ||
62 | } | ||
63 | |||
64 | /// <summary> | ||
65 | /// Maximum burst rate in bytes per second. This is the maximum number | ||
66 | /// of tokens that can accumulate in the bucket at any one time | ||
67 | /// </summary> | ||
68 | public int MaxBurst | ||
69 | { | ||
70 | get { return maxBurst; } | ||
71 | set { maxBurst = (value >= 0 ? value : 0); } | ||
72 | } | ||
73 | |||
74 | /// <summary> | ||
75 | /// The speed limit of this bucket in bytes per second. This is the | ||
76 | /// number of tokens that are added to the bucket per second | ||
77 | /// </summary> | ||
78 | /// <remarks>Tokens are added to the bucket any time | ||
79 | /// <seealso cref="RemoveTokens"/> is called, at the granularity of | ||
80 | /// the system tick interval (typically around 15-22ms)</remarks> | ||
81 | public int DripRate | ||
82 | { | ||
83 | get { return tokensPerMS * 1000; } | ||
84 | set | ||
85 | { | ||
86 | if (value == 0) | ||
87 | tokensPerMS = 0; | ||
88 | else | ||
89 | { | ||
90 | int bpms = (int)((float)value / 1000.0f); | ||
91 | |||
92 | if (bpms <= 0) | ||
93 | tokensPerMS = 1; // 1 byte/ms is the minimum granularity | ||
94 | else | ||
95 | tokensPerMS = bpms; | ||
96 | } | ||
97 | } | ||
98 | } | ||
99 | |||
100 | /// <summary> | ||
101 | /// The speed limit of this bucket in bytes per millisecond | ||
102 | /// </summary> | ||
103 | public int DripPerMS | ||
104 | { | ||
105 | get { return tokensPerMS; } | ||
106 | } | ||
107 | |||
108 | /// <summary> | ||
109 | /// The number of bytes that can be sent at this moment. This is the | ||
110 | /// current number of tokens in the bucket | ||
111 | /// <remarks>If this bucket has a parent bucket that does not have | ||
112 | /// enough tokens for a request, <seealso cref="RemoveTokens"/> will | ||
113 | /// return false regardless of the content of this bucket</remarks> | ||
114 | /// </summary> | ||
115 | public int Content | ||
116 | { | ||
117 | get { return content; } | ||
118 | } | ||
119 | |||
120 | #endregion Properties | ||
121 | |||
122 | /// <summary> | ||
123 | /// Default constructor | ||
124 | /// </summary> | ||
125 | /// <param name="parent">Parent bucket if this is a child bucket, or | ||
126 | /// null if this is a root bucket</param> | ||
127 | /// <param name="maxBurst">Maximum size of the bucket in bytes, or | ||
128 | /// zero if this bucket has no maximum capacity</param> | ||
129 | /// <param name="dripRate">Rate that the bucket fills, in bytes per | ||
130 | /// second. If zero, the bucket always remains full</param> | ||
131 | public TokenBucket(TokenBucket parent, int maxBurst, int dripRate) | ||
132 | { | ||
133 | this.parent = parent; | ||
134 | MaxBurst = maxBurst; | ||
135 | DripRate = dripRate; | ||
136 | lastDrip = Environment.TickCount & Int32.MaxValue; | ||
137 | } | ||
138 | |||
139 | /// <summary> | ||
140 | /// Remove a given number of tokens from the bucket | ||
141 | /// </summary> | ||
142 | /// <param name="amount">Number of tokens to remove from the bucket</param> | ||
143 | /// <returns>True if the requested number of tokens were removed from | ||
144 | /// the bucket, otherwise false</returns> | ||
145 | public bool RemoveTokens(int amount) | ||
146 | { | ||
147 | bool dummy; | ||
148 | return RemoveTokens(amount, out dummy); | ||
149 | } | ||
150 | |||
151 | /// <summary> | ||
152 | /// Remove a given number of tokens from the bucket | ||
153 | /// </summary> | ||
154 | /// <param name="amount">Number of tokens to remove from the bucket</param> | ||
155 | /// <param name="dripSucceeded">True if tokens were added to the bucket | ||
156 | /// during this call, otherwise false</param> | ||
157 | /// <returns>True if the requested number of tokens were removed from | ||
158 | /// the bucket, otherwise false</returns> | ||
159 | public bool RemoveTokens(int amount, out bool dripSucceeded) | ||
160 | { | ||
161 | if (maxBurst == 0) | ||
162 | { | ||
163 | dripSucceeded = true; | ||
164 | return true; | ||
165 | } | ||
166 | |||
167 | dripSucceeded = Drip(); | ||
168 | |||
169 | if (content - amount >= 0) | ||
170 | { | ||
171 | if (parent != null && !parent.RemoveTokens(amount)) | ||
172 | return false; | ||
173 | |||
174 | content -= amount; | ||
175 | return true; | ||
176 | } | ||
177 | else | ||
178 | { | ||
179 | return false; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | /// <summary> | ||
184 | /// Add tokens to the bucket over time. The number of tokens added each | ||
185 | /// call depends on the length of time that has passed since the last | ||
186 | /// call to Drip | ||
187 | /// </summary> | ||
188 | /// <returns>True if tokens were added to the bucket, otherwise false</returns> | ||
189 | public bool Drip() | ||
190 | { | ||
191 | if (tokensPerMS == 0) | ||
192 | { | ||
193 | content = maxBurst; | ||
194 | return true; | ||
195 | } | ||
196 | else | ||
197 | { | ||
198 | int now = Environment.TickCount & Int32.MaxValue; | ||
199 | int deltaMS = now - lastDrip; | ||
200 | |||
201 | if (deltaMS <= 0) | ||
202 | { | ||
203 | if (deltaMS < 0) | ||
204 | lastDrip = now; | ||
205 | return false; | ||
206 | } | ||
207 | |||
208 | int dripAmount = deltaMS * tokensPerMS; | ||
209 | |||
210 | content = Math.Min(content + dripAmount, maxBurst); | ||
211 | lastDrip = now; | ||
212 | |||
213 | return true; | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | } | ||
diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index f3242c1..e43f7cf 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs | |||
@@ -37,97 +37,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
37 | /// </summary> | 37 | /// </summary> |
38 | public sealed class UnackedPacketCollection | 38 | public sealed class UnackedPacketCollection |
39 | { | 39 | { |
40 | /// <summary>Synchronization primitive. A lock must be acquired on this | ||
41 | /// object before calling any of the unsafe methods</summary> | ||
42 | public object SyncRoot = new object(); | ||
43 | |||
44 | /// <summary>Holds the actual unacked packet data, sorted by sequence number</summary> | ||
45 | private SortedDictionary<uint, OutgoingPacket> packets = new SortedDictionary<uint, OutgoingPacket>(); | ||
46 | |||
47 | /// <summary>Gets the total number of unacked packets</summary> | ||
48 | public int Count { get { return packets.Count; } } | ||
49 | |||
50 | /// <summary> | 40 | /// <summary> |
51 | /// Default constructor | 41 | /// Holds information about a pending acknowledgement |
52 | /// </summary> | 42 | /// </summary> |
53 | public UnackedPacketCollection() | 43 | private struct PendingAck |
54 | { | 44 | { |
55 | } | 45 | /// <summary>Sequence number of the packet to remove</summary> |
46 | public uint SequenceNumber; | ||
47 | /// <summary>Environment.TickCount value when the remove was queued. | ||
48 | /// This is used to update round-trip times for packets</summary> | ||
49 | public int RemoveTime; | ||
50 | /// <summary>Whether or not this acknowledgement was attached to a | ||
51 | /// resent packet. If so, round-trip time will not be calculated</summary> | ||
52 | public bool FromResend; | ||
56 | 53 | ||
57 | /// <summary> | 54 | public PendingAck(uint sequenceNumber, int currentTime, bool fromResend) |
58 | /// Add an unacked packet to the collection | ||
59 | /// </summary> | ||
60 | /// <param name="packet">Packet that is awaiting acknowledgement</param> | ||
61 | /// <returns>True if the packet was successfully added, false if the | ||
62 | /// packet already existed in the collection</returns> | ||
63 | public bool Add(OutgoingPacket packet) | ||
64 | { | ||
65 | lock (SyncRoot) | ||
66 | { | 55 | { |
67 | if (!packets.ContainsKey(packet.SequenceNumber)) | 56 | SequenceNumber = sequenceNumber; |
68 | { | 57 | RemoveTime = currentTime; |
69 | packets.Add(packet.SequenceNumber, packet); | 58 | FromResend = fromResend; |
70 | return true; | ||
71 | } | ||
72 | return false; | ||
73 | } | 59 | } |
74 | } | 60 | } |
75 | 61 | ||
76 | /// <summary> | 62 | /// <summary>Holds the actual unacked packet data, sorted by sequence number</summary> |
77 | /// Removes a packet from the collection without attempting to obtain a | 63 | private Dictionary<uint, OutgoingPacket> m_packets = new Dictionary<uint, OutgoingPacket>(); |
78 | /// lock first | 64 | /// <summary>Holds packets that need to be added to the unacknowledged list</summary> |
79 | /// </summary> | 65 | private LocklessQueue<OutgoingPacket> m_pendingAdds = new LocklessQueue<OutgoingPacket>(); |
80 | /// <param name="sequenceNumber">Sequence number of the packet to remove</param> | 66 | /// <summary>Holds information about pending acknowledgements</summary> |
81 | /// <returns>True if the packet was found and removed, otherwise false</returns> | 67 | private LocklessQueue<PendingAck> m_pendingRemoves = new LocklessQueue<PendingAck>(); |
82 | public bool RemoveUnsafe(uint sequenceNumber) | ||
83 | { | ||
84 | return packets.Remove(sequenceNumber); | ||
85 | } | ||
86 | |||
87 | /// <summary> | ||
88 | /// Removes a packet from the collection without attempting to obtain a | ||
89 | /// lock first | ||
90 | /// </summary> | ||
91 | /// <param name="sequenceNumber">Sequence number of the packet to remove</param> | ||
92 | /// <param name="packet">Returns the removed packet</param> | ||
93 | /// <returns>True if the packet was found and removed, otherwise false</returns> | ||
94 | public bool RemoveUnsafe(uint sequenceNumber, out OutgoingPacket packet) | ||
95 | { | ||
96 | if (packets.TryGetValue(sequenceNumber, out packet)) | ||
97 | { | ||
98 | packets.Remove(sequenceNumber); | ||
99 | return true; | ||
100 | } | ||
101 | |||
102 | return false; | ||
103 | } | ||
104 | 68 | ||
105 | /// <summary> | 69 | /// <summary> |
106 | /// Removes all elements from the collection | 70 | /// Add an unacked packet to the collection |
107 | /// </summary> | 71 | /// </summary> |
108 | public void Clear() | 72 | /// <param name="packet">Packet that is awaiting acknowledgement</param> |
73 | /// <returns>True if the packet was successfully added, false if the | ||
74 | /// packet already existed in the collection</returns> | ||
75 | /// <remarks>This does not immediately add the ACK to the collection, | ||
76 | /// it only queues it so it can be added in a thread-safe way later</remarks> | ||
77 | public void Add(OutgoingPacket packet) | ||
109 | { | 78 | { |
110 | lock (SyncRoot) | 79 | m_pendingAdds.Enqueue(packet); |
111 | packets.Clear(); | ||
112 | } | 80 | } |
113 | 81 | ||
114 | /// <summary> | 82 | /// <summary> |
115 | /// Gets the packet with the lowest sequence number | 83 | /// Marks a packet as acknowledged |
116 | /// </summary> | 84 | /// </summary> |
117 | /// <returns>The packet with the lowest sequence number, or null if the | 85 | /// <param name="sequenceNumber">Sequence number of the packet to |
118 | /// collection is empty</returns> | 86 | /// acknowledge</param> |
119 | public OutgoingPacket GetOldest() | 87 | /// <param name="currentTime">Current value of Environment.TickCount</param> |
88 | /// <remarks>This does not immediately acknowledge the packet, it only | ||
89 | /// queues the ack so it can be handled in a thread-safe way later</remarks> | ||
90 | public void Remove(uint sequenceNumber, int currentTime, bool fromResend) | ||
120 | { | 91 | { |
121 | lock (SyncRoot) | 92 | m_pendingRemoves.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend)); |
122 | { | ||
123 | using (SortedDictionary<uint, OutgoingPacket>.ValueCollection.Enumerator e = packets.Values.GetEnumerator()) | ||
124 | { | ||
125 | if (e.MoveNext()) | ||
126 | return e.Current; | ||
127 | else | ||
128 | return null; | ||
129 | } | ||
130 | } | ||
131 | } | 93 | } |
132 | 94 | ||
133 | /// <summary> | 95 | /// <summary> |
@@ -138,15 +100,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
138 | /// packet is considered expired</param> | 100 | /// packet is considered expired</param> |
139 | /// <returns>A list of all expired packets according to the given | 101 | /// <returns>A list of all expired packets according to the given |
140 | /// expiration timeout</returns> | 102 | /// expiration timeout</returns> |
103 | /// <remarks>This function is not thread safe, and cannot be called | ||
104 | /// multiple times concurrently</remarks> | ||
141 | public List<OutgoingPacket> GetExpiredPackets(int timeoutMS) | 105 | public List<OutgoingPacket> GetExpiredPackets(int timeoutMS) |
142 | { | 106 | { |
107 | ProcessQueues(); | ||
108 | |||
143 | List<OutgoingPacket> expiredPackets = null; | 109 | List<OutgoingPacket> expiredPackets = null; |
144 | 110 | ||
145 | lock (SyncRoot) | 111 | if (m_packets.Count > 0) |
146 | { | 112 | { |
147 | int now = Environment.TickCount; | 113 | int now = Environment.TickCount & Int32.MaxValue; |
148 | foreach (OutgoingPacket packet in packets.Values) | 114 | |
115 | foreach (OutgoingPacket packet in m_packets.Values) | ||
149 | { | 116 | { |
117 | // TickCount of zero means a packet is in the resend queue | ||
118 | // but hasn't actually been sent over the wire yet | ||
150 | if (packet.TickCount == 0) | 119 | if (packet.TickCount == 0) |
151 | continue; | 120 | continue; |
152 | 121 | ||
@@ -154,16 +123,47 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
154 | { | 123 | { |
155 | if (expiredPackets == null) | 124 | if (expiredPackets == null) |
156 | expiredPackets = new List<OutgoingPacket>(); | 125 | expiredPackets = new List<OutgoingPacket>(); |
126 | |||
127 | // The TickCount will be set to the current time when the packet | ||
128 | // is actually sent out again | ||
129 | packet.TickCount = 0; | ||
130 | |||
157 | expiredPackets.Add(packet); | 131 | expiredPackets.Add(packet); |
158 | } | 132 | } |
159 | else | ||
160 | { | ||
161 | break; | ||
162 | } | ||
163 | } | 133 | } |
164 | } | 134 | } |
165 | 135 | ||
166 | return expiredPackets; | 136 | return expiredPackets; |
167 | } | 137 | } |
138 | |||
139 | private void ProcessQueues() | ||
140 | { | ||
141 | // Process all the pending adds | ||
142 | OutgoingPacket pendingAdd; | ||
143 | while (m_pendingAdds.Dequeue(out pendingAdd)) | ||
144 | m_packets[pendingAdd.SequenceNumber] = pendingAdd; | ||
145 | |||
146 | // Process all the pending removes, including updating statistics and round-trip times | ||
147 | PendingAck pendingRemove; | ||
148 | OutgoingPacket ackedPacket; | ||
149 | while (m_pendingRemoves.Dequeue(out pendingRemove)) | ||
150 | { | ||
151 | if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket)) | ||
152 | { | ||
153 | m_packets.Remove(pendingRemove.SequenceNumber); | ||
154 | |||
155 | // Update stats | ||
156 | System.Threading.Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); | ||
157 | |||
158 | if (!pendingRemove.FromResend) | ||
159 | { | ||
160 | // Calculate the round-trip time for this packet and its ACK | ||
161 | int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount; | ||
162 | if (rtt > 0) | ||
163 | ackedPacket.Client.UpdateRoundTrip(rtt); | ||
164 | } | ||
165 | } | ||
166 | } | ||
167 | } | ||
168 | } | 168 | } |
169 | } | 169 | } |
diff --git a/OpenSim/Region/ClientStack/ThrottleSettings.cs b/OpenSim/Region/ClientStack/ThrottleSettings.cs deleted file mode 100644 index fe4718c..0000000 --- a/OpenSim/Region/ClientStack/ThrottleSettings.cs +++ /dev/null | |||
@@ -1,57 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | namespace OpenSim.Region.ClientStack | ||
29 | { | ||
30 | /// <summary> | ||
31 | /// Represent throttle settings for a client stack. These settings are in bytes per second | ||
32 | /// </summary> | ||
33 | public class ThrottleSettings | ||
34 | { | ||
35 | /// <summary> | ||
36 | /// Minimum bytes per second that the throttle can be set to. | ||
37 | /// </summary> | ||
38 | public int Min; | ||
39 | |||
40 | /// <summary> | ||
41 | /// Maximum bytes per second that the throttle can be set to. | ||
42 | /// </summary> | ||
43 | public int Max; | ||
44 | |||
45 | /// <summary> | ||
46 | /// Current bytes per second that the throttle should be set to. | ||
47 | /// </summary> | ||
48 | public int Current; | ||
49 | |||
50 | public ThrottleSettings(int min, int max, int current) | ||
51 | { | ||
52 | Min = min; | ||
53 | Max = max; | ||
54 | Current = current; | ||
55 | } | ||
56 | } | ||
57 | } | ||
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/Tests/TextureSenderTests.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/Tests/TextureSenderTests.cs deleted file mode 100644 index efa275c..0000000 --- a/OpenSim/Region/CoreModules/Agent/TextureSender/Tests/TextureSenderTests.cs +++ /dev/null | |||
@@ -1,180 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using NUnit.Framework; | ||
30 | using NUnit.Framework.SyntaxHelpers; | ||
31 | using OpenMetaverse; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Tests.Common; | ||
34 | using OpenSim.Tests.Common.Mock; | ||
35 | |||
36 | namespace OpenSim.Region.CoreModules.Agent.TextureSender | ||
37 | { | ||
38 | [TestFixture] | ||
39 | public class UserTextureSenderTests | ||
40 | { | ||
41 | public UUID uuid1; | ||
42 | public UUID uuid2; | ||
43 | public UUID uuid3; | ||
44 | public UUID uuid4; | ||
45 | public int npackets, testsize; | ||
46 | public TestClient client; | ||
47 | public TextureSender ts; | ||
48 | public static Random random = new Random(); | ||
49 | |||
50 | [TestFixtureSetUp] | ||
51 | public void Init() | ||
52 | { | ||
53 | AgentCircuitData agent = new AgentCircuitData(); | ||
54 | agent.AgentID = UUID.Random(); | ||
55 | agent.firstname = "testfirstname"; | ||
56 | agent.lastname = "testlastname"; | ||
57 | agent.SessionID = UUID.Zero; | ||
58 | agent.SecureSessionID = UUID.Zero; | ||
59 | agent.circuitcode = 123; | ||
60 | agent.BaseFolder = UUID.Zero; | ||
61 | agent.InventoryFolder = UUID.Zero; | ||
62 | agent.startpos = Vector3.Zero; | ||
63 | agent.CapsPath = "http://wibble.com"; | ||
64 | client = new TestClient(agent, null); | ||
65 | ts = new TextureSender(client, 0, 0); | ||
66 | testsize = random.Next(5000,15000); | ||
67 | npackets = CalculateNumPackets(testsize); | ||
68 | uuid1 = UUID.Random(); | ||
69 | uuid2 = UUID.Random(); | ||
70 | uuid3 = UUID.Random(); | ||
71 | uuid4 = UUID.Random(); | ||
72 | } | ||
73 | |||
74 | /// <summary> | ||
75 | /// Test sending package | ||
76 | /// </summary> | ||
77 | [Test] | ||
78 | public void T010_SendPkg() | ||
79 | { | ||
80 | TestHelper.InMethod(); | ||
81 | // Normal sending | ||
82 | AssetBase abase = new AssetBase(uuid1, "asset one"); | ||
83 | byte[] abdata = new byte[testsize]; | ||
84 | random.NextBytes(abdata); | ||
85 | abase.Data = abdata; | ||
86 | bool isdone = false; | ||
87 | ts.TextureReceived(abase); | ||
88 | for (int i = 0; i < npackets; i++) { | ||
89 | isdone = ts.SendTexturePacket(); | ||
90 | } | ||
91 | |||
92 | Assert.That(isdone,Is.False); | ||
93 | isdone = ts.SendTexturePacket(); | ||
94 | Assert.That(isdone,Is.True); | ||
95 | } | ||
96 | |||
97 | [Test] | ||
98 | public void T011_UpdateReq() | ||
99 | { | ||
100 | TestHelper.InMethod(); | ||
101 | // Test packet number start | ||
102 | AssetBase abase = new AssetBase(uuid2, "asset two"); | ||
103 | byte[] abdata = new byte[testsize]; | ||
104 | random.NextBytes(abdata); | ||
105 | abase.Data = abdata; | ||
106 | |||
107 | bool isdone = false; | ||
108 | ts.TextureReceived(abase); | ||
109 | ts.UpdateRequest(0,3); | ||
110 | |||
111 | for (int i = 0; i < npackets-3; i++) { | ||
112 | isdone = ts.SendTexturePacket(); | ||
113 | } | ||
114 | |||
115 | Assert.That(isdone,Is.False); | ||
116 | isdone = ts.SendTexturePacket(); | ||
117 | Assert.That(isdone,Is.True); | ||
118 | |||
119 | // Test discard level | ||
120 | abase = new AssetBase(uuid3, "asset three"); | ||
121 | abdata = new byte[testsize]; | ||
122 | random.NextBytes(abdata); | ||
123 | abase.Data = abdata; | ||
124 | isdone = false; | ||
125 | ts.TextureReceived(abase); | ||
126 | ts.UpdateRequest(-1,0); | ||
127 | |||
128 | Assert.That(ts.SendTexturePacket(),Is.True); | ||
129 | |||
130 | abase = new AssetBase(uuid4, "asset four"); | ||
131 | abdata = new byte[testsize]; | ||
132 | random.NextBytes(abdata); | ||
133 | abase.Data = abdata; | ||
134 | isdone = false; | ||
135 | ts.TextureReceived(abase); | ||
136 | ts.UpdateRequest(0,5); | ||
137 | |||
138 | for (int i = 0; i < npackets-5; i++) { | ||
139 | isdone = ts.SendTexturePacket(); | ||
140 | } | ||
141 | Assert.That(isdone,Is.False); | ||
142 | isdone = ts.SendTexturePacket(); | ||
143 | Assert.That(isdone,Is.True); | ||
144 | } | ||
145 | |||
146 | [Test] | ||
147 | public void T999_FinishStatus() | ||
148 | { | ||
149 | TestHelper.InMethod(); | ||
150 | // Of the 4 assets "sent", only 2 sent the first part. | ||
151 | Assert.That(client.sentdatapkt.Count,Is.EqualTo(2)); | ||
152 | |||
153 | // Sum of all packets sent: | ||
154 | int totalpkts = (npackets) + (npackets - 2) + (npackets - 4); | ||
155 | Assert.That(client.sentpktpkt.Count,Is.EqualTo(totalpkts)); | ||
156 | } | ||
157 | |||
158 | /// <summary> | ||
159 | /// Calculate the number of packets that will be required to send the texture loaded into this sender | ||
160 | /// This is actually the number of 1000 byte packets not including an initial 600 byte packet... | ||
161 | /// Borrowed from TextureSender.cs | ||
162 | /// </summary> | ||
163 | /// <param name="length"></param> | ||
164 | /// <returns></returns> | ||
165 | private int CalculateNumPackets(int length) | ||
166 | { | ||
167 | int numPackets = 0; | ||
168 | |||
169 | if (length > 600) | ||
170 | { | ||
171 | //over 600 bytes so split up file | ||
172 | int restData = (length - 600); | ||
173 | int restPackets = ((restData + 999) / 1000); | ||
174 | numPackets = restPackets; | ||
175 | } | ||
176 | |||
177 | return numPackets; | ||
178 | } | ||
179 | } | ||
180 | } | ||
diff --git a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs index 66ca7c2..1add0ab 100644 --- a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs | |||
@@ -155,14 +155,6 @@ namespace OpenSim.Region.CoreModules.Asset | |||
155 | private int m_hitCount; | 155 | private int m_hitCount; |
156 | 156 | ||
157 | /// <summary> | 157 | /// <summary> |
158 | /// Initialize asset cache module with default parameters. | ||
159 | /// </summary> | ||
160 | public void Initialize() | ||
161 | { | ||
162 | Initialize(DefaultMaxSize, DefaultMaxCount, DefaultExpirationTime); | ||
163 | } | ||
164 | |||
165 | /// <summary> | ||
166 | /// Initialize asset cache module, with custom parameters. | 158 | /// Initialize asset cache module, with custom parameters. |
167 | /// </summary> | 159 | /// </summary> |
168 | /// <param name="maximalSize"> | 160 | /// <param name="maximalSize"> |
@@ -174,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
174 | /// <param name="expirationTime"> | 166 | /// <param name="expirationTime"> |
175 | /// Asset's expiration time. | 167 | /// Asset's expiration time. |
176 | /// </param> | 168 | /// </param> |
177 | public void Initialize(long maximalSize, int maximalCount, TimeSpan expirationTime) | 169 | protected void Initialize(long maximalSize, int maximalCount, TimeSpan expirationTime) |
178 | { | 170 | { |
179 | if (maximalSize <= 0 || maximalCount <= 0) | 171 | if (maximalSize <= 0 || maximalCount <= 0) |
180 | { | 172 | { |
diff --git a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs index 0a7e736..7da5e7a 100644 --- a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs | |||
@@ -44,10 +44,8 @@ namespace OpenSim.Region.CoreModules.Asset | |||
44 | LogManager.GetLogger( | 44 | LogManager.GetLogger( |
45 | MethodBase.GetCurrentMethod().DeclaringType); | 45 | MethodBase.GetCurrentMethod().DeclaringType); |
46 | 46 | ||
47 | private bool m_Enabled = false; | 47 | private bool m_Enabled; |
48 | private Cache m_Cache = new Cache(CacheMedium.Memory, | 48 | private Cache m_Cache; |
49 | CacheStrategy.Aggressive, | ||
50 | CacheFlags.AllowUpdate); | ||
51 | 49 | ||
52 | public string Name | 50 | public string Name |
53 | { | 51 | { |
@@ -77,6 +75,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
77 | return; | 75 | return; |
78 | } | 76 | } |
79 | 77 | ||
78 | m_Cache = new Cache(CacheMedium.Memory, CacheStrategy.Aggressive, CacheFlags.AllowUpdate); | ||
80 | m_Enabled = true; | 79 | m_Enabled = true; |
81 | 80 | ||
82 | m_log.Info("[ASSET CACHE]: Core asset cache enabled"); | 81 | m_log.Info("[ASSET CACHE]: Core asset cache enabled"); |
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 5ca4178..c6af806 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | |||
@@ -61,24 +61,23 @@ namespace Flotsam.RegionModules.AssetCache | |||
61 | LogManager.GetLogger( | 61 | LogManager.GetLogger( |
62 | MethodBase.GetCurrentMethod().DeclaringType); | 62 | MethodBase.GetCurrentMethod().DeclaringType); |
63 | 63 | ||
64 | private bool m_Enabled = false; | 64 | private bool m_Enabled; |
65 | 65 | ||
66 | private const string m_ModuleName = "FlotsamAssetCache"; | 66 | private const string m_ModuleName = "FlotsamAssetCache"; |
67 | private const string m_DefaultCacheDirectory = m_ModuleName; | 67 | private const string m_DefaultCacheDirectory = m_ModuleName; |
68 | private string m_CacheDirectory = m_DefaultCacheDirectory; | 68 | private string m_CacheDirectory = m_DefaultCacheDirectory; |
69 | 69 | ||
70 | 70 | private readonly List<char> m_InvalidChars = new List<char>(); | |
71 | private List<char> m_InvalidChars = new List<char>(); | ||
72 | 71 | ||
73 | private int m_LogLevel = 1; | 72 | private int m_LogLevel = 1; |
74 | private ulong m_HitRateDisplay = 1; // How often to display hit statistics, given in requests | 73 | private ulong m_HitRateDisplay = 1; // How often to display hit statistics, given in requests |
75 | 74 | ||
76 | private static ulong m_Requests = 0; | 75 | private static ulong m_Requests; |
77 | private static ulong m_RequestsForInprogress = 0; | 76 | private static ulong m_RequestsForInprogress; |
78 | private static ulong m_DiskHits = 0; | 77 | private static ulong m_DiskHits; |
79 | private static ulong m_MemoryHits = 0; | 78 | private static ulong m_MemoryHits; |
80 | private static double m_HitRateMemory = 0.0; | 79 | private static double m_HitRateMemory; |
81 | private static double m_HitRateFile = 0.0; | 80 | private static double m_HitRateFile; |
82 | 81 | ||
83 | #if WAIT_ON_INPROGRESS_REQUESTS | 82 | #if WAIT_ON_INPROGRESS_REQUESTS |
84 | private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); | 83 | private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); |
@@ -87,7 +86,7 @@ namespace Flotsam.RegionModules.AssetCache | |||
87 | private List<string> m_CurrentlyWriting = new List<string>(); | 86 | private List<string> m_CurrentlyWriting = new List<string>(); |
88 | #endif | 87 | #endif |
89 | 88 | ||
90 | private ExpiringCache<string, AssetBase> m_MemoryCache = new ExpiringCache<string, AssetBase>(); | 89 | private ExpiringCache<string, AssetBase> m_MemoryCache; |
91 | private bool m_MemoryCacheEnabled = true; | 90 | private bool m_MemoryCacheEnabled = true; |
92 | 91 | ||
93 | // Expiration is expressed in hours. | 92 | // Expiration is expressed in hours. |
@@ -101,12 +100,12 @@ namespace Flotsam.RegionModules.AssetCache | |||
101 | private static int m_CacheDirectoryTierLen = 3; | 100 | private static int m_CacheDirectoryTierLen = 3; |
102 | private static int m_CacheWarnAt = 30000; | 101 | private static int m_CacheWarnAt = 30000; |
103 | 102 | ||
104 | private System.Timers.Timer m_CachCleanTimer = new System.Timers.Timer(); | 103 | private System.Timers.Timer m_CacheCleanTimer; |
105 | 104 | ||
106 | private IAssetService m_AssetService = null; | 105 | private IAssetService m_AssetService; |
107 | private List<Scene> m_Scenes = new List<Scene>(); | 106 | private List<Scene> m_Scenes = new List<Scene>(); |
108 | 107 | ||
109 | private bool m_DeepScanBeforePurge = false; | 108 | private bool m_DeepScanBeforePurge; |
110 | 109 | ||
111 | public FlotsamAssetCache() | 110 | public FlotsamAssetCache() |
112 | { | 111 | { |
@@ -128,14 +127,15 @@ namespace Flotsam.RegionModules.AssetCache | |||
128 | { | 127 | { |
129 | IConfig moduleConfig = source.Configs["Modules"]; | 128 | IConfig moduleConfig = source.Configs["Modules"]; |
130 | 129 | ||
131 | |||
132 | if (moduleConfig != null) | 130 | if (moduleConfig != null) |
133 | { | 131 | { |
134 | string name = moduleConfig.GetString("AssetCaching", ""); | 132 | string name = moduleConfig.GetString("AssetCaching", String.Empty); |
135 | 133 | ||
136 | if (name == Name) | 134 | if (name == Name) |
137 | { | 135 | { |
136 | m_MemoryCache = new ExpiringCache<string, AssetBase>(); | ||
138 | m_Enabled = true; | 137 | m_Enabled = true; |
138 | |||
139 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} enabled", this.Name); | 139 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} enabled", this.Name); |
140 | 140 | ||
141 | IConfig assetConfig = source.Configs["AssetCache"]; | 141 | IConfig assetConfig = source.Configs["AssetCache"]; |
@@ -163,21 +163,11 @@ namespace Flotsam.RegionModules.AssetCache | |||
163 | m_FileExpirationCleanupTimer = TimeSpan.FromHours(assetConfig.GetDouble("FileCleanupTimer", m_DefaultFileExpiration)); | 163 | m_FileExpirationCleanupTimer = TimeSpan.FromHours(assetConfig.GetDouble("FileCleanupTimer", m_DefaultFileExpiration)); |
164 | if ((m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero)) | 164 | if ((m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero)) |
165 | { | 165 | { |
166 | m_CachCleanTimer.Interval = m_FileExpirationCleanupTimer.TotalMilliseconds; | 166 | m_CacheCleanTimer = new System.Timers.Timer(m_FileExpirationCleanupTimer.TotalMilliseconds); |
167 | m_CachCleanTimer.AutoReset = true; | 167 | m_CacheCleanTimer.AutoReset = true; |
168 | m_CachCleanTimer.Elapsed += CleanupExpiredFiles; | 168 | m_CacheCleanTimer.Elapsed += CleanupExpiredFiles; |
169 | m_CachCleanTimer.Enabled = true; | 169 | lock (m_CacheCleanTimer) |
170 | lock (m_CachCleanTimer) | 170 | m_CacheCleanTimer.Start(); |
171 | { | ||
172 | m_CachCleanTimer.Start(); | ||
173 | } | ||
174 | } | ||
175 | else | ||
176 | { | ||
177 | lock (m_CachCleanTimer) | ||
178 | { | ||
179 | m_CachCleanTimer.Enabled = false; | ||
180 | } | ||
181 | } | 171 | } |
182 | 172 | ||
183 | m_CacheDirectoryTiers = assetConfig.GetInt("CacheDirectoryTiers", 1); | 173 | m_CacheDirectoryTiers = assetConfig.GetInt("CacheDirectoryTiers", 1); |
@@ -208,7 +198,6 @@ namespace Flotsam.RegionModules.AssetCache | |||
208 | MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the file and/or memory cache", HandleConsoleCommand); | 198 | MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the file and/or memory cache", HandleConsoleCommand); |
209 | MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand); | 199 | MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand); |
210 | MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand); | 200 | MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand); |
211 | |||
212 | } | 201 | } |
213 | } | 202 | } |
214 | } | 203 | } |
@@ -313,12 +302,8 @@ namespace Flotsam.RegionModules.AssetCache | |||
313 | 302 | ||
314 | } | 303 | } |
315 | 304 | ||
316 | ThreadPool.QueueUserWorkItem( | 305 | Util.FireAndForget( |
317 | delegate | 306 | delegate { WriteFileCache(filename, asset); }); |
318 | { | ||
319 | WriteFileCache(filename, asset); | ||
320 | } | ||
321 | ); | ||
322 | } | 307 | } |
323 | } | 308 | } |
324 | catch (Exception e) | 309 | catch (Exception e) |
diff --git a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs index 4869f5d..1365e69 100644 --- a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs | |||
@@ -45,11 +45,13 @@ namespace OpenSim.Region.CoreModules.Asset | |||
45 | LogManager.GetLogger( | 45 | LogManager.GetLogger( |
46 | MethodBase.GetCurrentMethod().DeclaringType); | 46 | MethodBase.GetCurrentMethod().DeclaringType); |
47 | 47 | ||
48 | private bool m_Enabled = false; | 48 | private bool m_Enabled; |
49 | private ICache m_Cache = new GlynnTucker.Cache.SimpleMemoryCache(); | 49 | private ICache m_Cache; |
50 | private ulong m_Hits; | ||
51 | private ulong m_Requests; | ||
50 | 52 | ||
51 | // Instrumentation | 53 | // Instrumentation |
52 | private uint m_DebugRate = 0; | 54 | private uint m_DebugRate; |
53 | 55 | ||
54 | public Type ReplaceableInterface | 56 | public Type ReplaceableInterface |
55 | { | 57 | { |
@@ -72,6 +74,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
72 | 74 | ||
73 | if (name == Name) | 75 | if (name == Name) |
74 | { | 76 | { |
77 | m_Cache = new GlynnTucker.Cache.SimpleMemoryCache(); | ||
75 | m_Enabled = true; | 78 | m_Enabled = true; |
76 | 79 | ||
77 | m_log.Info("[ASSET CACHE]: GlynnTucker asset cache enabled"); | 80 | m_log.Info("[ASSET CACHE]: GlynnTucker asset cache enabled"); |
@@ -80,7 +83,6 @@ namespace OpenSim.Region.CoreModules.Asset | |||
80 | IConfig cacheConfig = source.Configs["AssetCache"]; | 83 | IConfig cacheConfig = source.Configs["AssetCache"]; |
81 | if (cacheConfig != null) | 84 | if (cacheConfig != null) |
82 | m_DebugRate = (uint)cacheConfig.GetInt("DebugRate", 0); | 85 | m_DebugRate = (uint)cacheConfig.GetInt("DebugRate", 0); |
83 | |||
84 | } | 86 | } |
85 | } | 87 | } |
86 | } | 88 | } |
@@ -117,24 +119,6 @@ namespace OpenSim.Region.CoreModules.Asset | |||
117 | m_Cache.AddOrUpdate(asset.ID, asset); | 119 | m_Cache.AddOrUpdate(asset.ID, asset); |
118 | } | 120 | } |
119 | 121 | ||
120 | private ulong m_Hits = 0; | ||
121 | private ulong m_Requests = 0; | ||
122 | private void Debug(Object asset) | ||
123 | { | ||
124 | // Temporary instrumentation to measure the hit/miss rate | ||
125 | if (m_DebugRate > 0) | ||
126 | { | ||
127 | m_Requests++; | ||
128 | if (asset != null) | ||
129 | m_Hits++; | ||
130 | |||
131 | if ((m_Requests % m_DebugRate) == 0) | ||
132 | m_log.DebugFormat("[ASSET CACHE]: Hit Rate {0} / {1} == {2}%", m_Hits, m_Requests, ((float)m_Hits / m_Requests) * 100); | ||
133 | |||
134 | } | ||
135 | // End instrumentation | ||
136 | } | ||
137 | |||
138 | public AssetBase Get(string id) | 122 | public AssetBase Get(string id) |
139 | { | 123 | { |
140 | Object asset = null; | 124 | Object asset = null; |
@@ -156,5 +140,20 @@ namespace OpenSim.Region.CoreModules.Asset | |||
156 | { | 140 | { |
157 | m_Cache.Clear(); | 141 | m_Cache.Clear(); |
158 | } | 142 | } |
143 | |||
144 | private void Debug(Object asset) | ||
145 | { | ||
146 | // Temporary instrumentation to measure the hit/miss rate | ||
147 | if (m_DebugRate > 0) | ||
148 | { | ||
149 | ++m_Requests; | ||
150 | if (asset != null) | ||
151 | ++m_Hits; | ||
152 | |||
153 | if ((m_Requests % m_DebugRate) == 0) | ||
154 | m_log.DebugFormat("[ASSET CACHE]: Hit Rate {0} / {1} == {2}%", m_Hits, m_Requests, ((float)m_Hits / (float)m_Requests) * 100.0f); | ||
155 | } | ||
156 | // End instrumentation | ||
157 | } | ||
159 | } | 158 | } |
160 | } | 159 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 66a9b5a..cd59bdb 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | |||
@@ -224,11 +224,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
224 | 224 | ||
225 | foreach (Scene s in m_scenes) | 225 | foreach (Scene s in m_scenes) |
226 | { | 226 | { |
227 | s.ForEachScenePresence(delegate(ScenePresence presence) | 227 | s.ForEachScenePresence( |
228 | { | 228 | delegate(ScenePresence presence) |
229 | TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, | 229 | { |
230 | c.Type, message, sourceType); | 230 | TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType); |
231 | }); | 231 | } |
232 | ); | ||
232 | } | 233 | } |
233 | } | 234 | } |
234 | 235 | ||
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 4896edf..3bb162e 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -756,7 +756,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
756 | 756 | ||
757 | public void sendRegionHandshakeToAll() | 757 | public void sendRegionHandshakeToAll() |
758 | { | 758 | { |
759 | m_scene.Broadcast(sendRegionHandshake); | 759 | m_scene.ForEachClient(sendRegionHandshake); |
760 | } | 760 | } |
761 | 761 | ||
762 | public void handleEstateChangeInfo(IClientAPI remoteClient, UUID invoice, UUID senderID, UInt32 parms1, UInt32 parms2) | 762 | public void handleEstateChangeInfo(IClientAPI remoteClient, UUID invoice, UUID senderID, UInt32 parms1, UInt32 parms2) |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index d2b5cb1..53c64cb 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -147,9 +147,10 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
147 | client.OnParcelDwellRequest += ClientOnParcelDwellRequest; | 147 | client.OnParcelDwellRequest += ClientOnParcelDwellRequest; |
148 | client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; | 148 | client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; |
149 | 149 | ||
150 | if (m_scene.Entities.ContainsKey(client.AgentId)) | 150 | EntityBase presenceEntity; |
151 | if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) | ||
151 | { | 152 | { |
152 | SendLandUpdate((ScenePresence)m_scene.Entities[client.AgentId], true); | 153 | SendLandUpdate((ScenePresence)presenceEntity, true); |
153 | SendParcelOverlay(client); | 154 | SendParcelOverlay(client); |
154 | } | 155 | } |
155 | } | 156 | } |
@@ -1061,7 +1062,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1061 | { | 1062 | { |
1062 | land.LandData.OwnerID = ownerID; | 1063 | land.LandData.OwnerID = ownerID; |
1063 | 1064 | ||
1064 | m_scene.Broadcast(SendParcelOverlay); | 1065 | m_scene.ForEachClient(SendParcelOverlay); |
1065 | land.SendLandUpdateToClient(remote_client); | 1066 | land.SendLandUpdateToClient(remote_client); |
1066 | } | 1067 | } |
1067 | } | 1068 | } |
@@ -1083,7 +1084,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1083 | land.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 1084 | land.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
1084 | else | 1085 | else |
1085 | land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; | 1086 | land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; |
1086 | m_scene.Broadcast(SendParcelOverlay); | 1087 | m_scene.ForEachClient(SendParcelOverlay); |
1087 | land.SendLandUpdateToClient(remote_client); | 1088 | land.SendLandUpdateToClient(remote_client); |
1088 | } | 1089 | } |
1089 | } | 1090 | } |
@@ -1107,7 +1108,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1107 | land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; | 1108 | land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; |
1108 | land.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); | 1109 | land.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); |
1109 | land.LandData.IsGroupOwned = false; | 1110 | land.LandData.IsGroupOwned = false; |
1110 | m_scene.Broadcast(SendParcelOverlay); | 1111 | m_scene.ForEachClient(SendParcelOverlay); |
1111 | land.SendLandUpdateToClient(remote_client); | 1112 | land.SendLandUpdateToClient(remote_client); |
1112 | } | 1113 | } |
1113 | } | 1114 | } |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index b9b7da5..bfe85f1 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs | |||
@@ -139,10 +139,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
139 | } | 139 | } |
140 | else | 140 | else |
141 | { | 141 | { |
142 | //Normal Calculations | 142 | // Normal Calculations |
143 | return Convert.ToInt32( | 143 | return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.objectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); |
144 | Math.Round((Convert.ToDecimal(LandData.Area) / Convert.ToDecimal(65536)) * m_scene.objectCapacity * | ||
145 | Convert.ToDecimal(m_scene.RegionInfo.RegionSettings.ObjectBonus))); ; | ||
146 | } | 144 | } |
147 | } | 145 | } |
148 | public int GetSimulatorMaxPrimCount(ILandObject thisObject) | 146 | public int GetSimulatorMaxPrimCount(ILandObject thisObject) |
diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs b/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs index 6499915..d8c5ed9 100644 --- a/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs | |||
@@ -81,8 +81,12 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
81 | 81 | ||
82 | public void RegionLoaded(Scene scene) | 82 | public void RegionLoaded(Scene scene) |
83 | { | 83 | { |
84 | if (!enabledYN) | 84 | if (enabledYN) |
85 | return; | 85 | RegionLoadedDoWork(scene); |
86 | } | ||
87 | |||
88 | private void RegionLoadedDoWork(Scene scene) | ||
89 | { | ||
86 | /* | 90 | /* |
87 | // For testing on a single instance | 91 | // For testing on a single instance |
88 | if (scene.RegionInfo.RegionLocX == 1004 && scene.RegionInfo.RegionLocY == 1000) | 92 | if (scene.RegionInfo.RegionLocX == 1004 && scene.RegionInfo.RegionLocY == 1000) |
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 4fb4c51..4e40084 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -1095,7 +1095,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1095 | // The reason is so we don't cause the thread to freeze waiting | 1095 | // The reason is so we don't cause the thread to freeze waiting |
1096 | // for the 1 second it costs to start a thread manually. | 1096 | // for the 1 second it costs to start a thread manually. |
1097 | if (!threadrunning) | 1097 | if (!threadrunning) |
1098 | ThreadPool.QueueUserWorkItem(new WaitCallback(this.StartThread)); | 1098 | Util.FireAndForget(this.StartThread); |
1099 | 1099 | ||
1100 | lock (m_rootAgents) | 1100 | lock (m_rootAgents) |
1101 | { | 1101 | { |
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index d651fd4..5a5fcfe 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | |||
@@ -499,13 +499,11 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
499 | { | 499 | { |
500 | } | 500 | } |
501 | 501 | ||
502 | public virtual void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, | 502 | public virtual void SendAvatarData(SendAvatarData data) |
503 | uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation) | ||
504 | { | 503 | { |
505 | } | 504 | } |
506 | 505 | ||
507 | public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, | 506 | public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) |
508 | Vector3 position, Vector3 velocity, Quaternion rotation, UUID agentid) | ||
509 | { | 507 | { |
510 | } | 508 | } |
511 | 509 | ||
@@ -521,27 +519,15 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
521 | { | 519 | { |
522 | } | 520 | } |
523 | 521 | ||
524 | public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, | 522 | public virtual void SendPrimitiveToClient(SendPrimitiveData data) |
525 | PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, | ||
526 | Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, | ||
527 | UUID objectID, UUID ownerID, string text, byte[] color, | ||
528 | uint parentID, | ||
529 | byte[] particleSystem, byte clickAction, byte material) | ||
530 | { | 523 | { |
531 | } | 524 | } |
532 | public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, | 525 | |
533 | PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, | 526 | public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) |
534 | Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, | ||
535 | UUID objectID, UUID ownerID, string text, byte[] color, | ||
536 | uint parentID, | ||
537 | byte[] particleSystem, byte clickAction, byte material, byte[] textureanimation, | ||
538 | bool attachment, uint AttachmentPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius) | ||
539 | { | 527 | { |
540 | } | 528 | } |
541 | public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, | 529 | |
542 | Vector3 position, Quaternion rotation, Vector3 velocity, | 530 | public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) |
543 | Vector3 rotationalvelocity, byte state, UUID AssetId, | ||
544 | UUID ownerID, int attachPoint) | ||
545 | { | 531 | { |
546 | } | 532 | } |
547 | 533 | ||
diff --git a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs index 8e3f4a0..7251d57 100644 --- a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs +++ b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs | |||
@@ -34,7 +34,6 @@ namespace OpenSim.Region.Framework.Interfaces | |||
34 | { | 34 | { |
35 | void Reset(); | 35 | void Reset(); |
36 | void Close(); | 36 | void Close(); |
37 | int MaxPrimsPerFrame { get; set; } | ||
38 | void QueuePartForUpdate(SceneObjectPart part); | 37 | void QueuePartForUpdate(SceneObjectPart part); |
39 | void SendPrimUpdates(); | 38 | void SendPrimUpdates(); |
40 | } | 39 | } |
diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs index 0ceef39..099fcce 100644 --- a/OpenSim/Region/Framework/Scenes/EntityManager.cs +++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs | |||
@@ -93,40 +93,31 @@ namespace OpenSim.Region.Framework.Scenes | |||
93 | { | 93 | { |
94 | get | 94 | get |
95 | { | 95 | { |
96 | lock (m_lock) | 96 | return m_eb_uuid.Count; |
97 | { | ||
98 | return m_eb_uuid.Count; | ||
99 | } | ||
100 | } | 97 | } |
101 | } | 98 | } |
102 | 99 | ||
103 | public bool ContainsKey(UUID id) | 100 | public bool ContainsKey(UUID id) |
104 | { | 101 | { |
105 | lock (m_lock) | 102 | try |
106 | { | 103 | { |
107 | try | 104 | return m_eb_uuid.ContainsKey(id); |
108 | { | 105 | } |
109 | return m_eb_uuid.ContainsKey(id); | 106 | catch |
110 | } | 107 | { |
111 | catch | 108 | return false; |
112 | { | ||
113 | return false; | ||
114 | } | ||
115 | } | 109 | } |
116 | } | 110 | } |
117 | 111 | ||
118 | public bool ContainsKey(uint localID) | 112 | public bool ContainsKey(uint localID) |
119 | { | 113 | { |
120 | lock (m_lock) | 114 | try |
121 | { | 115 | { |
122 | try | 116 | return m_eb_localID.ContainsKey(localID); |
123 | { | 117 | } |
124 | return m_eb_localID.ContainsKey(localID); | 118 | catch |
125 | } | 119 | { |
126 | catch | 120 | return false; |
127 | { | ||
128 | return false; | ||
129 | } | ||
130 | } | 121 | } |
131 | } | 122 | } |
132 | 123 | ||
@@ -136,7 +127,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
136 | { | 127 | { |
137 | try | 128 | try |
138 | { | 129 | { |
139 | bool a = m_eb_uuid.Remove(m_eb_localID[localID].UUID); | 130 | bool a = false; |
131 | EntityBase entity; | ||
132 | if (m_eb_localID.TryGetValue(localID, out entity)) | ||
133 | a = m_eb_uuid.Remove(entity.UUID); | ||
134 | |||
140 | bool b = m_eb_localID.Remove(localID); | 135 | bool b = m_eb_localID.Remove(localID); |
141 | return a && b; | 136 | return a && b; |
142 | } | 137 | } |
@@ -154,7 +149,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
154 | { | 149 | { |
155 | try | 150 | try |
156 | { | 151 | { |
157 | bool a = m_eb_localID.Remove(m_eb_uuid[id].LocalId); | 152 | bool a = false; |
153 | EntityBase entity; | ||
154 | if (m_eb_uuid.TryGetValue(id, out entity)) | ||
155 | a = m_eb_localID.Remove(entity.LocalId); | ||
156 | |||
158 | bool b = m_eb_uuid.Remove(id); | 157 | bool b = m_eb_uuid.Remove(id); |
159 | return a && b; | 158 | return a && b; |
160 | } | 159 | } |
@@ -206,14 +205,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
206 | { | 205 | { |
207 | lock (m_lock) | 206 | lock (m_lock) |
208 | { | 207 | { |
209 | try | 208 | EntityBase entity; |
210 | { | 209 | if (m_eb_uuid.TryGetValue(id, out entity)) |
211 | return m_eb_uuid[id]; | 210 | return entity; |
212 | } | 211 | else |
213 | catch | ||
214 | { | ||
215 | return null; | 212 | return null; |
216 | } | ||
217 | } | 213 | } |
218 | } | 214 | } |
219 | set | 215 | set |
@@ -228,14 +224,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
228 | { | 224 | { |
229 | lock (m_lock) | 225 | lock (m_lock) |
230 | { | 226 | { |
231 | try | 227 | EntityBase entity; |
232 | { | 228 | if (m_eb_localID.TryGetValue(localID, out entity)) |
233 | return m_eb_localID[localID]; | 229 | return entity; |
234 | } | 230 | else |
235 | catch | ||
236 | { | ||
237 | return null; | 231 | return null; |
238 | } | ||
239 | } | 232 | } |
240 | } | 233 | } |
241 | set | 234 | set |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 627034a..4d76b4ef 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -2351,12 +2351,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2351 | item = InventoryService.GetItem(item); | 2351 | item = InventoryService.GetItem(item); |
2352 | 2352 | ||
2353 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); | 2353 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); |
2354 | IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>(); | ||
2355 | if (ava != null) | ||
2356 | { | ||
2357 | ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | ||
2358 | } | ||
2359 | |||
2360 | } | 2354 | } |
2361 | return att.UUID; | 2355 | return att.UUID; |
2362 | } | 2356 | } |
@@ -2402,12 +2396,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2402 | InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); | 2396 | InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); |
2403 | item = InventoryService.GetItem(item); | 2397 | item = InventoryService.GetItem(item); |
2404 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); | 2398 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); |
2405 | |||
2406 | if (m_AvatarFactory != null) | ||
2407 | { | ||
2408 | m_log.InfoFormat("[SCENE INVENTORY]: Saving avatar attachment. AgentID:{0} ItemID:{1} AttachmentPoint:{2}", remoteClient.AgentId, itemID, AttachmentPt); | ||
2409 | m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | ||
2410 | } | ||
2411 | } | 2399 | } |
2412 | } | 2400 | } |
2413 | 2401 | ||
@@ -2447,12 +2435,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2447 | if (TryGetAvatar(remoteClient.AgentId, out presence)) | 2435 | if (TryGetAvatar(remoteClient.AgentId, out presence)) |
2448 | { | 2436 | { |
2449 | presence.Appearance.DetachAttachment(itemID); | 2437 | presence.Appearance.DetachAttachment(itemID); |
2450 | IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>(); | 2438 | |
2451 | if (ava != null) | 2439 | // Save avatar attachment information |
2440 | if (m_AvatarFactory != null) | ||
2452 | { | 2441 | { |
2453 | ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | 2442 | m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", ItemID: " + itemID); |
2443 | m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | ||
2454 | } | 2444 | } |
2455 | |||
2456 | } | 2445 | } |
2457 | 2446 | ||
2458 | m_sceneGraph.DetachSingleAttachmentToInv(itemID, remoteClient); | 2447 | m_sceneGraph.DetachSingleAttachmentToInv(itemID, remoteClient); |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index cc74f26..5005ac9 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -57,6 +57,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
57 | 57 | ||
58 | public partial class Scene : SceneBase | 58 | public partial class Scene : SceneBase |
59 | { | 59 | { |
60 | public enum UpdatePrioritizationSchemes { | ||
61 | Time = 0, | ||
62 | Distance = 1, | ||
63 | SimpleAngularDistance = 2, | ||
64 | } | ||
65 | |||
60 | public delegate void SynchronizeSceneHandler(Scene scene); | 66 | public delegate void SynchronizeSceneHandler(Scene scene); |
61 | public SynchronizeSceneHandler SynchronizeScene = null; | 67 | public SynchronizeSceneHandler SynchronizeScene = null; |
62 | 68 | ||
@@ -222,6 +228,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
222 | protected IXMLRPC m_xmlrpcModule; | 228 | protected IXMLRPC m_xmlrpcModule; |
223 | protected IWorldComm m_worldCommModule; | 229 | protected IWorldComm m_worldCommModule; |
224 | protected IAvatarFactory m_AvatarFactory; | 230 | protected IAvatarFactory m_AvatarFactory; |
231 | public IAvatarFactory AvatarFactory | ||
232 | { | ||
233 | get { return m_AvatarFactory; } | ||
234 | } | ||
225 | protected IConfigSource m_config; | 235 | protected IConfigSource m_config; |
226 | protected IRegionSerialiserModule m_serialiser; | 236 | protected IRegionSerialiserModule m_serialiser; |
227 | protected IInterregionCommsOut m_interregionCommsOut; | 237 | protected IInterregionCommsOut m_interregionCommsOut; |
@@ -269,9 +279,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
269 | private volatile bool shuttingdown = false; | 279 | private volatile bool shuttingdown = false; |
270 | 280 | ||
271 | private int m_lastUpdate = Environment.TickCount; | 281 | private int m_lastUpdate = Environment.TickCount; |
272 | private int m_maxPrimsPerFrame = 200; | ||
273 | private bool m_firstHeartbeat = true; | 282 | private bool m_firstHeartbeat = true; |
274 | 283 | ||
284 | private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; | ||
285 | private bool m_reprioritization_enabled = true; | ||
286 | private double m_reprioritization_interval = 2000.0; | ||
287 | private double m_root_reprioritization_distance = 5.0; | ||
288 | private double m_child_reprioritization_distance = 10.0; | ||
289 | |||
275 | private object m_deleting_scene_object = new object(); | 290 | private object m_deleting_scene_object = new object(); |
276 | 291 | ||
277 | // the minimum time that must elapse before a changed object will be considered for persisted | 292 | // the minimum time that must elapse before a changed object will be considered for persisted |
@@ -283,6 +298,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
283 | 298 | ||
284 | #region Properties | 299 | #region Properties |
285 | 300 | ||
301 | public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } } | ||
302 | public bool IsReprioritizationEnabled { get { return m_reprioritization_enabled; } } | ||
303 | public double ReprioritizationInterval { get { return m_reprioritization_interval; } } | ||
304 | public double RootReprioritizationDistance { get { return m_root_reprioritization_distance; } } | ||
305 | public double ChildReprioritizationDistance { get { return m_child_reprioritization_distance; } } | ||
306 | |||
286 | public AgentCircuitManager AuthenticateHandler | 307 | public AgentCircuitManager AuthenticateHandler |
287 | { | 308 | { |
288 | get { return m_authenticateHandler; } | 309 | get { return m_authenticateHandler; } |
@@ -327,12 +348,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
327 | get { return m_sceneGraph.m_syncRoot; } | 348 | get { return m_sceneGraph.m_syncRoot; } |
328 | } | 349 | } |
329 | 350 | ||
330 | public int MaxPrimsPerFrame | ||
331 | { | ||
332 | get { return m_maxPrimsPerFrame; } | ||
333 | set { m_maxPrimsPerFrame = value; } | ||
334 | } | ||
335 | |||
336 | /// <summary> | 351 | /// <summary> |
337 | /// This is for llGetRegionFPS | 352 | /// This is for llGetRegionFPS |
338 | /// </summary> | 353 | /// </summary> |
@@ -346,13 +361,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
346 | get { return m_defaultScriptEngine; } | 361 | get { return m_defaultScriptEngine; } |
347 | } | 362 | } |
348 | 363 | ||
349 | // Reference to all of the agents in the scene (root and child) | ||
350 | protected Dictionary<UUID, ScenePresence> m_scenePresences | ||
351 | { | ||
352 | get { return m_sceneGraph.ScenePresences; } | ||
353 | set { m_sceneGraph.ScenePresences = value; } | ||
354 | } | ||
355 | |||
356 | public EntityManager Entities | 364 | public EntityManager Entities |
357 | { | 365 | { |
358 | get { return m_sceneGraph.Entities; } | 366 | get { return m_sceneGraph.Entities; } |
@@ -510,7 +518,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
510 | 518 | ||
511 | m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine"); | 519 | m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine"); |
512 | 520 | ||
513 | m_maxPrimsPerFrame = startupConfig.GetInt("MaxPrimsPerFrame", 200); | ||
514 | IConfig packetConfig = m_config.Configs["PacketPool"]; | 521 | IConfig packetConfig = m_config.Configs["PacketPool"]; |
515 | if (packetConfig != null) | 522 | if (packetConfig != null) |
516 | { | 523 | { |
@@ -519,6 +526,35 @@ namespace OpenSim.Region.Framework.Scenes | |||
519 | } | 526 | } |
520 | 527 | ||
521 | m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); | 528 | m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); |
529 | |||
530 | IConfig interest_management_config = m_config.Configs["InterestManagement"]; | ||
531 | if (interest_management_config != null) | ||
532 | { | ||
533 | string update_prioritization_scheme = interest_management_config.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower(); | ||
534 | switch (update_prioritization_scheme) | ||
535 | { | ||
536 | case "time": | ||
537 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; | ||
538 | break; | ||
539 | case "distance": | ||
540 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.Distance; | ||
541 | break; | ||
542 | case "simpleangulardistance": | ||
543 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance; | ||
544 | break; | ||
545 | default: | ||
546 | m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time"); | ||
547 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; | ||
548 | break; | ||
549 | } | ||
550 | |||
551 | m_reprioritization_enabled = interest_management_config.GetBoolean("ReprioritizationEnabled", true); | ||
552 | m_reprioritization_interval = interest_management_config.GetDouble("ReprioritizationInterval", 5000.0); | ||
553 | m_root_reprioritization_distance = interest_management_config.GetDouble("RootReprioritizationDistance", 10.0); | ||
554 | m_child_reprioritization_distance = interest_management_config.GetDouble("ChildReprioritizationDistance", 20.0); | ||
555 | } | ||
556 | |||
557 | m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); | ||
522 | } | 558 | } |
523 | catch | 559 | catch |
524 | { | 560 | { |
@@ -1144,14 +1180,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1144 | /// <param name="stats">Stats on the Simulator's performance</param> | 1180 | /// <param name="stats">Stats on the Simulator's performance</param> |
1145 | private void SendSimStatsPackets(SimStats stats) | 1181 | private void SendSimStatsPackets(SimStats stats) |
1146 | { | 1182 | { |
1147 | List<ScenePresence> StatSendAgents = GetScenePresences(); | 1183 | ForEachScenePresence( |
1148 | foreach (ScenePresence agent in StatSendAgents) | 1184 | delegate(ScenePresence agent) |
1149 | { | ||
1150 | if (!agent.IsChildAgent) | ||
1151 | { | 1185 | { |
1152 | agent.ControllingClient.SendSimStats(stats); | 1186 | if (!agent.IsChildAgent) |
1187 | agent.ControllingClient.SendSimStats(stats); | ||
1153 | } | 1188 | } |
1154 | } | 1189 | ); |
1155 | } | 1190 | } |
1156 | 1191 | ||
1157 | /// <summary> | 1192 | /// <summary> |
@@ -1200,15 +1235,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1200 | } | 1235 | } |
1201 | 1236 | ||
1202 | /// <summary> | 1237 | /// <summary> |
1203 | /// Perform delegate action on all clients subscribing to updates from this region. | ||
1204 | /// </summary> | ||
1205 | /// <returns></returns> | ||
1206 | public void Broadcast(Action<IClientAPI> whatToDo) | ||
1207 | { | ||
1208 | ForEachScenePresence(delegate(ScenePresence presence) { whatToDo(presence.ControllingClient); }); | ||
1209 | } | ||
1210 | |||
1211 | /// <summary> | ||
1212 | /// Backup the scene. This acts as the main method of the backup thread. | 1238 | /// Backup the scene. This acts as the main method of the backup thread. |
1213 | /// </summary> | 1239 | /// </summary> |
1214 | /// <returns></returns> | 1240 | /// <returns></returns> |
@@ -3054,17 +3080,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3054 | } | 3080 | } |
3055 | 3081 | ||
3056 | m_eventManager.TriggerOnRemovePresence(agentID); | 3082 | m_eventManager.TriggerOnRemovePresence(agentID); |
3057 | Broadcast(delegate(IClientAPI client) | 3083 | ForEachClient( |
3058 | { | 3084 | delegate(IClientAPI client) |
3059 | try | 3085 | { |
3060 | { | 3086 | //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway |
3061 | client.SendKillObject(avatar.RegionHandle, avatar.LocalId); | 3087 | try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } |
3062 | } | 3088 | catch (NullReferenceException) { } |
3063 | catch (NullReferenceException) | 3089 | }); |
3064 | { | ||
3065 | //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway. | ||
3066 | } | ||
3067 | }); | ||
3068 | 3090 | ||
3069 | ForEachScenePresence( | 3091 | ForEachScenePresence( |
3070 | delegate(ScenePresence presence) { presence.CoarseLocationChange(); }); | 3092 | delegate(ScenePresence presence) { presence.CoarseLocationChange(); }); |
@@ -3149,7 +3171,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3149 | return; | 3171 | return; |
3150 | } | 3172 | } |
3151 | } | 3173 | } |
3152 | Broadcast(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); | 3174 | ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); |
3153 | } | 3175 | } |
3154 | 3176 | ||
3155 | #endregion | 3177 | #endregion |
@@ -3475,10 +3497,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3475 | { | 3497 | { |
3476 | ScenePresence presence; | 3498 | ScenePresence presence; |
3477 | 3499 | ||
3478 | lock (m_scenePresences) | 3500 | lock (m_sceneGraph.ScenePresences) |
3479 | { | 3501 | m_sceneGraph.ScenePresences.TryGetValue(agentID, out presence); |
3480 | m_scenePresences.TryGetValue(agentID, out presence); | ||
3481 | } | ||
3482 | 3502 | ||
3483 | if (presence != null) | 3503 | if (presence != null) |
3484 | { | 3504 | { |
@@ -3688,12 +3708,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3688 | public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, | 3708 | public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, |
3689 | Vector3 lookAt, uint teleportFlags) | 3709 | Vector3 lookAt, uint teleportFlags) |
3690 | { | 3710 | { |
3691 | ScenePresence sp = null; | 3711 | ScenePresence sp; |
3692 | lock (m_scenePresences) | 3712 | lock (m_sceneGraph.ScenePresences) |
3693 | { | 3713 | m_sceneGraph.ScenePresences.TryGetValue(remoteClient.AgentId, out sp); |
3694 | if (m_scenePresences.ContainsKey(remoteClient.AgentId)) | ||
3695 | sp = m_scenePresences[remoteClient.AgentId]; | ||
3696 | } | ||
3697 | 3714 | ||
3698 | if (sp != null) | 3715 | if (sp != null) |
3699 | { | 3716 | { |
@@ -4142,7 +4159,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4142 | public void ForEachScenePresence(Action<ScenePresence> action) | 4159 | public void ForEachScenePresence(Action<ScenePresence> action) |
4143 | { | 4160 | { |
4144 | // We don't want to try to send messages if there are no avatars. | 4161 | // We don't want to try to send messages if there are no avatars. |
4145 | if (m_scenePresences != null) | 4162 | if (m_sceneGraph != null && m_sceneGraph.ScenePresences != null) |
4146 | { | 4163 | { |
4147 | try | 4164 | try |
4148 | { | 4165 | { |
@@ -4222,7 +4239,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4222 | 4239 | ||
4223 | public void ForEachClient(Action<IClientAPI> action) | 4240 | public void ForEachClient(Action<IClientAPI> action) |
4224 | { | 4241 | { |
4225 | m_sceneGraph.ForEachClient(action); | 4242 | ClientManager.ForEach(action); |
4226 | } | 4243 | } |
4227 | 4244 | ||
4228 | public void ForEachSOG(Action<SceneObjectGroup> action) | 4245 | public void ForEachSOG(Action<SceneObjectGroup> action) |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index ba5119f..deee6c3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -467,7 +467,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
467 | protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent) | 467 | protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent) |
468 | { | 468 | { |
469 | // If we can't take it, we can't attach it! | 469 | // If we can't take it, we can't attach it! |
470 | // | ||
471 | SceneObjectPart part = m_parentScene.GetSceneObjectPart(objectLocalID); | 470 | SceneObjectPart part = m_parentScene.GetSceneObjectPart(objectLocalID); |
472 | if (part == null) | 471 | if (part == null) |
473 | return; | 472 | return; |
@@ -477,9 +476,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
477 | return; | 476 | return; |
478 | 477 | ||
479 | // Calls attach with a Zero position | 478 | // Calls attach with a Zero position |
480 | // | ||
481 | AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false); | 479 | AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false); |
482 | m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); | 480 | m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); |
481 | |||
482 | // Save avatar attachment information | ||
483 | ScenePresence presence; | ||
484 | if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence)) | ||
485 | { | ||
486 | m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", AttachmentPoint: " + AttachmentPt); | ||
487 | m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | ||
488 | } | ||
483 | } | 489 | } |
484 | 490 | ||
485 | public SceneObjectGroup RezSingleAttachment( | 491 | public SceneObjectGroup RezSingleAttachment( |
@@ -574,7 +580,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
574 | } | 580 | } |
575 | 581 | ||
576 | 582 | ||
577 | group.SetAttachmentPoint(Convert.ToByte(AttachmentPt)); | 583 | group.SetAttachmentPoint((byte)AttachmentPt); |
578 | group.AbsolutePosition = attachPos; | 584 | group.AbsolutePosition = attachPos; |
579 | 585 | ||
580 | // Saves and gets itemID | 586 | // Saves and gets itemID |
@@ -613,7 +619,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
613 | 619 | ||
614 | newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance); | 620 | newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance); |
615 | newAvatar.IsChildAgent = true; | 621 | newAvatar.IsChildAgent = true; |
616 | newAvatar.MaxPrimsPerFrame = m_parentScene.MaxPrimsPerFrame; | ||
617 | 622 | ||
618 | AddScenePresence(newAvatar); | 623 | AddScenePresence(newAvatar); |
619 | 624 | ||
@@ -847,7 +852,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
847 | /// </summary> | 852 | /// </summary> |
848 | /// <param name="localID"></param> | 853 | /// <param name="localID"></param> |
849 | /// <returns>null if no scene object group containing that prim is found</returns> | 854 | /// <returns>null if no scene object group containing that prim is found</returns> |
850 | private SceneObjectGroup GetGroupByPrim(uint localID) | 855 | public SceneObjectGroup GetGroupByPrim(uint localID) |
851 | { | 856 | { |
852 | if (Entities.ContainsKey(localID)) | 857 | if (Entities.ContainsKey(localID)) |
853 | return Entities[localID] as SceneObjectGroup; | 858 | return Entities[localID] as SceneObjectGroup; |
@@ -1107,23 +1112,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1107 | return UUID.Zero; | 1112 | return UUID.Zero; |
1108 | } | 1113 | } |
1109 | 1114 | ||
1110 | protected internal void ForEachClient(Action<IClientAPI> action) | ||
1111 | { | ||
1112 | List<ScenePresence> splist = GetScenePresences(); | ||
1113 | foreach (ScenePresence presence in splist) | ||
1114 | { | ||
1115 | try | ||
1116 | { | ||
1117 | action(presence.ControllingClient); | ||
1118 | } | ||
1119 | catch (Exception e) | ||
1120 | { | ||
1121 | // Catch it and move on. This includes situations where splist has inconsistent info | ||
1122 | m_log.WarnFormat("[SCENE]: Problem processing action in ForEachClient: ", e.Message); | ||
1123 | } | ||
1124 | } | ||
1125 | } | ||
1126 | |||
1127 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) | 1115 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) |
1128 | { | 1116 | { |
1129 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); | 1117 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index b8bd9b4..69b3ded 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -906,7 +906,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
906 | SetAttachmentPoint(Convert.ToByte(attachmentpoint)); | 906 | SetAttachmentPoint(Convert.ToByte(attachmentpoint)); |
907 | 907 | ||
908 | avatar.AddAttachment(this); | 908 | avatar.AddAttachment(this); |
909 | m_log.DebugFormat("[SOG]: Added att {0} to avie {1}", UUID, avatar.UUID); | 909 | m_log.Debug("[SOG]: Added attachment " + UUID + " to avatar " + avatar.UUID); |
910 | 910 | ||
911 | if (!silent) | 911 | if (!silent) |
912 | { | 912 | { |
@@ -1824,7 +1824,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1824 | public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags) | 1824 | public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags) |
1825 | { | 1825 | { |
1826 | 1826 | ||
1827 | remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.ObjectOwner, RootPart.GroupID, RootPart.BaseMask, | 1827 | remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask, |
1828 | RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, | 1828 | RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, |
1829 | RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, | 1829 | RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, |
1830 | RootPart.CreatorID, RootPart.Name, RootPart.Description); | 1830 | RootPart.CreatorID, RootPart.Name, RootPart.Description); |
@@ -3355,5 +3355,77 @@ namespace OpenSim.Region.Framework.Scenes | |||
3355 | 3355 | ||
3356 | return true; | 3356 | return true; |
3357 | } | 3357 | } |
3358 | |||
3359 | public double GetUpdatePriority(IClientAPI client) | ||
3360 | { | ||
3361 | switch (Scene.UpdatePrioritizationScheme) | ||
3362 | { | ||
3363 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3364 | return GetPriorityByTime(); | ||
3365 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3366 | return GetPriorityByDistance(client); | ||
3367 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3368 | return GetPriorityBySimpleAngularDistance(client); | ||
3369 | default: | ||
3370 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); | ||
3371 | } | ||
3372 | } | ||
3373 | |||
3374 | private double GetPriorityByTime() | ||
3375 | { | ||
3376 | return DateTime.Now.ToOADate(); | ||
3377 | } | ||
3378 | |||
3379 | private double GetPriorityByDistance(IClientAPI client) | ||
3380 | { | ||
3381 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3382 | if (presence != null) | ||
3383 | { | ||
3384 | return GetPriorityByDistance((presence.IsChildAgent) ? | ||
3385 | presence.AbsolutePosition : presence.CameraPosition); | ||
3386 | } | ||
3387 | return double.NaN; | ||
3388 | } | ||
3389 | |||
3390 | private double GetPriorityBySimpleAngularDistance(IClientAPI client) | ||
3391 | { | ||
3392 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3393 | if (presence != null) | ||
3394 | { | ||
3395 | return GetPriorityBySimpleAngularDistance((presence.IsChildAgent) ? | ||
3396 | presence.AbsolutePosition : presence.CameraPosition); | ||
3397 | } | ||
3398 | return double.NaN; | ||
3399 | } | ||
3400 | |||
3401 | public double GetPriorityByDistance(Vector3 position) | ||
3402 | { | ||
3403 | return Vector3.Distance(AbsolutePosition, position); | ||
3404 | } | ||
3405 | |||
3406 | public double GetPriorityBySimpleAngularDistance(Vector3 position) | ||
3407 | { | ||
3408 | double distance = Vector3.Distance(position, AbsolutePosition); | ||
3409 | if (distance >= double.Epsilon) | ||
3410 | { | ||
3411 | float height; | ||
3412 | Vector3 box = GetAxisAlignedBoundingBox(out height); | ||
3413 | |||
3414 | double angle = box.X / distance; | ||
3415 | double max = angle; | ||
3416 | |||
3417 | angle = box.Y / distance; | ||
3418 | if (max < angle) | ||
3419 | max = angle; | ||
3420 | |||
3421 | angle = box.Z / distance; | ||
3422 | if (max < angle) | ||
3423 | max = angle; | ||
3424 | |||
3425 | return -max; | ||
3426 | } | ||
3427 | else | ||
3428 | return double.MinValue; | ||
3429 | } | ||
3358 | } | 3430 | } |
3359 | } | 3431 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 23a7021..32171a0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -841,16 +841,6 @@ if (m_shape != null) { | |||
841 | return m_offsetPosition + m_groupPosition; } | 841 | return m_offsetPosition + m_groupPosition; } |
842 | } | 842 | } |
843 | 843 | ||
844 | public UUID ObjectCreator | ||
845 | { | ||
846 | get { return _creatorID; } | ||
847 | } | ||
848 | |||
849 | public UUID ObjectOwner | ||
850 | { | ||
851 | get { return _ownerID; } | ||
852 | } | ||
853 | |||
854 | public SceneObjectGroup ParentGroup | 844 | public SceneObjectGroup ParentGroup |
855 | { | 845 | { |
856 | get { return m_parentGroup; } | 846 | get { return m_parentGroup; } |
@@ -1427,7 +1417,7 @@ if (m_shape != null) { | |||
1427 | // Move afterwards ResetIDs as it clears the localID | 1417 | // Move afterwards ResetIDs as it clears the localID |
1428 | dupe.LocalId = localID; | 1418 | dupe.LocalId = localID; |
1429 | // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. | 1419 | // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. |
1430 | dupe._lastOwnerID = ObjectOwner; | 1420 | dupe._lastOwnerID = OwnerID; |
1431 | 1421 | ||
1432 | byte[] extraP = new byte[Shape.ExtraParams.Length]; | 1422 | byte[] extraP = new byte[Shape.ExtraParams.Length]; |
1433 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); | 1423 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); |
@@ -2388,10 +2378,10 @@ if (m_shape != null) { | |||
2388 | //isattachment = ParentGroup.RootPart.IsAttachment; | 2378 | //isattachment = ParentGroup.RootPart.IsAttachment; |
2389 | 2379 | ||
2390 | byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; | 2380 | byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; |
2391 | remoteClient.SendPrimitiveToClient(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, | 2381 | remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, |
2392 | lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, _ownerID, | 2382 | lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, _ownerID, |
2393 | m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, | 2383 | m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, |
2394 | AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius); | 2384 | AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient))); |
2395 | } | 2385 | } |
2396 | 2386 | ||
2397 | /// <summary> | 2387 | /// <summary> |
@@ -3764,13 +3754,15 @@ if (m_shape != null) { | |||
3764 | if (ParentGroup.RootPart == this) | 3754 | if (ParentGroup.RootPart == this) |
3765 | lPos = AbsolutePosition; | 3755 | lPos = AbsolutePosition; |
3766 | } | 3756 | } |
3767 | 3757 | ||
3768 | remoteClient.SendPrimTerseUpdate(m_regionHandle, | 3758 | // Causes this thread to dig into the Client Thread Data. |
3759 | // Remember your locking here! | ||
3760 | remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, | ||
3769 | (ushort)(m_parentGroup.GetTimeDilation() * | 3761 | (ushort)(m_parentGroup.GetTimeDilation() * |
3770 | (float)ushort.MaxValue), LocalId, lPos, | 3762 | (float)ushort.MaxValue), LocalId, lPos, |
3771 | RotationOffset, Velocity, | 3763 | RotationOffset, Velocity, Acceleration, |
3772 | RotationalVelocity, state, FromItemID, | 3764 | RotationalVelocity, state, FromItemID, |
3773 | OwnerID, (int)AttachmentPoint); | 3765 | OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient))); |
3774 | } | 3766 | } |
3775 | 3767 | ||
3776 | public void AddScriptLPS(int count) | 3768 | public void AddScriptLPS(int count) |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 098e010..f4ca877 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -871,12 +871,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
871 | { | 871 | { |
872 | foreach (IScriptModule e in engines) | 872 | foreach (IScriptModule e in engines) |
873 | { | 873 | { |
874 | string n = e.GetAssemblyName(item.ItemID); | 874 | if (e != null) |
875 | if (n != "") | ||
876 | { | 875 | { |
877 | if (!ret.Contains(n)) | 876 | string n = e.GetAssemblyName(item.ItemID); |
878 | ret.Add(n); | 877 | if (n != String.Empty) |
879 | break; | 878 | { |
879 | if (!ret.Contains(n)) | ||
880 | ret.Add(n); | ||
881 | break; | ||
882 | } | ||
880 | } | 883 | } |
881 | } | 884 | } |
882 | } | 885 | } |
@@ -898,12 +901,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
898 | { | 901 | { |
899 | foreach (IScriptModule e in engines) | 902 | foreach (IScriptModule e in engines) |
900 | { | 903 | { |
901 | string n = e.GetXMLState(item.ItemID); | 904 | if (e != null) |
902 | if (n != "") | ||
903 | { | 905 | { |
904 | if (!ret.ContainsKey(item.ItemID)) | 906 | string n = e.GetXMLState(item.ItemID); |
905 | ret[item.ItemID] = n; | 907 | if (n != String.Empty) |
906 | break; | 908 | { |
909 | if (!ret.ContainsKey(item.ItemID)) | ||
910 | ret[item.ItemID] = n; | ||
911 | break; | ||
912 | } | ||
907 | } | 913 | } |
908 | } | 914 | } |
909 | } | 915 | } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c25fa55..d7113bf 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -28,6 +28,7 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Timers; | ||
31 | using OpenMetaverse; | 32 | using OpenMetaverse; |
32 | using log4net; | 33 | using log4net; |
33 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
@@ -127,8 +128,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
127 | 128 | ||
128 | private bool m_setAlwaysRun; | 129 | private bool m_setAlwaysRun; |
129 | 130 | ||
130 | private bool m_updatesAllowed = true; | ||
131 | private List<AgentUpdateArgs> m_agentUpdates = new List<AgentUpdateArgs>(); | ||
132 | private string m_movementAnimation = "DEFAULT"; | 131 | private string m_movementAnimation = "DEFAULT"; |
133 | private long m_animPersistUntil = 0; | 132 | private long m_animPersistUntil = 0; |
134 | private bool m_allowFalling = false; | 133 | private bool m_allowFalling = false; |
@@ -172,6 +171,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
172 | 171 | ||
173 | // Position of agent's camera in world (region cordinates) | 172 | // Position of agent's camera in world (region cordinates) |
174 | protected Vector3 m_CameraCenter = Vector3.Zero; | 173 | protected Vector3 m_CameraCenter = Vector3.Zero; |
174 | protected Vector3 m_lastCameraCenter = Vector3.Zero; | ||
175 | |||
176 | protected Timer m_reprioritization_timer; | ||
177 | protected bool m_reprioritizing = false; | ||
178 | protected bool m_reprioritization_called = false; | ||
175 | 179 | ||
176 | // Use these three vectors to figure out what the agent is looking at | 180 | // Use these three vectors to figure out what the agent is looking at |
177 | // Convert it to a Matrix and/or Quaternion | 181 | // Convert it to a Matrix and/or Quaternion |
@@ -403,12 +407,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
403 | set { m_parentPosition = value; } | 407 | set { m_parentPosition = value; } |
404 | } | 408 | } |
405 | 409 | ||
406 | public int MaxPrimsPerFrame | ||
407 | { | ||
408 | get { return m_sceneViewer.MaxPrimsPerFrame; } | ||
409 | set { m_sceneViewer.MaxPrimsPerFrame = value; } | ||
410 | } | ||
411 | |||
412 | /// <summary> | 410 | /// <summary> |
413 | /// Absolute position of this avatar in 'region cordinates' | 411 | /// Absolute position of this avatar in 'region cordinates' |
414 | /// </summary> | 412 | /// </summary> |
@@ -645,7 +643,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
645 | 643 | ||
646 | m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>(); | 644 | m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>(); |
647 | 645 | ||
648 | AbsolutePosition = m_controllingClient.StartPos; | 646 | AbsolutePosition = posLastSignificantMove = m_CameraCenter = |
647 | m_lastCameraCenter = m_controllingClient.StartPos; | ||
648 | |||
649 | m_reprioritization_timer = new Timer(world.ReprioritizationInterval); | ||
650 | m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize); | ||
651 | m_reprioritization_timer.AutoReset = false; | ||
652 | |||
653 | |||
649 | AdjustKnownSeeds(); | 654 | AdjustKnownSeeds(); |
650 | 655 | ||
651 | TrySetMovementAnimation("STAND"); // TODO: I think, this won't send anything, as we are still a child here... | 656 | TrySetMovementAnimation("STAND"); // TODO: I think, this won't send anything, as we are still a child here... |
@@ -1083,34 +1088,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1083 | 1088 | ||
1084 | } | 1089 | } |
1085 | 1090 | ||
1086 | // These methods allow to queue up agent updates (like key presses) | ||
1087 | // until all attachment scripts are running and the animations from | ||
1088 | // AgentDataUpdate have been started. It is essential for combat | ||
1089 | // devices, weapons and AOs that keypresses are not processed | ||
1090 | // until scripts that are potentially interested in them are | ||
1091 | // up and running and that animations a script knows to be running | ||
1092 | // from before a crossing are running again | ||
1093 | // | ||
1094 | public void LockAgentUpdates() | ||
1095 | { | ||
1096 | m_updatesAllowed = false; | ||
1097 | } | ||
1098 | |||
1099 | public void UnlockAgentUpdates() | ||
1100 | { | ||
1101 | lock (m_agentUpdates) | ||
1102 | { | ||
1103 | if (m_updatesAllowed == false) | ||
1104 | { | ||
1105 | foreach (AgentUpdateArgs a in m_agentUpdates) | ||
1106 | RealHandleAgentUpdate(ControllingClient, a); | ||
1107 | m_agentUpdates.Clear(); | ||
1108 | m_updatesAllowed = true; | ||
1109 | } | ||
1110 | } | ||
1111 | } | ||
1112 | |||
1113 | |||
1114 | /// <summary> | 1091 | /// <summary> |
1115 | /// Callback for the Camera view block check. Gets called with the results of the camera view block test | 1092 | /// Callback for the Camera view block check. Gets called with the results of the camera view block test |
1116 | /// hitYN is true when there's something in the way. | 1093 | /// hitYN is true when there's something in the way. |
@@ -1148,43 +1125,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
1148 | } | 1125 | } |
1149 | } | 1126 | } |
1150 | 1127 | ||
1128 | Array m_dirControlFlags = Enum.GetValues(typeof(Dir_ControlFlags)); | ||
1129 | |||
1151 | /// <summary> | 1130 | /// <summary> |
1152 | /// This is the event handler for client movement. If a client is moving, this event is triggering. | 1131 | /// This is the event handler for client movement. If a client is moving, this event is triggering. |
1153 | /// </summary> | 1132 | /// </summary> |
1154 | public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) | 1133 | public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) |
1155 | { | 1134 | { |
1156 | lock (m_agentUpdates) | ||
1157 | { | ||
1158 | if (m_updatesAllowed) | ||
1159 | { | ||
1160 | RealHandleAgentUpdate(remoteClient, agentData); | ||
1161 | return; | ||
1162 | } | ||
1163 | |||
1164 | m_agentUpdates.Add(agentData); | ||
1165 | } | ||
1166 | } | ||
1167 | |||
1168 | private void RealHandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) | ||
1169 | { | ||
1170 | //if (m_isChildAgent) | 1135 | //if (m_isChildAgent) |
1171 | //{ | 1136 | //{ |
1172 | // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); | 1137 | // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); |
1173 | // return; | 1138 | // return; |
1174 | //} | 1139 | //} |
1175 | 1140 | ||
1176 | 1141 | m_perfMonMS = Environment.TickCount; | |
1177 | m_movementUpdateCount++; | ||
1178 | if (m_movementUpdateCount >= int.MaxValue) | ||
1179 | m_movementUpdateCount = 1; | ||
1180 | 1142 | ||
1143 | ++m_movementUpdateCount; | ||
1144 | if (m_movementUpdateCount < 1) | ||
1145 | m_movementUpdateCount = 1; | ||
1181 | 1146 | ||
1182 | // Must check for standing up even when PhysicsActor is null, | 1147 | // Must check for standing up even when PhysicsActor is null, |
1183 | // since sitting currently removes avatar from physical scene | 1148 | // since sitting currently removes avatar from physical scene |
1184 | //m_log.Debug("agentPos:" + AbsolutePosition.ToString()); | 1149 | //m_log.Debug("agentPos:" + AbsolutePosition.ToString()); |
1185 | 1150 | ||
1186 | // This is irritating. Really. | 1151 | // This is irritating. Really. |
1187 | |||
1188 | if (!AbsolutePosition.IsFinite()) | 1152 | if (!AbsolutePosition.IsFinite()) |
1189 | { | 1153 | { |
1190 | RemoveFromPhysicalScene(); | 1154 | RemoveFromPhysicalScene(); |
@@ -1205,19 +1169,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1205 | { | 1169 | { |
1206 | m_LastFinitePos = m_pos; | 1170 | m_LastFinitePos = m_pos; |
1207 | } | 1171 | } |
1208 | //m_physicsActor.AddForce(new PhysicsVector(999999999, 99999999, 999999999999999), true); | ||
1209 | 1172 | ||
1173 | //m_physicsActor.AddForce(new PhysicsVector(999999999, 99999999, 999999999999999), true); | ||
1210 | 1174 | ||
1211 | //ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); | 1175 | //ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); |
1212 | //if (land != null) | 1176 | //if (land != null) |
1213 | //{ | 1177 | //{ |
1214 | //if (land.landData.landingType == (byte)1 && land.landData.userLocation != Vector3.Zero) | 1178 | //if (land.landData.landingType == (byte)1 && land.landData.userLocation != Vector3.Zero) |
1215 | //{ | 1179 | //{ |
1216 | // agent.startpos = land.landData.userLocation; | 1180 | // agent.startpos = land.landData.userLocation; |
1217 | //} | 1181 | //} |
1218 | //} | 1182 | //} |
1219 | |||
1220 | m_perfMonMS = Environment.TickCount; | ||
1221 | 1183 | ||
1222 | uint flags = agentData.ControlFlags; | 1184 | uint flags = agentData.ControlFlags; |
1223 | Quaternion bodyRotation = agentData.BodyRotation; | 1185 | Quaternion bodyRotation = agentData.BodyRotation; |
@@ -1225,6 +1187,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1225 | // Camera location in world. We'll need to raytrace | 1187 | // Camera location in world. We'll need to raytrace |
1226 | // from this location from time to time. | 1188 | // from this location from time to time. |
1227 | m_CameraCenter = agentData.CameraCenter; | 1189 | m_CameraCenter = agentData.CameraCenter; |
1190 | if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance) | ||
1191 | { | ||
1192 | ReprioritizeUpdates(); | ||
1193 | m_lastCameraCenter = m_CameraCenter; | ||
1194 | } | ||
1228 | 1195 | ||
1229 | // Use these three vectors to figure out what the agent is looking at | 1196 | // Use these three vectors to figure out what the agent is looking at |
1230 | // Convert it to a Matrix and/or Quaternion | 1197 | // Convert it to a Matrix and/or Quaternion |
@@ -1235,7 +1202,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1235 | // The Agent's Draw distance setting | 1202 | // The Agent's Draw distance setting |
1236 | m_DrawDistance = agentData.Far; | 1203 | m_DrawDistance = agentData.Far; |
1237 | 1204 | ||
1238 | if ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) | 1205 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) |
1239 | { | 1206 | { |
1240 | StandUp(); | 1207 | StandUp(); |
1241 | } | 1208 | } |
@@ -1243,14 +1210,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1243 | // Check if Client has camera in 'follow cam' or 'build' mode. | 1210 | // Check if Client has camera in 'follow cam' or 'build' mode. |
1244 | Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation); | 1211 | Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation); |
1245 | 1212 | ||
1246 | m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f) | 1213 | m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f) |
1247 | && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false; | 1214 | && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false; |
1248 | 1215 | ||
1249 | //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto); | 1216 | //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto); |
1250 | // Raycast from the avatar's head to the camera to see if there's anything blocking the view | 1217 | // Raycast from the avatar's head to the camera to see if there's anything blocking the view |
1251 | if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) | 1218 | if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) |
1252 | { | 1219 | { |
1253 | |||
1254 | if (m_followCamAuto) | 1220 | if (m_followCamAuto) |
1255 | { | 1221 | { |
1256 | Vector3 headadjustment = new Vector3(0, 0, 0.3f); | 1222 | Vector3 headadjustment = new Vector3(0, 0, 0.3f); |
@@ -1258,24 +1224,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
1258 | } | 1224 | } |
1259 | } | 1225 | } |
1260 | 1226 | ||
1261 | m_mouseLook = (flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; | 1227 | m_mouseLook = (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; |
1262 | |||
1263 | |||
1264 | |||
1265 | m_leftButtonDown = (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; | 1228 | m_leftButtonDown = (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; |
1266 | 1229 | ||
1267 | |||
1268 | |||
1269 | lock (scriptedcontrols) | 1230 | lock (scriptedcontrols) |
1270 | { | 1231 | { |
1271 | if (scriptedcontrols.Count > 0) | 1232 | if (scriptedcontrols.Count > 0) |
1272 | { | 1233 | { |
1273 | SendControlToScripts(flags); | 1234 | SendControlToScripts(flags); |
1274 | flags = RemoveIgnoredControls(flags, IgnoredControls); | 1235 | flags = RemoveIgnoredControls(flags, IgnoredControls); |
1275 | |||
1276 | } | 1236 | } |
1277 | } | 1237 | } |
1278 | 1238 | ||
1279 | if (PhysicsActor == null) | 1239 | if (PhysicsActor == null) |
1280 | { | 1240 | { |
1281 | return; | 1241 | return; |
@@ -1284,7 +1244,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1284 | if (m_autopilotMoving) | 1244 | if (m_autopilotMoving) |
1285 | CheckAtSitTarget(); | 1245 | CheckAtSitTarget(); |
1286 | 1246 | ||
1287 | if ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) | 1247 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) |
1288 | { | 1248 | { |
1289 | // TODO: This doesn't prevent the user from walking yet. | 1249 | // TODO: This doesn't prevent the user from walking yet. |
1290 | // Setting parent ID would fix this, if we knew what value | 1250 | // Setting parent ID would fix this, if we knew what value |
@@ -1317,13 +1277,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1317 | PhysicsActor.Flying = false; | 1277 | PhysicsActor.Flying = false; |
1318 | else | 1278 | else |
1319 | PhysicsActor.Flying = ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | 1279 | PhysicsActor.Flying = ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); |
1320 | 1280 | ||
1321 | if (PhysicsActor.Flying != oldflying) | 1281 | if (PhysicsActor.Flying != oldflying) |
1322 | { | 1282 | { |
1323 | update_movementflag = true; | 1283 | update_movementflag = true; |
1324 | } | 1284 | } |
1325 | } | 1285 | } |
1326 | 1286 | ||
1327 | if (q != m_bodyRot) | 1287 | if (q != m_bodyRot) |
1328 | { | 1288 | { |
1329 | m_bodyRot = q; | 1289 | m_bodyRot = q; |
@@ -1339,15 +1299,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1339 | 1299 | ||
1340 | // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying | 1300 | // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying |
1341 | // this prevents 'jumping' in inappropriate situations. | 1301 | // this prevents 'jumping' in inappropriate situations. |
1342 | if ((m_mouseLook && !m_physicsActor.Flying) || (m_leftButtonDown && !m_physicsActor.Flying)) | 1302 | if ((m_mouseLook && !m_physicsActor.Flying) || (m_leftButtonDown && !m_physicsActor.Flying)) |
1343 | dirVectors = GetWalkDirectionVectors(); | 1303 | dirVectors = GetWalkDirectionVectors(); |
1344 | else | 1304 | else |
1345 | dirVectors = Dir_Vectors; | 1305 | dirVectors = Dir_Vectors; |
1346 | 1306 | ||
1347 | 1307 | ||
1348 | foreach (Dir_ControlFlags DCF in Enum.GetValues(typeof (Dir_ControlFlags))) | 1308 | foreach (Dir_ControlFlags DCF in m_dirControlFlags) |
1349 | { | 1309 | { |
1350 | if ((flags & (uint) DCF) != 0) | 1310 | if ((flags & (uint)DCF) != 0) |
1351 | { | 1311 | { |
1352 | bResetMoveToPosition = true; | 1312 | bResetMoveToPosition = true; |
1353 | DCFlagKeyPressed = true; | 1313 | DCFlagKeyPressed = true; |
@@ -1359,18 +1319,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
1359 | { | 1319 | { |
1360 | // Why did I get this? | 1320 | // Why did I get this? |
1361 | } | 1321 | } |
1362 | 1322 | ||
1363 | if ((m_movementflag & (uint) DCF) == 0) | 1323 | if ((m_movementflag & (uint)DCF) == 0) |
1364 | { | 1324 | { |
1365 | m_movementflag += (byte) (uint) DCF; | 1325 | m_movementflag += (byte)(uint)DCF; |
1366 | update_movementflag = true; | 1326 | update_movementflag = true; |
1367 | } | 1327 | } |
1368 | } | 1328 | } |
1369 | else | 1329 | else |
1370 | { | 1330 | { |
1371 | if ((m_movementflag & (uint) DCF) != 0) | 1331 | if ((m_movementflag & (uint)DCF) != 0) |
1372 | { | 1332 | { |
1373 | m_movementflag -= (byte) (uint) DCF; | 1333 | m_movementflag -= (byte)(uint)DCF; |
1374 | update_movementflag = true; | 1334 | update_movementflag = true; |
1375 | } | 1335 | } |
1376 | else | 1336 | else |
@@ -1461,14 +1421,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1461 | } | 1421 | } |
1462 | catch (Exception) | 1422 | catch (Exception) |
1463 | { | 1423 | { |
1464 | |||
1465 | //Avoid system crash, can be slower but... | 1424 | //Avoid system crash, can be slower but... |
1466 | } | 1425 | } |
1467 | |||
1468 | } | 1426 | } |
1469 | } | 1427 | } |
1470 | } | 1428 | } |
1471 | 1429 | ||
1472 | // Cause the avatar to stop flying if it's colliding | 1430 | // Cause the avatar to stop flying if it's colliding |
1473 | // with something with the down arrow pressed. | 1431 | // with something with the down arrow pressed. |
1474 | 1432 | ||
@@ -1476,8 +1434,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1476 | if (m_physicsActor != null && m_physicsActor.Flying && !m_forceFly) | 1434 | if (m_physicsActor != null && m_physicsActor.Flying && !m_forceFly) |
1477 | { | 1435 | { |
1478 | // Are the landing controls requirements filled? | 1436 | // Are the landing controls requirements filled? |
1479 | bool controlland = (((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || | 1437 | bool controlland = (((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || |
1480 | ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); | 1438 | ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); |
1481 | 1439 | ||
1482 | // Are the collision requirements fulfilled? | 1440 | // Are the collision requirements fulfilled? |
1483 | bool colliding = (m_physicsActor.IsColliding == true); | 1441 | bool colliding = (m_physicsActor.IsColliding == true); |
@@ -1490,10 +1448,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1490 | 1448 | ||
1491 | if (update_movementflag || (update_rotation && DCFlagKeyPressed)) | 1449 | if (update_movementflag || (update_rotation && DCFlagKeyPressed)) |
1492 | { | 1450 | { |
1493 | // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); | 1451 | // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); |
1494 | // m_log.DebugFormat( | 1452 | // m_log.DebugFormat( |
1495 | // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); | 1453 | // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); |
1496 | 1454 | ||
1497 | AddNewMovement(agent_control_v3, q); | 1455 | AddNewMovement(agent_control_v3, q); |
1498 | 1456 | ||
1499 | if (update_movementflag) | 1457 | if (update_movementflag) |
@@ -2456,11 +2414,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2456 | m_perfMonMS = Environment.TickCount; | 2414 | m_perfMonMS = Environment.TickCount; |
2457 | 2415 | ||
2458 | Vector3 pos = m_pos; | 2416 | Vector3 pos = m_pos; |
2459 | Vector3 vel = Velocity; | ||
2460 | Quaternion rot = m_bodyRot; | ||
2461 | pos.Z -= m_appearance.HipOffset; | 2417 | pos.Z -= m_appearance.HipOffset; |
2462 | remoteClient.SendAvatarTerseUpdate(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, new Vector3(pos.X, pos.Y, pos.Z), | 2418 | |
2463 | new Vector3(vel.X, vel.Y, vel.Z), rot, m_uuid); | 2419 | remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, |
2420 | pos, m_velocity, Vector3.Zero, m_rotation, Vector4.Zero, m_uuid, null, GetUpdatePriority(remoteClient))); | ||
2464 | 2421 | ||
2465 | m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); | 2422 | m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); |
2466 | m_scene.StatsReporter.AddAgentUpdates(1); | 2423 | m_scene.StatsReporter.AddAgentUpdates(1); |
@@ -2474,7 +2431,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2474 | { | 2431 | { |
2475 | m_perfMonMS = Environment.TickCount; | 2432 | m_perfMonMS = Environment.TickCount; |
2476 | 2433 | ||
2477 | m_scene.Broadcast(SendTerseUpdateToClient); | 2434 | m_scene.ForEachClient(SendTerseUpdateToClient); |
2478 | 2435 | ||
2479 | m_lastVelocity = m_velocity; | 2436 | m_lastVelocity = m_velocity; |
2480 | lastPhysPos = AbsolutePosition; | 2437 | lastPhysPos = AbsolutePosition; |
@@ -2566,9 +2523,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2566 | Vector3 pos = m_pos; | 2523 | Vector3 pos = m_pos; |
2567 | pos.Z -= m_appearance.HipOffset; | 2524 | pos.Z -= m_appearance.HipOffset; |
2568 | 2525 | ||
2569 | remoteAvatar.m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, | 2526 | remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, |
2570 | LocalId, m_pos, m_appearance.Texture.GetBytes(), | 2527 | LocalId, m_pos, m_appearance.Texture.GetBytes(), |
2571 | m_parentID, rot); | 2528 | m_parentID, rot)); |
2572 | m_scene.StatsReporter.AddAgentUpdates(1); | 2529 | m_scene.StatsReporter.AddAgentUpdates(1); |
2573 | } | 2530 | } |
2574 | 2531 | ||
@@ -2637,8 +2594,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2637 | Vector3 pos = m_pos; | 2594 | Vector3 pos = m_pos; |
2638 | pos.Z -= m_appearance.HipOffset; | 2595 | pos.Z -= m_appearance.HipOffset; |
2639 | 2596 | ||
2640 | m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, | 2597 | m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, |
2641 | m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot); | 2598 | m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot)); |
2642 | 2599 | ||
2643 | if (!m_isChildAgent) | 2600 | if (!m_isChildAgent) |
2644 | { | 2601 | { |
@@ -2744,8 +2701,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2744 | } | 2701 | } |
2745 | 2702 | ||
2746 | Quaternion rot = m_bodyRot; | 2703 | Quaternion rot = m_bodyRot; |
2747 | m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, | 2704 | m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, |
2748 | m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot); | 2705 | m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot)); |
2749 | 2706 | ||
2750 | } | 2707 | } |
2751 | 2708 | ||
@@ -2776,7 +2733,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2776 | if (m_isChildAgent) | 2733 | if (m_isChildAgent) |
2777 | return; | 2734 | return; |
2778 | 2735 | ||
2779 | m_scene.Broadcast( | 2736 | m_scene.ForEachClient( |
2780 | delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId, objectIDs); }); | 2737 | delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId, objectIDs); }); |
2781 | } | 2738 | } |
2782 | 2739 | ||
@@ -2830,7 +2787,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2830 | } | 2787 | } |
2831 | 2788 | ||
2832 | // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m | 2789 | // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m |
2833 | if (Util.GetDistanceTo(AbsolutePosition,m_LastChildAgentUpdatePosition) > 32) | 2790 | if (Util.GetDistanceTo(AbsolutePosition, m_LastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance) |
2834 | { | 2791 | { |
2835 | ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); | 2792 | ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); |
2836 | cadu.ActiveGroupID = UUID.Zero.Guid; | 2793 | cadu.ActiveGroupID = UUID.Zero.Guid; |
@@ -3125,6 +3082,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3125 | if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!! | 3082 | if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!! |
3126 | m_pos = new Vector3(cAgentData.Position.X + shiftx, cAgentData.Position.Y + shifty, cAgentData.Position.Z); | 3083 | m_pos = new Vector3(cAgentData.Position.X + shiftx, cAgentData.Position.Y + shifty, cAgentData.Position.Z); |
3127 | 3084 | ||
3085 | if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) | ||
3086 | { | ||
3087 | posLastSignificantMove = AbsolutePosition; | ||
3088 | ReprioritizeUpdates(); | ||
3089 | } | ||
3090 | |||
3128 | // It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region | 3091 | // It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region |
3129 | m_CameraCenter = cAgentData.Center; | 3092 | m_CameraCenter = cAgentData.Center; |
3130 | 3093 | ||
@@ -3487,7 +3450,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3487 | 3450 | ||
3488 | public void Close() | 3451 | public void Close() |
3489 | { | 3452 | { |
3490 | |||
3491 | lock (m_attachments) | 3453 | lock (m_attachments) |
3492 | { | 3454 | { |
3493 | // Delete attachments from scene | 3455 | // Delete attachments from scene |
@@ -3505,10 +3467,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
3505 | { | 3467 | { |
3506 | m_knownChildRegions.Clear(); | 3468 | m_knownChildRegions.Clear(); |
3507 | } | 3469 | } |
3470 | |||
3471 | lock (m_reprioritization_timer) | ||
3472 | { | ||
3473 | m_reprioritization_timer.Enabled = false; | ||
3474 | m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize); | ||
3475 | } | ||
3476 | // I don't get it but mono crashes when you try to dispose of this timer, | ||
3477 | // unsetting the elapsed callback should be enough to allow for cleanup however. | ||
3478 | //m_reprioritizationTimer.Dispose(); | ||
3479 | |||
3508 | m_sceneViewer.Close(); | 3480 | m_sceneViewer.Close(); |
3509 | 3481 | ||
3510 | RemoveFromPhysicalScene(); | 3482 | RemoveFromPhysicalScene(); |
3511 | GC.Collect(); | ||
3512 | } | 3483 | } |
3513 | 3484 | ||
3514 | public ScenePresence() | 3485 | public ScenePresence() |
@@ -3884,5 +3855,115 @@ namespace OpenSim.Region.Framework.Scenes | |||
3884 | } | 3855 | } |
3885 | } | 3856 | } |
3886 | } | 3857 | } |
3858 | |||
3859 | public double GetUpdatePriority(IClientAPI client) | ||
3860 | { | ||
3861 | switch (Scene.UpdatePrioritizationScheme) | ||
3862 | { | ||
3863 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3864 | return GetPriorityByTime(); | ||
3865 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3866 | return GetPriorityByDistance(client); | ||
3867 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3868 | return GetPriorityByDistance(client); | ||
3869 | default: | ||
3870 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); | ||
3871 | } | ||
3872 | } | ||
3873 | |||
3874 | private double GetPriorityByTime() | ||
3875 | { | ||
3876 | return DateTime.Now.ToOADate(); | ||
3877 | } | ||
3878 | |||
3879 | private double GetPriorityByDistance(IClientAPI client) | ||
3880 | { | ||
3881 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3882 | if (presence != null) | ||
3883 | { | ||
3884 | return GetPriorityByDistance((presence.IsChildAgent) ? | ||
3885 | presence.AbsolutePosition : presence.CameraPosition); | ||
3886 | } | ||
3887 | return double.NaN; | ||
3888 | } | ||
3889 | |||
3890 | private double GetPriorityByDistance(Vector3 position) | ||
3891 | { | ||
3892 | return Vector3.Distance(AbsolutePosition, position); | ||
3893 | } | ||
3894 | |||
3895 | private double GetSOGUpdatePriority(SceneObjectGroup sog) | ||
3896 | { | ||
3897 | switch (Scene.UpdatePrioritizationScheme) | ||
3898 | { | ||
3899 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3900 | throw new InvalidOperationException("UpdatePrioritizationScheme for time not supported for reprioritization"); | ||
3901 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3902 | return sog.GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); | ||
3903 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3904 | return sog.GetPriorityBySimpleAngularDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); | ||
3905 | default: | ||
3906 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); | ||
3907 | } | ||
3908 | } | ||
3909 | |||
3910 | private double UpdatePriority(UpdatePriorityData data) | ||
3911 | { | ||
3912 | EntityBase entity; | ||
3913 | SceneObjectGroup group; | ||
3914 | |||
3915 | if (Scene.Entities.TryGetValue(data.localID, out entity)) | ||
3916 | { | ||
3917 | group = entity as SceneObjectGroup; | ||
3918 | if (group != null) | ||
3919 | return GetSOGUpdatePriority(group); | ||
3920 | |||
3921 | ScenePresence presence = entity as ScenePresence; | ||
3922 | if (presence == null) | ||
3923 | throw new InvalidOperationException("entity found is neither SceneObjectGroup nor ScenePresence"); | ||
3924 | switch (Scene.UpdatePrioritizationScheme) | ||
3925 | { | ||
3926 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3927 | throw new InvalidOperationException("UpdatePrioritization for time not supported for reprioritization"); | ||
3928 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3929 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3930 | return GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); | ||
3931 | default: | ||
3932 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); | ||
3933 | } | ||
3934 | } | ||
3935 | else | ||
3936 | { | ||
3937 | group = Scene.SceneGraph.GetGroupByPrim(data.localID); | ||
3938 | if (group != null) | ||
3939 | return GetSOGUpdatePriority(group); | ||
3940 | } | ||
3941 | return double.NaN; | ||
3942 | } | ||
3943 | |||
3944 | private void ReprioritizeUpdates() | ||
3945 | { | ||
3946 | if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != Scene.UpdatePrioritizationSchemes.Time) | ||
3947 | { | ||
3948 | lock (m_reprioritization_timer) | ||
3949 | { | ||
3950 | if (!m_reprioritizing) | ||
3951 | m_reprioritization_timer.Enabled = m_reprioritizing = true; | ||
3952 | else | ||
3953 | m_reprioritization_called = true; | ||
3954 | } | ||
3955 | } | ||
3956 | } | ||
3957 | |||
3958 | private void Reprioritize(object sender, ElapsedEventArgs e) | ||
3959 | { | ||
3960 | m_controllingClient.ReprioritizeUpdates(StateUpdateTypes.All, UpdatePriority); | ||
3961 | |||
3962 | lock (m_reprioritization_timer) | ||
3963 | { | ||
3964 | m_reprioritization_timer.Enabled = m_reprioritizing = m_reprioritization_called; | ||
3965 | m_reprioritization_called = false; | ||
3966 | } | ||
3967 | } | ||
3887 | } | 3968 | } |
3888 | } | 3969 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 8ab0552..e4296ef 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs | |||
@@ -45,14 +45,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
45 | 45 | ||
46 | protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); | 46 | protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); |
47 | 47 | ||
48 | protected int m_maxPrimsPerFrame = 200; | ||
49 | |||
50 | public int MaxPrimsPerFrame | ||
51 | { | ||
52 | get { return m_maxPrimsPerFrame; } | ||
53 | set { m_maxPrimsPerFrame = value; } | ||
54 | } | ||
55 | |||
56 | public SceneViewer() | 48 | public SceneViewer() |
57 | { | 49 | { |
58 | } | 50 | } |
@@ -82,16 +74,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
82 | { | 74 | { |
83 | m_pendingObjects = new Queue<SceneObjectGroup>(); | 75 | m_pendingObjects = new Queue<SceneObjectGroup>(); |
84 | 76 | ||
85 | List<EntityBase> ents = new List<EntityBase>(m_presence.Scene.Entities); | 77 | foreach (EntityBase e in m_presence.Scene.Entities) |
86 | if (!m_presence.IsChildAgent) // Proximity sort makes no sense for | ||
87 | { // Child agents | ||
88 | ents.Sort(delegate(EntityBase a, EntityBase b) | ||
89 | { | ||
90 | return Vector3.Distance(m_presence.AbsolutePosition, a.AbsolutePosition).CompareTo(Vector3.Distance(m_presence.AbsolutePosition, b.AbsolutePosition)); | ||
91 | }); | ||
92 | } | ||
93 | |||
94 | foreach (EntityBase e in ents) | ||
95 | { | 78 | { |
96 | if (e is SceneObjectGroup) | 79 | if (e is SceneObjectGroup) |
97 | m_pendingObjects.Enqueue((SceneObjectGroup)e); | 80 | m_pendingObjects.Enqueue((SceneObjectGroup)e); |
@@ -99,7 +82,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
99 | } | 82 | } |
100 | } | 83 | } |
101 | 84 | ||
102 | while (m_pendingObjects != null && m_pendingObjects.Count > 0 && m_partsUpdateQueue.Count < m_maxPrimsPerFrame) | 85 | while (m_pendingObjects != null && m_pendingObjects.Count > 0) |
103 | { | 86 | { |
104 | SceneObjectGroup g = m_pendingObjects.Dequeue(); | 87 | SceneObjectGroup g = m_pendingObjects.Dequeue(); |
105 | 88 | ||
@@ -183,8 +166,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
183 | m_presence.GenerateClientFlags(part.UUID)); | 166 | m_presence.GenerateClientFlags(part.UUID)); |
184 | } | 167 | } |
185 | } | 168 | } |
186 | |||
187 | m_presence.ControllingClient.FlushPrimUpdates(); | ||
188 | } | 169 | } |
189 | 170 | ||
190 | public void Reset() | 171 | public void Reset() |
diff --git a/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs b/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs index 29c4672..f3be028 100644 --- a/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs +++ b/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs | |||
@@ -35,8 +35,8 @@ namespace OpenSim.Region.Framework.Scenes.Scripting | |||
35 | string Description { get; set; } | 35 | string Description { get; set; } |
36 | 36 | ||
37 | UUID UUID { get; } | 37 | UUID UUID { get; } |
38 | UUID ObjectOwner { get; } | 38 | UUID OwnerID { get; } |
39 | UUID ObjectCreator { get; } | 39 | UUID CreatorID { get; } |
40 | Vector3 AbsolutePosition { get; } | 40 | Vector3 AbsolutePosition { get; } |
41 | 41 | ||
42 | string SitName { get; set; } | 42 | string SitName { get; set; } |
diff --git a/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs b/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs index af18a98..d7198f0 100644 --- a/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs +++ b/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs | |||
@@ -68,12 +68,12 @@ namespace OpenSim.Region.Framework.Scenes.Scripting | |||
68 | get { return UUID.Zero; } | 68 | get { return UUID.Zero; } |
69 | } | 69 | } |
70 | 70 | ||
71 | public UUID ObjectOwner | 71 | public UUID OwnerID |
72 | { | 72 | { |
73 | get { return UUID.Zero; } | 73 | get { return UUID.Zero; } |
74 | } | 74 | } |
75 | 75 | ||
76 | public UUID ObjectCreator | 76 | public UUID CreatorID |
77 | { | 77 | { |
78 | get { return UUID.Zero; } | 78 | get { return UUID.Zero; } |
79 | } | 79 | } |
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 434da0a..df03b8d 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -1013,12 +1013,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1013 | 1013 | ||
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | public void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation) | 1016 | public void SendAvatarData(SendAvatarData data) |
1017 | { | 1017 | { |
1018 | 1018 | ||
1019 | } | 1019 | } |
1020 | 1020 | ||
1021 | public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity, Quaternion rotation, UUID agentid) | 1021 | public void SendAvatarTerseUpdate(SendAvatarTerseData data) |
1022 | { | 1022 | { |
1023 | 1023 | ||
1024 | } | 1024 | } |
@@ -1038,19 +1038,19 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1038 | 1038 | ||
1039 | } | 1039 | } |
1040 | 1040 | ||
1041 | public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, byte clickAction, byte material, byte[] textureanim, bool attachment, uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius) | 1041 | public void SendPrimitiveToClient(SendPrimitiveData data) |
1042 | { | 1042 | { |
1043 | 1043 | ||
1044 | } | 1044 | } |
1045 | 1045 | ||
1046 | public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, byte clickAction, byte material) | 1046 | public void SendPrimTerseUpdate(SendPrimitiveTerseData data) |
1047 | { | 1047 | { |
1048 | 1048 | ||
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID owner, int attachPoint) | 1051 | public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) |
1052 | { | 1052 | { |
1053 | 1053 | ||
1054 | } | 1054 | } |
1055 | 1055 | ||
1056 | public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, bool fetchFolders, bool fetchItems) | 1056 | public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, bool fetchFolders, bool fetchItems) |
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index b209199..b2544fa 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | |||
@@ -1244,18 +1244,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1244 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Updating scene title for {0} with title: {1}", AgentID, Title); | 1244 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Updating scene title for {0} with title: {1}", AgentID, Title); |
1245 | 1245 | ||
1246 | ScenePresence presence = null; | 1246 | ScenePresence presence = null; |
1247 | lock (m_sceneList) | 1247 | |
1248 | foreach (Scene scene in m_sceneList) | ||
1248 | { | 1249 | { |
1249 | foreach (Scene scene in m_sceneList) | 1250 | presence = scene.GetScenePresence(AgentID); |
1251 | if (presence != null) | ||
1250 | { | 1252 | { |
1251 | presence = scene.GetScenePresence(AgentID); | 1253 | presence.Grouptitle = Title; |
1252 | if (presence != null) | ||
1253 | { | ||
1254 | presence.Grouptitle = Title; | ||
1255 | 1254 | ||
1256 | // FixMe: Ter suggests a "Schedule" method that I can't find. | 1255 | // FixMe: Ter suggests a "Schedule" method that I can't find. |
1257 | presence.SendFullUpdateToAllClients(); | 1256 | presence.SendFullUpdateToAllClients(); |
1258 | } | ||
1259 | } | 1257 | } |
1260 | } | 1258 | } |
1261 | } | 1259 | } |
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs index 0379180..e185351 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs | |||
@@ -188,7 +188,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
188 | // MISC COMPARISONS (UUID, Byte) | 188 | // MISC COMPARISONS (UUID, Byte) |
189 | if (first.ClickAction != second.ClickAction) | 189 | if (first.ClickAction != second.ClickAction) |
190 | result |= Diff.CLICKACTION; | 190 | result |= Diff.CLICKACTION; |
191 | if (first.ObjectOwner != second.ObjectOwner) | 191 | if (first.OwnerID != second.OwnerID) |
192 | result |= Diff.OBJECTOWNER; | 192 | result |= Diff.OBJECTOWNER; |
193 | 193 | ||
194 | 194 | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs index ce50f9e..4521f8e 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs | |||
@@ -259,7 +259,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | |||
259 | if (e.InnerException != null) | 259 | if (e.InnerException != null) |
260 | m_log.Error("[MRM] " + e.InnerException); | 260 | m_log.Error("[MRM] " + e.InnerException); |
261 | 261 | ||
262 | m_scene.Broadcast(delegate(IClientAPI user) | 262 | m_scene.ForEachClient(delegate(IClientAPI user) |
263 | { | 263 | { |
264 | user.SendAlertMessage( | 264 | user.SendAlertMessage( |
265 | "MRM UnAuthorizedAccess: " + e); | 265 | "MRM UnAuthorizedAccess: " + e); |
@@ -268,7 +268,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | |||
268 | catch (Exception e) | 268 | catch (Exception e) |
269 | { | 269 | { |
270 | m_log.Info("[MRM] Error: " + e); | 270 | m_log.Info("[MRM] Error: " + e); |
271 | m_scene.Broadcast(delegate(IClientAPI user) | 271 | m_scene.ForEachClient(delegate(IClientAPI user) |
272 | { | 272 | { |
273 | user.SendAlertMessage( | 273 | user.SendAlertMessage( |
274 | "Compile error while building MRM script, check OpenSim console for more information."); | 274 | "Compile error while building MRM script, check OpenSim console for more information."); |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index f7c63ac..f7cadaa 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | |||
@@ -588,13 +588,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
588 | { | 588 | { |
589 | } | 589 | } |
590 | 590 | ||
591 | public virtual void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, | 591 | public virtual void SendAvatarData(SendAvatarData data) |
592 | uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation) | ||
593 | { | 592 | { |
594 | } | 593 | } |
595 | 594 | ||
596 | public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, | 595 | public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) |
597 | Vector3 position, Vector3 velocity, Quaternion rotation, UUID agentId) | ||
598 | { | 596 | { |
599 | } | 597 | } |
600 | 598 | ||
@@ -610,26 +608,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
610 | { | 608 | { |
611 | } | 609 | } |
612 | 610 | ||
613 | public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, | 611 | public virtual void SendPrimitiveToClient(SendPrimitiveData data) |
614 | PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, | ||
615 | Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, | ||
616 | UUID objectID, UUID ownerID, string text, byte[] color, | ||
617 | uint parentID, | ||
618 | byte[] particleSystem, byte clickAction, byte material) | ||
619 | { | 612 | { |
620 | } | 613 | } |
621 | public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, | 614 | |
622 | PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, | 615 | public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) |
623 | Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, | ||
624 | UUID objectID, UUID ownerID, string text, byte[] color, | ||
625 | uint parentID, | ||
626 | byte[] particleSystem, byte clickAction, byte material, byte[] textureanimation, | ||
627 | bool attachment, uint AttachmentPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius) | ||
628 | { | 616 | { |
629 | } | 617 | } |
630 | public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, | 618 | |
631 | Vector3 position, Quaternion rotation, Vector3 velocity, | 619 | public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) |
632 | Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint) | ||
633 | { | 620 | { |
634 | } | 621 | } |
635 | 622 | ||
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 1ea08e2..f609e73 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs | |||
@@ -289,6 +289,9 @@ namespace OpenSim.Region.Physics.Meshing | |||
289 | ManagedImage managedImage; // we never use this | 289 | ManagedImage managedImage; // we never use this |
290 | OpenJPEG.DecodeToImage(primShape.SculptData, out managedImage, out idata); | 290 | OpenJPEG.DecodeToImage(primShape.SculptData, out managedImage, out idata); |
291 | 291 | ||
292 | // Remove the reference to the encoded JPEG2000 data so it can be GCed | ||
293 | primShape.SculptData = Utils.EmptyBytes; | ||
294 | |||
292 | if (cacheSculptMaps) | 295 | if (cacheSculptMaps) |
293 | { | 296 | { |
294 | try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } | 297 | try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } |
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 1fff846..71ace16 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | |||
@@ -139,8 +139,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
139 | public int m_eventsubscription = 0; | 139 | public int m_eventsubscription = 0; |
140 | private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); | 140 | private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); |
141 | 141 | ||
142 | // unique UUID of this character object | ||
143 | public UUID m_uuid; | ||
144 | public bool bad = false; | ||
145 | |||
142 | public OdeCharacter(String avName, OdeScene parent_scene, PhysicsVector pos, CollisionLocker dode, PhysicsVector size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor) | 146 | public OdeCharacter(String avName, OdeScene parent_scene, PhysicsVector pos, CollisionLocker dode, PhysicsVector size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor) |
143 | { | 147 | { |
148 | m_uuid = UUID.Random(); | ||
149 | |||
144 | // ode = dode; | 150 | // ode = dode; |
145 | _velocity = new PhysicsVector(); | 151 | _velocity = new PhysicsVector(); |
146 | _target_velocity = new PhysicsVector(); | 152 | _target_velocity = new PhysicsVector(); |
@@ -225,11 +231,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
225 | set { m_localID = value; } | 231 | set { m_localID = value; } |
226 | } | 232 | } |
227 | 233 | ||
228 | public override int GetHashCode() | ||
229 | { | ||
230 | return (int)m_localID; | ||
231 | } | ||
232 | |||
233 | public override bool Grabbed | 234 | public override bool Grabbed |
234 | { | 235 | { |
235 | set { return; } | 236 | set { return; } |
@@ -1112,10 +1113,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1112 | } | 1113 | } |
1113 | catch (NullReferenceException) | 1114 | catch (NullReferenceException) |
1114 | { | 1115 | { |
1116 | bad = true; | ||
1115 | _parent_scene.BadCharacter(this); | 1117 | _parent_scene.BadCharacter(this); |
1116 | vec = new d.Vector3(_position.X, _position.Y, _position.Z); | 1118 | vec = new d.Vector3(_position.X, _position.Y, _position.Z); |
1117 | base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem! | 1119 | base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem! |
1118 | m_log.WarnFormat("[ODEPLUGIN]: Avatar Null reference for Avatar: {0}", m_name); | 1120 | m_log.WarnFormat("[ODEPLUGIN]: Avatar Null reference for Avatar {0}, physical actor {1}", m_name, m_uuid); |
1119 | } | 1121 | } |
1120 | 1122 | ||
1121 | 1123 | ||
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 9429544..0a065be 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | |||
@@ -1665,6 +1665,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1665 | if (!_characters.Contains(chr)) | 1665 | if (!_characters.Contains(chr)) |
1666 | { | 1666 | { |
1667 | _characters.Add(chr); | 1667 | _characters.Add(chr); |
1668 | if (chr.bad) | ||
1669 | m_log.DebugFormat("[PHYSICS] Added BAD actor {0} to characters list", chr.m_uuid); | ||
1668 | } | 1670 | } |
1669 | } | 1671 | } |
1670 | } | 1672 | } |
@@ -2587,7 +2589,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2587 | lock (_taintedActors) | 2589 | lock (_taintedActors) |
2588 | { | 2590 | { |
2589 | if (!(_taintedActors.Contains(taintedchar))) | 2591 | if (!(_taintedActors.Contains(taintedchar))) |
2592 | { | ||
2590 | _taintedActors.Add(taintedchar); | 2593 | _taintedActors.Add(taintedchar); |
2594 | if (taintedchar.bad) | ||
2595 | m_log.DebugFormat("[PHYSICS]: Added BAD actor {0} to tainted actors", taintedchar.m_uuid); | ||
2596 | } | ||
2591 | } | 2597 | } |
2592 | } | 2598 | } |
2593 | } | 2599 | } |
@@ -2992,7 +2998,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2992 | foreach (OdeCharacter actor in _characters) | 2998 | foreach (OdeCharacter actor in _characters) |
2993 | { | 2999 | { |
2994 | if (actor != null) | 3000 | if (actor != null) |
3001 | { | ||
3002 | if (actor.bad) | ||
3003 | m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); | ||
2995 | actor.UpdatePositionAndVelocity(); | 3004 | actor.UpdatePositionAndVelocity(); |
3005 | } | ||
2996 | } | 3006 | } |
2997 | } | 3007 | } |
2998 | 3008 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 7c176bb..11f255f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -137,13 +137,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
137 | return lease; | 137 | return lease; |
138 | } | 138 | } |
139 | 139 | ||
140 | protected virtual void ConditionalScriptSleep(int delay) | ||
141 | { | ||
142 | // Uncomment to get SL compatibility! | ||
143 | // | ||
144 | // ScriptSleep(delay); | ||
145 | } | ||
146 | |||
147 | protected virtual void ScriptSleep(int delay) | 140 | protected virtual void ScriptSleep(int delay) |
148 | { | 141 | { |
149 | delay = (int)((float)delay * m_ScriptDelayFactor); | 142 | delay = (int)((float)delay * m_ScriptDelayFactor); |
@@ -1686,7 +1679,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1686 | { | 1679 | { |
1687 | m_host.AddScriptLPS(1); | 1680 | m_host.AddScriptLPS(1); |
1688 | SetTexture(m_host, texture, face); | 1681 | SetTexture(m_host, texture, face); |
1689 | ConditionalScriptSleep(200); | 1682 | ScriptSleep(200); |
1690 | } | 1683 | } |
1691 | 1684 | ||
1692 | public void llSetLinkTexture(int linknumber, string texture, int face) | 1685 | public void llSetLinkTexture(int linknumber, string texture, int face) |
@@ -1698,7 +1691,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1698 | foreach (SceneObjectPart part in parts) | 1691 | foreach (SceneObjectPart part in parts) |
1699 | SetTexture(part, texture, face); | 1692 | SetTexture(part, texture, face); |
1700 | 1693 | ||
1701 | ConditionalScriptSleep(200); | 1694 | ScriptSleep(200); |
1702 | } | 1695 | } |
1703 | 1696 | ||
1704 | protected void SetTexture(SceneObjectPart part, string texture, int face) | 1697 | protected void SetTexture(SceneObjectPart part, string texture, int face) |
@@ -1743,7 +1736,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1743 | m_host.AddScriptLPS(1); | 1736 | m_host.AddScriptLPS(1); |
1744 | 1737 | ||
1745 | ScaleTexture(m_host, u, v, face); | 1738 | ScaleTexture(m_host, u, v, face); |
1746 | ConditionalScriptSleep(200); | 1739 | ScriptSleep(200); |
1747 | } | 1740 | } |
1748 | 1741 | ||
1749 | protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) | 1742 | protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) |
@@ -1779,7 +1772,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1779 | { | 1772 | { |
1780 | m_host.AddScriptLPS(1); | 1773 | m_host.AddScriptLPS(1); |
1781 | OffsetTexture(m_host, u, v, face); | 1774 | OffsetTexture(m_host, u, v, face); |
1782 | ConditionalScriptSleep(200); | 1775 | ScriptSleep(200); |
1783 | } | 1776 | } |
1784 | 1777 | ||
1785 | protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) | 1778 | protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) |
@@ -1815,7 +1808,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1815 | { | 1808 | { |
1816 | m_host.AddScriptLPS(1); | 1809 | m_host.AddScriptLPS(1); |
1817 | RotateTexture(m_host, rotation, face); | 1810 | RotateTexture(m_host, rotation, face); |
1818 | ConditionalScriptSleep(200); | 1811 | ScriptSleep(200); |
1819 | } | 1812 | } |
1820 | 1813 | ||
1821 | protected void RotateTexture(SceneObjectPart part, double rotation, int face) | 1814 | protected void RotateTexture(SceneObjectPart part, double rotation, int face) |
@@ -2289,7 +2282,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2289 | { | 2282 | { |
2290 | m_host.AddScriptLPS(1); | 2283 | m_host.AddScriptLPS(1); |
2291 | m_host.PreloadSound(sound); | 2284 | m_host.PreloadSound(sound); |
2292 | ConditionalScriptSleep(1000); | 2285 | ScriptSleep(1000); |
2293 | } | 2286 | } |
2294 | 2287 | ||
2295 | /// <summary> | 2288 | /// <summary> |
@@ -2581,28 +2574,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2581 | { | 2574 | { |
2582 | m_host.AddScriptLPS(1); | 2575 | m_host.AddScriptLPS(1); |
2583 | Deprecated("llMakeExplosion"); | 2576 | Deprecated("llMakeExplosion"); |
2584 | ConditionalScriptSleep(100); | 2577 | ScriptSleep(100); |
2585 | } | 2578 | } |
2586 | 2579 | ||
2587 | public void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset) | 2580 | public void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset) |
2588 | { | 2581 | { |
2589 | m_host.AddScriptLPS(1); | 2582 | m_host.AddScriptLPS(1); |
2590 | Deprecated("llMakeFountain"); | 2583 | Deprecated("llMakeFountain"); |
2591 | ConditionalScriptSleep(100); | 2584 | ScriptSleep(100); |
2592 | } | 2585 | } |
2593 | 2586 | ||
2594 | public void llMakeSmoke(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) | 2587 | public void llMakeSmoke(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) |
2595 | { | 2588 | { |
2596 | m_host.AddScriptLPS(1); | 2589 | m_host.AddScriptLPS(1); |
2597 | Deprecated("llMakeSmoke"); | 2590 | Deprecated("llMakeSmoke"); |
2598 | ConditionalScriptSleep(100); | 2591 | ScriptSleep(100); |
2599 | } | 2592 | } |
2600 | 2593 | ||
2601 | public void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) | 2594 | public void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) |
2602 | { | 2595 | { |
2603 | m_host.AddScriptLPS(1); | 2596 | m_host.AddScriptLPS(1); |
2604 | Deprecated("llMakeFire"); | 2597 | Deprecated("llMakeFire"); |
2605 | ConditionalScriptSleep(100); | 2598 | ScriptSleep(100); |
2606 | } | 2599 | } |
2607 | 2600 | ||
2608 | public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) | 2601 | public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) |
@@ -2661,7 +2654,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2661 | } | 2654 | } |
2662 | // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) | 2655 | // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) |
2663 | ScriptSleep((int)((groupmass * velmag) / 10)); | 2656 | ScriptSleep((int)((groupmass * velmag) / 10)); |
2664 | ConditionalScriptSleep(100); | 2657 | ScriptSleep(100); |
2665 | return; | 2658 | return; |
2666 | } | 2659 | } |
2667 | } | 2660 | } |
@@ -2881,7 +2874,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2881 | { | 2874 | { |
2882 | m_host.AddScriptLPS(1); | 2875 | m_host.AddScriptLPS(1); |
2883 | 2876 | ||
2884 | return m_host.ObjectOwner.ToString(); | 2877 | return m_host.OwnerID.ToString(); |
2885 | } | 2878 | } |
2886 | 2879 | ||
2887 | public void llInstantMessage(string user, string message) | 2880 | public void llInstantMessage(string user, string message) |
@@ -2947,7 +2940,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2947 | } | 2940 | } |
2948 | 2941 | ||
2949 | emailModule.SendEmail(m_host.UUID, address, subject, message); | 2942 | emailModule.SendEmail(m_host.UUID, address, subject, message); |
2950 | ConditionalScriptSleep(20000); | 2943 | ScriptSleep(20000); |
2951 | } | 2944 | } |
2952 | 2945 | ||
2953 | public void llGetNextEmail(string address, string subject) | 2946 | public void llGetNextEmail(string address, string subject) |
@@ -3751,7 +3744,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3751 | // destination is an object | 3744 | // destination is an object |
3752 | World.MoveTaskInventoryItem(destId, m_host, objId); | 3745 | World.MoveTaskInventoryItem(destId, m_host, objId); |
3753 | } | 3746 | } |
3754 | ConditionalScriptSleep(3000); | 3747 | ScriptSleep(3000); |
3755 | } | 3748 | } |
3756 | 3749 | ||
3757 | public void llRemoveInventory(string name) | 3750 | public void llRemoveInventory(string name) |
@@ -3852,7 +3845,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3852 | AsyncCommands. | 3845 | AsyncCommands. |
3853 | DataserverPlugin.DataserverReply(rq.ToString(), reply); | 3846 | DataserverPlugin.DataserverReply(rq.ToString(), reply); |
3854 | 3847 | ||
3855 | ConditionalScriptSleep(100); | 3848 | ScriptSleep(100); |
3856 | return tid.ToString(); | 3849 | return tid.ToString(); |
3857 | } | 3850 | } |
3858 | 3851 | ||
@@ -3890,11 +3883,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3890 | reply); | 3883 | reply); |
3891 | }); | 3884 | }); |
3892 | 3885 | ||
3893 | ConditionalScriptSleep(1000); | 3886 | ScriptSleep(1000); |
3894 | return tid.ToString(); | 3887 | return tid.ToString(); |
3895 | } | 3888 | } |
3896 | } | 3889 | } |
3897 | ConditionalScriptSleep(1000); | 3890 | ScriptSleep(1000); |
3898 | return String.Empty; | 3891 | return String.Empty; |
3899 | } | 3892 | } |
3900 | 3893 | ||
@@ -3922,7 +3915,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3922 | } | 3915 | } |
3923 | } | 3916 | } |
3924 | } | 3917 | } |
3925 | ConditionalScriptSleep(5000); | 3918 | ScriptSleep(5000); |
3926 | } | 3919 | } |
3927 | 3920 | ||
3928 | public void llTextBox(string avatar, string message, int chat_channel) | 3921 | public void llTextBox(string avatar, string message, int chat_channel) |
@@ -4666,7 +4659,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4666 | { | 4659 | { |
4667 | index = src.Length + index; | 4660 | index = src.Length + index; |
4668 | } | 4661 | } |
4669 | if (index >= src.Length) | 4662 | if (index >= src.Length || index < 0) |
4670 | { | 4663 | { |
4671 | return 0; | 4664 | return 0; |
4672 | } | 4665 | } |
@@ -4691,7 +4684,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4691 | { | 4684 | { |
4692 | index = src.Length + index; | 4685 | index = src.Length + index; |
4693 | } | 4686 | } |
4694 | if (index >= src.Length) | 4687 | if (index >= src.Length || index < 0) |
4695 | { | 4688 | { |
4696 | return 0.0; | 4689 | return 0.0; |
4697 | } | 4690 | } |
@@ -4718,7 +4711,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4718 | { | 4711 | { |
4719 | index = src.Length + index; | 4712 | index = src.Length + index; |
4720 | } | 4713 | } |
4721 | if (index >= src.Length) | 4714 | if (index >= src.Length || index < 0) |
4722 | { | 4715 | { |
4723 | return String.Empty; | 4716 | return String.Empty; |
4724 | } | 4717 | } |
@@ -4732,7 +4725,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4732 | { | 4725 | { |
4733 | index = src.Length + index; | 4726 | index = src.Length + index; |
4734 | } | 4727 | } |
4735 | if (index >= src.Length) | 4728 | if (index >= src.Length || index < 0) |
4736 | { | 4729 | { |
4737 | return ""; | 4730 | return ""; |
4738 | } | 4731 | } |
@@ -4746,7 +4739,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4746 | { | 4739 | { |
4747 | index = src.Length + index; | 4740 | index = src.Length + index; |
4748 | } | 4741 | } |
4749 | if (index >= src.Length) | 4742 | if (index >= src.Length || index < 0) |
4750 | { | 4743 | { |
4751 | return new LSL_Vector(0, 0, 0); | 4744 | return new LSL_Vector(0, 0, 0); |
4752 | } | 4745 | } |
@@ -4767,7 +4760,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4767 | { | 4760 | { |
4768 | index = src.Length + index; | 4761 | index = src.Length + index; |
4769 | } | 4762 | } |
4770 | if (index >= src.Length) | 4763 | if (index >= src.Length || index < 0) |
4771 | { | 4764 | { |
4772 | return new LSL_Rotation(0, 0, 0, 1); | 4765 | return new LSL_Rotation(0, 0, 0, 1); |
4773 | } | 4766 | } |
@@ -5382,7 +5375,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5382 | { | 5375 | { |
5383 | m_host.AddScriptLPS(1); | 5376 | m_host.AddScriptLPS(1); |
5384 | m_host.AdjustSoundGain(volume); | 5377 | m_host.AdjustSoundGain(volume); |
5385 | ConditionalScriptSleep(100); | 5378 | ScriptSleep(100); |
5386 | } | 5379 | } |
5387 | 5380 | ||
5388 | public void llSetSoundQueueing(int queue) | 5381 | public void llSetSoundQueueing(int queue) |
@@ -5465,7 +5458,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5465 | World.TeleportClientHome(agentId, presence.ControllingClient); | 5458 | World.TeleportClientHome(agentId, presence.ControllingClient); |
5466 | } | 5459 | } |
5467 | } | 5460 | } |
5468 | ConditionalScriptSleep(5000); | 5461 | ScriptSleep(5000); |
5469 | } | 5462 | } |
5470 | 5463 | ||
5471 | public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) | 5464 | public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) |
@@ -5640,7 +5633,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5640 | ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y); | 5633 | ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y); |
5641 | if (parcel != null) | 5634 | if (parcel != null) |
5642 | { | 5635 | { |
5643 | if (m_host.ObjectOwner == parcel.LandData.OwnerID || | 5636 | if (m_host.OwnerID == parcel.LandData.OwnerID || |
5644 | (m_host.OwnerID == m_host.GroupID && m_host.GroupID == parcel.LandData.GroupID | 5637 | (m_host.OwnerID == m_host.GroupID && m_host.GroupID == parcel.LandData.GroupID |
5645 | && parcel.LandData.IsGroupOwned) || World.Permissions.IsGod(m_host.OwnerID)) | 5638 | && parcel.LandData.IsGroupOwned) || World.Permissions.IsGod(m_host.OwnerID)) |
5646 | { | 5639 | { |
@@ -5850,7 +5843,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5850 | 5843 | ||
5851 | for (int i = 0; i < rules.Length; i += 2) | 5844 | for (int i = 0; i < rules.Length; i += 2) |
5852 | { | 5845 | { |
5853 | switch ((int)rules.Data[i]) | 5846 | switch (Convert.ToInt32(rules.Data[i])) |
5854 | { | 5847 | { |
5855 | case (int)ScriptBaseClass.PSYS_PART_FLAGS: | 5848 | case (int)ScriptBaseClass.PSYS_PART_FLAGS: |
5856 | prules.PartDataFlags = (Primitive.ParticleSystem.ParticleDataFlags)(uint)rules.GetLSLIntegerItem(i + 1); | 5849 | prules.PartDataFlags = (Primitive.ParticleSystem.ParticleDataFlags)(uint)rules.GetLSLIntegerItem(i + 1); |
@@ -6157,7 +6150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6157 | land.ParcelAccessList.Add(entry); | 6150 | land.ParcelAccessList.Add(entry); |
6158 | } | 6151 | } |
6159 | } | 6152 | } |
6160 | ConditionalScriptSleep(100); | 6153 | ScriptSleep(100); |
6161 | } | 6154 | } |
6162 | 6155 | ||
6163 | public void llSetTouchText(string text) | 6156 | public void llSetTouchText(string text) |
@@ -6254,7 +6247,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6254 | av, m_host.Name, m_host.UUID, m_host.OwnerID, | 6247 | av, m_host.Name, m_host.UUID, m_host.OwnerID, |
6255 | message, new UUID("00000000-0000-2222-3333-100000001000"), chat_channel, buts); | 6248 | message, new UUID("00000000-0000-2222-3333-100000001000"), chat_channel, buts); |
6256 | 6249 | ||
6257 | ConditionalScriptSleep(1000); | 6250 | ScriptSleep(1000); |
6258 | } | 6251 | } |
6259 | 6252 | ||
6260 | public void llVolumeDetect(int detect) | 6253 | public void llVolumeDetect(int detect) |
@@ -6279,7 +6272,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6279 | m_host.AddScriptLPS(1); | 6272 | m_host.AddScriptLPS(1); |
6280 | // Report an error as it does in SL | 6273 | // Report an error as it does in SL |
6281 | ShoutError("Deprecated. Please use llRemoteLoadScriptPin instead."); | 6274 | ShoutError("Deprecated. Please use llRemoteLoadScriptPin instead."); |
6282 | ConditionalScriptSleep(3000); | 6275 | ScriptSleep(3000); |
6283 | } | 6276 | } |
6284 | 6277 | ||
6285 | public void llSetRemoteScriptAccessPin(int pin) | 6278 | public void llSetRemoteScriptAccessPin(int pin) |
@@ -6365,14 +6358,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6365 | m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams("remote_data", resobj, | 6358 | m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams("remote_data", resobj, |
6366 | new DetectParams[0])); | 6359 | new DetectParams[0])); |
6367 | } | 6360 | } |
6368 | ConditionalScriptSleep(1000); | 6361 | ScriptSleep(1000); |
6369 | } | 6362 | } |
6370 | 6363 | ||
6371 | public LSL_String llSendRemoteData(string channel, string dest, int idata, string sdata) | 6364 | public LSL_String llSendRemoteData(string channel, string dest, int idata, string sdata) |
6372 | { | 6365 | { |
6373 | m_host.AddScriptLPS(1); | 6366 | m_host.AddScriptLPS(1); |
6374 | IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); | 6367 | IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); |
6375 | ConditionalScriptSleep(3000); | 6368 | ScriptSleep(3000); |
6376 | return (xmlrpcMod.SendRemoteData(m_localID, m_itemID, channel, dest, idata, sdata)).ToString(); | 6369 | return (xmlrpcMod.SendRemoteData(m_localID, m_itemID, channel, dest, idata, sdata)).ToString(); |
6377 | } | 6370 | } |
6378 | 6371 | ||
@@ -6381,7 +6374,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6381 | m_host.AddScriptLPS(1); | 6374 | m_host.AddScriptLPS(1); |
6382 | IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); | 6375 | IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); |
6383 | xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata); | 6376 | xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata); |
6384 | ConditionalScriptSleep(3000); | 6377 | ScriptSleep(3000); |
6385 | } | 6378 | } |
6386 | 6379 | ||
6387 | public void llCloseRemoteDataChannel(string channel) | 6380 | public void llCloseRemoteDataChannel(string channel) |
@@ -6389,7 +6382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6389 | m_host.AddScriptLPS(1); | 6382 | m_host.AddScriptLPS(1); |
6390 | IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); | 6383 | IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); |
6391 | xmlrpcMod.CloseXMLRPCChannel((UUID)channel); | 6384 | xmlrpcMod.CloseXMLRPCChannel((UUID)channel); |
6392 | ConditionalScriptSleep(1000); | 6385 | ScriptSleep(1000); |
6393 | } | 6386 | } |
6394 | 6387 | ||
6395 | public LSL_String llMD5String(string src, int nonce) | 6388 | public LSL_String llMD5String(string src, int nonce) |
@@ -7117,7 +7110,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7117 | { | 7110 | { |
7118 | m_host.AddScriptLPS(1); | 7111 | m_host.AddScriptLPS(1); |
7119 | Deprecated("llXorBase64Strings"); | 7112 | Deprecated("llXorBase64Strings"); |
7120 | ConditionalScriptSleep(300); | 7113 | ScriptSleep(300); |
7121 | return String.Empty; | 7114 | return String.Empty; |
7122 | } | 7115 | } |
7123 | 7116 | ||
@@ -7160,12 +7153,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7160 | 7153 | ||
7161 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); | 7154 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); |
7162 | 7155 | ||
7163 | if (land.LandData.OwnerID != m_host.ObjectOwner) | 7156 | if (land.LandData.OwnerID != m_host.OwnerID) |
7164 | return; | 7157 | return; |
7165 | 7158 | ||
7166 | land.SetMusicUrl(url); | 7159 | land.SetMusicUrl(url); |
7167 | 7160 | ||
7168 | ConditionalScriptSleep(2000); | 7161 | ScriptSleep(2000); |
7169 | } | 7162 | } |
7170 | 7163 | ||
7171 | public LSL_Vector llGetRootPosition() | 7164 | public LSL_Vector llGetRootPosition() |
@@ -7218,7 +7211,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7218 | public LSL_String llGetCreator() | 7211 | public LSL_String llGetCreator() |
7219 | { | 7212 | { |
7220 | m_host.AddScriptLPS(1); | 7213 | m_host.AddScriptLPS(1); |
7221 | return m_host.ObjectCreator.ToString(); | 7214 | return m_host.CreatorID.ToString(); |
7222 | } | 7215 | } |
7223 | 7216 | ||
7224 | public LSL_String llGetTimestamp() | 7217 | public LSL_String llGetTimestamp() |
@@ -8210,7 +8203,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8210 | case 5: // DATA_SIM_POS | 8203 | case 5: // DATA_SIM_POS |
8211 | if (info == null) | 8204 | if (info == null) |
8212 | { | 8205 | { |
8213 | ConditionalScriptSleep(1000); | 8206 | ScriptSleep(1000); |
8214 | return UUID.Zero.ToString(); | 8207 | return UUID.Zero.ToString(); |
8215 | } | 8208 | } |
8216 | reply = new LSL_Vector( | 8209 | reply = new LSL_Vector( |
@@ -8227,7 +8220,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8227 | case 7: // DATA_SIM_RATING | 8220 | case 7: // DATA_SIM_RATING |
8228 | if (info == null) | 8221 | if (info == null) |
8229 | { | 8222 | { |
8230 | ConditionalScriptSleep(1000); | 8223 | ScriptSleep(1000); |
8231 | return UUID.Zero.ToString(); | 8224 | return UUID.Zero.ToString(); |
8232 | } | 8225 | } |
8233 | int access = info.Maturity; | 8226 | int access = info.Maturity; |
@@ -8246,7 +8239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8246 | reply = "OpenSim"; | 8239 | reply = "OpenSim"; |
8247 | break; | 8240 | break; |
8248 | default: | 8241 | default: |
8249 | ConditionalScriptSleep(1000); | 8242 | ScriptSleep(1000); |
8250 | return UUID.Zero.ToString(); // Raise no event | 8243 | return UUID.Zero.ToString(); // Raise no event |
8251 | } | 8244 | } |
8252 | UUID rq = UUID.Random(); | 8245 | UUID rq = UUID.Random(); |
@@ -8257,7 +8250,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8257 | AsyncCommands. | 8250 | AsyncCommands. |
8258 | DataserverPlugin.DataserverReply(rq.ToString(), reply); | 8251 | DataserverPlugin.DataserverReply(rq.ToString(), reply); |
8259 | 8252 | ||
8260 | ConditionalScriptSleep(1000); | 8253 | ScriptSleep(1000); |
8261 | return tid.ToString(); | 8254 | return tid.ToString(); |
8262 | } | 8255 | } |
8263 | catch(Exception) | 8256 | catch(Exception) |
@@ -8399,9 +8392,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8399 | IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); | 8392 | IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); |
8400 | if (null != dm) | 8393 | if (null != dm) |
8401 | dm.SendUrlToUser( | 8394 | dm.SendUrlToUser( |
8402 | new UUID(avatar_id), m_host.Name, m_host.UUID, m_host.ObjectOwner, false, message, url); | 8395 | new UUID(avatar_id), m_host.Name, m_host.UUID, m_host.OwnerID, false, message, url); |
8403 | 8396 | ||
8404 | ConditionalScriptSleep(10000); | 8397 | ScriptSleep(10000); |
8405 | } | 8398 | } |
8406 | 8399 | ||
8407 | public void llParcelMediaCommandList(LSL_List commandList) | 8400 | public void llParcelMediaCommandList(LSL_List commandList) |
@@ -8414,7 +8407,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8414 | // according to the docs, this command only works if script owner and land owner are the same | 8407 | // according to the docs, this command only works if script owner and land owner are the same |
8415 | // lets add estate owners and gods, too, and use the generic permission check. | 8408 | // lets add estate owners and gods, too, and use the generic permission check. |
8416 | ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); | 8409 | ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); |
8417 | if (!World.Permissions.CanEditParcel(m_host.ObjectOwner, landObject)) return; | 8410 | if (!World.Permissions.CanEditParcel(m_host.OwnerID, landObject)) return; |
8418 | 8411 | ||
8419 | bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? | 8412 | bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? |
8420 | byte loop = 0; | 8413 | byte loop = 0; |
@@ -8637,7 +8630,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8637 | time); | 8630 | time); |
8638 | } | 8631 | } |
8639 | } | 8632 | } |
8640 | ConditionalScriptSleep(2000); | 8633 | ScriptSleep(2000); |
8641 | } | 8634 | } |
8642 | 8635 | ||
8643 | public LSL_List llParcelMediaQuery(LSL_List aList) | 8636 | public LSL_List llParcelMediaQuery(LSL_List aList) |
@@ -8675,7 +8668,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8675 | 8668 | ||
8676 | } | 8669 | } |
8677 | } | 8670 | } |
8678 | ConditionalScriptSleep(2000); | 8671 | ScriptSleep(2000); |
8679 | return list; | 8672 | return list; |
8680 | } | 8673 | } |
8681 | 8674 | ||
@@ -8684,7 +8677,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8684 | m_host.AddScriptLPS(1); | 8677 | m_host.AddScriptLPS(1); |
8685 | Int64 tmp = 0; | 8678 | Int64 tmp = 0; |
8686 | Math.DivRem(Convert.ToInt64(Math.Pow(a, b)), c, out tmp); | 8679 | Math.DivRem(Convert.ToInt64(Math.Pow(a, b)), c, out tmp); |
8687 | ConditionalScriptSleep(1000); | 8680 | ScriptSleep(1000); |
8688 | return Convert.ToInt32(tmp); | 8681 | return Convert.ToInt32(tmp); |
8689 | } | 8682 | } |
8690 | 8683 | ||
@@ -8788,7 +8781,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8788 | public void llSetPrimURL(string url) | 8781 | public void llSetPrimURL(string url) |
8789 | { | 8782 | { |
8790 | m_host.AddScriptLPS(1); | 8783 | m_host.AddScriptLPS(1); |
8791 | ConditionalScriptSleep(2000); | 8784 | ScriptSleep(2000); |
8792 | } | 8785 | } |
8793 | 8786 | ||
8794 | /// <summary> | 8787 | /// <summary> |
@@ -8799,7 +8792,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8799 | { | 8792 | { |
8800 | m_host.AddScriptLPS(1); | 8793 | m_host.AddScriptLPS(1); |
8801 | ShoutError("llRefreshPrimURL - not yet supported"); | 8794 | ShoutError("llRefreshPrimURL - not yet supported"); |
8802 | ConditionalScriptSleep(20000); | 8795 | ScriptSleep(20000); |
8803 | } | 8796 | } |
8804 | 8797 | ||
8805 | public LSL_String llEscapeURL(string url) | 8798 | public LSL_String llEscapeURL(string url) |
@@ -8841,7 +8834,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8841 | new Vector3((float)pos.x, (float)pos.y, (float)pos.z), | 8834 | new Vector3((float)pos.x, (float)pos.y, (float)pos.z), |
8842 | new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); | 8835 | new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); |
8843 | } | 8836 | } |
8844 | ConditionalScriptSleep(1000); | 8837 | ScriptSleep(1000); |
8845 | } | 8838 | } |
8846 | 8839 | ||
8847 | public void llAddToLandBanList(string avatar, double hours) | 8840 | public void llAddToLandBanList(string avatar, double hours) |
@@ -8860,7 +8853,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8860 | land.ParcelAccessList.Add(entry); | 8853 | land.ParcelAccessList.Add(entry); |
8861 | } | 8854 | } |
8862 | } | 8855 | } |
8863 | ConditionalScriptSleep(100); | 8856 | ScriptSleep(100); |
8864 | } | 8857 | } |
8865 | 8858 | ||
8866 | public void llRemoveFromLandPassList(string avatar) | 8859 | public void llRemoveFromLandPassList(string avatar) |
@@ -8882,7 +8875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8882 | } | 8875 | } |
8883 | } | 8876 | } |
8884 | } | 8877 | } |
8885 | ConditionalScriptSleep(100); | 8878 | ScriptSleep(100); |
8886 | } | 8879 | } |
8887 | 8880 | ||
8888 | public void llRemoveFromLandBanList(string avatar) | 8881 | public void llRemoveFromLandBanList(string avatar) |
@@ -8904,7 +8897,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8904 | } | 8897 | } |
8905 | } | 8898 | } |
8906 | } | 8899 | } |
8907 | ConditionalScriptSleep(100); | 8900 | ScriptSleep(100); |
8908 | } | 8901 | } |
8909 | 8902 | ||
8910 | public void llSetCameraParams(LSL_List rules) | 8903 | public void llSetCameraParams(LSL_List rules) |
@@ -9084,9 +9077,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9084 | Vector3 velocity = m_host.Velocity; | 9077 | Vector3 velocity = m_host.Velocity; |
9085 | Quaternion rotation = m_host.RotationOffset; | 9078 | Quaternion rotation = m_host.RotationOffset; |
9086 | string ownerName = String.Empty; | 9079 | string ownerName = String.Empty; |
9087 | ScenePresence scenePresence = World.GetScenePresence(m_host.ObjectOwner); | 9080 | ScenePresence scenePresence = World.GetScenePresence(m_host.OwnerID); |
9088 | if (scenePresence == null) | 9081 | if (scenePresence == null) |
9089 | ownerName = resolveName(m_host.ObjectOwner); | 9082 | ownerName = resolveName(m_host.OwnerID); |
9090 | else | 9083 | else |
9091 | ownerName = scenePresence.Name; | 9084 | ownerName = scenePresence.Name; |
9092 | 9085 | ||
@@ -9111,7 +9104,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9111 | httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z); | 9104 | httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z); |
9112 | httpHeaders["X-SecondLife-Local-Rotation"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000})", rotation.X, rotation.Y, rotation.Z, rotation.W); | 9105 | httpHeaders["X-SecondLife-Local-Rotation"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000})", rotation.X, rotation.Y, rotation.Z, rotation.W); |
9113 | httpHeaders["X-SecondLife-Owner-Name"] = ownerName; | 9106 | httpHeaders["X-SecondLife-Owner-Name"] = ownerName; |
9114 | httpHeaders["X-SecondLife-Owner-Key"] = m_host.ObjectOwner.ToString(); | 9107 | httpHeaders["X-SecondLife-Owner-Key"] = m_host.OwnerID.ToString(); |
9115 | string userAgent = config.Configs["Network"].GetString("user_agent", null); | 9108 | string userAgent = config.Configs["Network"].GetString("user_agent", null); |
9116 | if (userAgent != null) | 9109 | if (userAgent != null) |
9117 | httpHeaders["User-Agent"] = userAgent; | 9110 | httpHeaders["User-Agent"] = userAgent; |
@@ -9166,7 +9159,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9166 | } | 9159 | } |
9167 | } | 9160 | } |
9168 | } | 9161 | } |
9169 | ConditionalScriptSleep(100); | 9162 | ScriptSleep(100); |
9170 | } | 9163 | } |
9171 | 9164 | ||
9172 | public void llResetLandPassList() | 9165 | public void llResetLandPassList() |
@@ -9183,7 +9176,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9183 | } | 9176 | } |
9184 | } | 9177 | } |
9185 | } | 9178 | } |
9186 | ConditionalScriptSleep(100); | 9179 | ScriptSleep(100); |
9187 | } | 9180 | } |
9188 | 9181 | ||
9189 | public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) | 9182 | public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) |
@@ -9262,7 +9255,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9262 | ret.Add(detectedParams.Value); | 9255 | ret.Add(detectedParams.Value); |
9263 | } | 9256 | } |
9264 | } | 9257 | } |
9265 | ConditionalScriptSleep(2000); | 9258 | ScriptSleep(2000); |
9266 | return ret; | 9259 | return ret; |
9267 | } | 9260 | } |
9268 | 9261 | ||
@@ -9520,7 +9513,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9520 | AsyncCommands. | 9513 | AsyncCommands. |
9521 | DataserverPlugin.DataserverReply(assetID.ToString(), | 9514 | DataserverPlugin.DataserverReply(assetID.ToString(), |
9522 | NotecardCache.GetLines(assetID).ToString()); | 9515 | NotecardCache.GetLines(assetID).ToString()); |
9523 | ConditionalScriptSleep(100); | 9516 | ScriptSleep(100); |
9524 | return tid.ToString(); | 9517 | return tid.ToString(); |
9525 | } | 9518 | } |
9526 | 9519 | ||
@@ -9542,7 +9535,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9542 | NotecardCache.GetLines(id).ToString()); | 9535 | NotecardCache.GetLines(id).ToString()); |
9543 | }); | 9536 | }); |
9544 | 9537 | ||
9545 | ConditionalScriptSleep(100); | 9538 | ScriptSleep(100); |
9546 | return tid.ToString(); | 9539 | return tid.ToString(); |
9547 | } | 9540 | } |
9548 | 9541 | ||
@@ -9581,7 +9574,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9581 | { | 9574 | { |
9582 | AsyncCommands.DataserverPlugin.DataserverReply(assetID.ToString(), | 9575 | AsyncCommands.DataserverPlugin.DataserverReply(assetID.ToString(), |
9583 | NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); | 9576 | NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); |
9584 | ConditionalScriptSleep(100); | 9577 | ScriptSleep(100); |
9585 | return tid.ToString(); | 9578 | return tid.ToString(); |
9586 | } | 9579 | } |
9587 | 9580 | ||
@@ -9602,7 +9595,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9602 | NotecardCache.GetLine(id, line, m_notecardLineReadCharsMax)); | 9595 | NotecardCache.GetLine(id, line, m_notecardLineReadCharsMax)); |
9603 | }); | 9596 | }); |
9604 | 9597 | ||
9605 | ConditionalScriptSleep(100); | 9598 | ScriptSleep(100); |
9606 | return tid.ToString(); | 9599 | return tid.ToString(); |
9607 | } | 9600 | } |
9608 | } | 9601 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 4cb4b61..52396b6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | |||
@@ -1164,7 +1164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1164 | ILandObject land | 1164 | ILandObject land |
1165 | = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); | 1165 | = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); |
1166 | 1166 | ||
1167 | if (land.LandData.OwnerID != m_host.ObjectOwner) | 1167 | if (land.LandData.OwnerID != m_host.OwnerID) |
1168 | return; | 1168 | return; |
1169 | 1169 | ||
1170 | land.SetMediaUrl(url); | 1170 | land.SetMediaUrl(url); |
@@ -1182,7 +1182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1182 | ILandObject land | 1182 | ILandObject land |
1183 | = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); | 1183 | = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); |
1184 | 1184 | ||
1185 | if (land.LandData.OwnerID != m_host.ObjectOwner) | 1185 | if (land.LandData.OwnerID != m_host.OwnerID) |
1186 | { | 1186 | { |
1187 | OSSLError("osSetParcelSIPAddress: Sorry, you need to own the land to use this function"); | 1187 | OSSLError("osSetParcelSIPAddress: Sorry, you need to own the land to use this function"); |
1188 | return; | 1188 | return; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index 2842f6b..3f38bb6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | |||
@@ -1975,7 +1975,7 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
1975 | 1975 | ||
1976 | public override int GetHashCode() | 1976 | public override int GetHashCode() |
1977 | { | 1977 | { |
1978 | return Convert.ToInt32(value); | 1978 | return value.GetHashCode(); |
1979 | } | 1979 | } |
1980 | 1980 | ||
1981 | 1981 | ||